# Quick start

Build a filterable product list in 5 minutes.

**What you'll build:** A query that filters products by category and returns matching items instantly — no backend required.

## Prerequisites

- A supported Node.js version, see [Compatibility](/sdk/compatibility#nodejs) (`node -v` to check)
- A TypeScript/JavaScript project (or use `npx tsx` to run standalone)

## Install

```bash group="install" tab="npm"
npm install @dcupl/core
```

```bash group="install" tab="yarn"
yarn add @dcupl/core
```

```bash group="install" tab="pnpm"
pnpm add @dcupl/core
```

TypeScript types are included; type names such as `ModelDefinition` come from `@dcupl/common`, which you install (`npm install @dcupl/common`) only when you import them in your own code.

## Create your first query

Create a new file and paste this complete example:

```typescript filename="demo.ts"
import { Dcupl } from '@dcupl/core';

async function main() {
  // 1. Create a dcupl instance
  const dcupl = new Dcupl();

  // 2. Define a model with filterable properties
  dcupl.models.set({
    key: 'Product',
    properties: [
      { key: 'name', type: 'string' },
      { key: 'price', type: 'int' },
      { key: 'category', type: 'string' },
    ],
  });

  // 3. Load data (inline or from external API)
  dcupl.data.set(
    [
      { key: 'p1', name: 'Laptop', price: 999, category: 'Electronics' },
      { key: 'p2', name: 'Mouse', price: 29, category: 'Electronics' },
      { key: 'p3', name: 'Desk', price: 299, category: 'Furniture' },
    ],
    { model: 'Product' },
  );

  // 4. Initialize (builds indexes). Resolves false, and logs the error,
  //    if processing fails; it doesn't throw.
  await dcupl.init();

  // 5. Create a list to query the model
  const list = dcupl.lists.create({ modelKey: 'Product' });

  // 6. Add filter conditions
  list.catalog.query.addCondition({
    attribute: 'category',
    operator: 'eq',
    value: 'Electronics',
  });

  // 7. Get results
  const results = list.catalog.query.items();
  console.log('Filtered results:', results);
  // → [
  //     { key: 'p1', name: 'Laptop', price: 999, category: 'Electronics' },
  //     { key: 'p2', name: 'Mouse', price: 29, category: 'Electronics' }
  //   ]
}

main();
```

> Run it with `npx tsx demo.ts` or your preferred TypeScript runner.

**Want to skip setup?** [→ Try it in the Playground](/playground) — experiment with filters, sorting, and facets live.

## Common operations

```typescript title="Common query operations"
// Conditions on different attributes combine with AND (with step 6: Electronics and price >= 50)
list.catalog.query.addCondition({ attribute: 'price', operator: 'gte', value: 50 });
list.catalog.query.items(); // → Laptop

// Conditions on the same attribute combine with OR
list.catalog.query.clear(); // removes all conditions and sort/pagination options
list.catalog.query.addCondition([
  { attribute: 'category', operator: 'eq', value: 'Electronics' },
  { attribute: 'category', operator: 'eq', value: 'Furniture' },
]); // → Laptop, Mouse, Desk

// OR across attributes: a group with an explicit groupType
list.catalog.query.clear();
list.catalog.query.addGroup({
  groupKey: 'cheap-or-furniture',
  groupType: 'or',
  queries: [
    { attribute: 'category', operator: 'eq', value: 'Furniture' },
    { attribute: 'price', operator: 'lt', value: 50 },
  ],
}); // → Desk, Mouse

// Sort ('ASC' or 'DESC', uppercase) and paginate
list.catalog.query.clear();
list.catalog.query.applyOptions({ sort: { attributes: ['price'], order: ['ASC'] }, start: 0, count: 2 });
list.catalog.query.items(); // → Mouse, Desk
```

Every other common call (facets, metadata, aggregations) is on one page: [Quick reference](/sdk/reference).

## Update data

Data changes after `init()` are staged. Apply them with `dcupl.update()`; lists then return the new results.

```typescript title="Update data after init"
dcupl.data.upsert([{ key: 'p4', name: 'Monitor', price: 199, category: 'Electronics' }], { model: 'Product' });
await dcupl.update(); // resolves false, and logs the error, if the update fails

list.catalog.query.items(); // → Mouse, Monitor (still sorted by price, 2 per page)
```

## Next steps

- [Setup options](/sdk/setup-options) — Load from the Console, your own files or a script tag
- [Core concepts](/sdk/core-concepts) — Understand models, lists, and query
- [Tutorial: Your First App](/learn/tutorials/first-app) — Build a small app around these calls
- [Models](/sdk/core-concepts/models) — Property types, references, validation rules
- [Querying](/sdk/queries/query-filter) — All filter operators
- [Facets](/sdk/fn/facets) — Build filter UIs with counts
