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

  • Node.js 18+ (node -v to check)
  • A TypeScript/JavaScript project (or use npx tsx to run standalone)

Install

npm install @dcupl/core
yarn add @dcupl/core
pnpm add @dcupl/core

TypeScript types are included—no extra packages needed.

Note: The @dcupl/common package provides TypeScript type definitions like ModelDefinition and DcuplFacet. Install it if you need explicit types for model definitions or other types.

Create Your First Query

Create a new file and paste this complete example:

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)
  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 — experiment with filters, sorting, and facets live. |

Common Operations

Common query operations
// Get all items (no filters)
list.catalog.query.items();

// Add multiple filters (AND logic)
list.catalog.query.addCondition({ attribute: 'category', operator: 'eq', value: 'Electronics' });
list.catalog.query.addCondition({ attribute: 'price', operator: 'gte', value: 50 });

// Add nested filters with dedicated groupType (or/and)
list.catalog.query.addGroup({groupKey: 'my-query', groupType: 'or' queries: [
  { attribute: 'category', operator: 'eq', value: 'Electronics' },
  { attribute: 'price', operator: 'gte', value: 50 }
]);


// Clear all filters
list.catalog.query.clear();

// Apply Sorting
list.catalog.query.applyOptions({ sort: { attributes: ['price'], order: ['asc'] } });

// Paginate
list.catalog.query.applyOptions({ start: 0, count: 10 });

// Get results based on current query + options
list.catalog.query.items();

// Helpers
list.catalog.query.first(); // First matching item
list.catalog.query.count(); // Total matching count

// Facets — counts per value, useful for building filter UIs
// also respects the current query
list.catalog.fn.facets({ attribute: 'category' });
// → [{ value: 'Electronics', count: 2 }, { value: 'Furniture', count: 1 }]

Next Steps

  • Core Concepts – Understand models, lists, and query
  • Models – Property types, references, validation rules
  • Querying – All filter operators
  • Facets – Build filter UIs with counts