CouchSet

Getting started

Install CouchSet, choose an entrypoint, and run your first model operation.

Requirements

CouchSet needs Node.js, Couchbase Server or Capella, and credentials for an existing bucket.

FeatureCluster needs
Key-value CRUDData service + bucket
SQL++ reads (findMany, page, …)Query service + suitable indexes
Full-text / vector / Search geoSearch service
Eventing reconcileEventing service + dedicated metadata collection
npm install couchset
# or: pnpm add couchset / yarn add couchset

Modern API (couchset/next)

New applications should import from couchset/next.

Singleton + Model

import { couchset, Model } from 'couchset/next';

type User = { email: string; displayName?: string };

const users = new Model('User', {
  scope: 'app',
  collection: 'users',
  indexes: [{ name: 'idx_user_email', fields: ['email'] }],
});

await couchset({
  connectionString: process.env.COUCHBASE_URL ?? 'couchbase://localhost',
  username: process.env.COUCHBASE_USERNAME ?? 'Administrator',
  password: process.env.COUCHBASE_PASSWORD ?? 'password',
  bucketName: process.env.COUCHBASE_BUCKET ?? 'app',
});

const created = await users.insert<User>({ email: '[email protected]' });
const found = await users.getById<User>(created.id);

Inserted values include id, createdAt, updatedAt, _type, and _scope. insert rejects an existing ID; use upsert for explicit insert-or-replace.

Models may be constructed before couchset(); operations wait for the shared connection. See Connections and clients.

Client + defineModel

Prefer a client when you want isolated registries, DI, tests, or transactions:

import { createCouchsetClient, dateCodec, defineModel } from 'couchset/next';

type Session = { id: string; userId: string; expiresAt: Date };

const sessions = defineModel<Session>({
  name: 'Session',
  scope: 'auth',
  collection: 'sessions',
  codecs: { expiresAt: dateCodec },
  indexes: [{ name: 'idx_session_user', fields: ['userId'] }],
});

const db = createCouchsetClient({
  connectionString: process.env.COUCHBASE_URL ?? 'couchbase://localhost',
  username: process.env.COUCHBASE_USERNAME ?? 'Administrator',
  password: process.env.COUCHBASE_PASSWORD ?? 'password',
  bucketName: process.env.COUCHBASE_BUCKET ?? 'app',
  models: [sessions],
});

await db.ready();
const sessionModel = db.model(sessions);

defineModel() and db.model() perform no DDL. Create scopes/collections/indexes explicitly (API or CLI):

await db.ensureCollections();
await db.ensureIndexes({ waitForIndexes: true });

Legacy default (couchset)

The package root preserves the older API:

import { couchset, Model } from 'couchset';

await couchset({ connectionString, username, password, bucketName });
const users = new Model('User');
const created = await users.create({ email: '[email protected]' });
const found = await users.findById(created.id);
await users.updateById(created.id, { ...found, email: '[email protected]' });
await users.delete(created.id);

Do not mix assumptions between legacy and modern entrypoints (method names and defaults differ).

  1. Models and definitions — keyspaces, soft delete, keys
  2. CRUD and queries — filters, pagination, TTL
  3. Validation and codecs — dates and write validation
  4. Provisioning and transactions — ensure/plan/CAS

Pitfalls

  • Expecting import or db.model() to create collections/indexes.
  • Mixing couchset and couchset/next APIs in one codebase without clear boundaries.
  • Running SQL++ reads before Query indexes exist.
  • Using Capella / TLS without couchbases:// and encoded credentials (Connections).

See also

On this page