.md

Setup options

dcupl offers three setups: Console + Loader (recommended), the Loader with your own files, and SDK-only. All of them use the same query API—your application code stays the same regardless of which you choose.

The Console manages your models and data sources visually. The Loader fetches everything at runtime from Console's CDN.

Why it's recommended:

  • Visual model editor – Define schemas without writing JSON
  • External data sources – Load data from any URL, or pull it in from APIs, S3, Azure or git with workflows
  • Environments – Per-environment variables and headers (e.g. dev, staging, prod) in the loader configuration
  • Team collaboration – Non-developers can edit models and data
  • Version control – Draft → Production file versions for safe deployments

Where the project ID and the Browser key come from, and how to pin a version or pick an environment: Load from the console.

Loader with your own files

The Loader doesn't need the Console. Point it at any host that serves a dcupl.lc.json and the files it lists: your own server or CDN, or dcupl serve from the CLI, which serves your project's dcupl/ folder on http://localhost:8083 by default.

Models are JSON files you host next to your data, and versioning is up to you (e.g. git).

Use cases:

  • Local development against the files on your disk
  • Projects that keep models and data in git and deploy them with the app
  • Hosting the files yourself instead of on the dcupl CDN

SDK-only

Define models and load data directly in code. No external dependencies.

Use cases:

  • Quick prototypes and learning
  • Small, static datasets bundled with your app
  • Full programmatic control required

Comparison

Console + Loader (recommended) Loader with your own files SDK-only
Packages @dcupl/core + @dcupl/loader @dcupl/core + @dcupl/loader @dcupl/core
Models Visual editor in Console JSON files you host Defined in code
Data Auto-fetched from URLs Auto-fetched from URLs Inline or manual fetch
Environments Loader environments you define Loader environments you define Manual config
Versioning Draft → Production versions Up to you (e.g. git) Up to you (e.g. git)

Setup code

import { Dcupl } from '@dcupl/core';
import { DcuplAppLoader } from '@dcupl/loader';

const dcupl = new Dcupl({
  config: {
    projectId: 'your-project-id', // From Console
    apiKey: 'your-api-key', // From Console
    version: 'draft', // CDN file version: 'draft' (default) or 'production'
  },
});

const loader = new DcuplAppLoader();
dcupl.loaders.add(loader);

// Fetch configuration and data from Console CDN
await loader.config.fetch();
await loader.process(); // loads every resource in the configuration
await dcupl.init();

// Query your data
const list = dcupl.lists.create({ modelKey: 'Product' });
const results = list.catalog.query.items();
import { Dcupl } from '@dcupl/core';
import { DcuplAppLoader } from '@dcupl/loader';

const dcupl = new Dcupl();

const loader = new DcuplAppLoader();
dcupl.loaders.add(loader);

// Fetches `${baseUrl}/dcupl.lc.json`; `${baseUrl}` in resource URLs
// resolves to the same host
await loader.config.fetch({ baseUrl: 'http://localhost:8083' }); // dcupl serve, or your own host
await loader.process();
await dcupl.init();

// Query your data
const list = dcupl.lists.create({ modelKey: 'Product' });
const results = list.catalog.query.items();
import { Dcupl } from '@dcupl/core';

const dcupl = new Dcupl();

// Define model in code
dcupl.models.set({
  key: 'Product',
  properties: [
    { key: 'name', type: 'string' },
    { key: 'price', type: 'float' },
  ],
});

// Load data inline
dcupl.data.set(
  [
    { key: 'p1', name: 'Widget', price: 29.99 },
    { key: 'p2', name: 'Gadget', price: 49.99 },
  ],
  { model: 'Product' },
);

await dcupl.init();

// Query your data
const list = dcupl.lists.create({ modelKey: 'Product' });
const results = list.catalog.query.items();

For every new Dcupl() option, see DcuplInitOptions.

Script tag (no build step)

For a page without a bundler, load the @dcupl/bundle browser build. It contains the SDK and the Loader and defines one global function, initDcupl():

index.html
<script src="https://cdn.jsdelivr.net/npm/@dcupl/bundle/dist/dcupl.bundle.min.js"></script>
<script>
  initDcupl({
    options: { config: { projectId: 'your-project-id', apiKey: 'your-api-key' } },
  })
    .then(({ dcupl }) => {
      const list = dcupl.lists.create({ modelKey: 'Product' });
      console.log(list.catalog.query.items());
    })
    .catch((error) => console.error('dcupl failed to load', error));
</script>
  • initDcupl({ options, appLoaderConfig, processOptions }) runs the Console + Loader setup above: new Dcupl(options), loader.config.fetch(appLoaderConfig), loader.process(processOptions) and dcupl.init(). It resolves { dcupl, loader } and also sets window.dcupl. It rejects when the loader configuration can't be fetched (Invalid Loader Configuration).
  • For your own files, pass appLoaderConfig: { baseUrl: 'http://localhost:8083' } instead of the project config.
  • It resolves even when init() resolves false; the cause is logged to the console (see When init() Resolves false).
  • The URL above loads the latest release. In production, pin a version and add its integrity hash together with crossorigin="anonymous". Without crossorigin, the browser blocks a cross-origin script that has an integrity hash:
Pinned version
<script
  src="https://cdn.jsdelivr.net/npm/@dcupl/bundle@<version>/dist/dcupl.bundle.min.js"
  integrity="sha384-<hash>"
  crossorigin="anonymous"
></script>

Applications

A loader configuration can define applications: named presets in the applications[] array of dcupl.lc.json that pick resources by tag. Pass a key to process({ applicationKey }) to load only that part of the project; Load one application shows the call and what an unknown key does, Applications in the Loader API the full behaviour, and Applications how the Console uses them.

Migrating from SDK-only to Console

  1. Create a project in Console
  2. Define models in the visual editor (or import existing JSON)
  3. Add data sources (URLs, file uploads)
  4. Get your projectId and apiKey
  5. Replace dcupl.models.set() and dcupl.data.set() with the Loader setup
  6. Query code stays the same—no changes needed