Setup & Quick Start
Status: The TypeScript SDK is in beta.
This page gets you from install to first query. Pick the package set that matches the code you are writing.
Pick the right package
| If you are writing… | Install |
|---|---|
| UI, service, or script that runs SQL | @kalamdb/client |
| Typed Drizzle table code | @kalamdb/client @kalamdb/orm drizzle-orm |
| Background worker or agent | @kalamdb/client @kalamdb/consumer |
Looking for Rust instead? Use the Rust SDK.
Install
App client only
npm i @kalamdb/clientApp client plus worker runtime
npm i @kalamdb/client @kalamdb/consumerApp client plus Drizzle ORM
npm i @kalamdb/client @kalamdb/orm drizzle-ormRuntime requirements:
- Node.js
>= 18(or a modern browser for@kalamdb/client) - running KalamDB server (
http://localhost:2900by default)
Quick start: @kalamdb/client
Copy this into a script after KalamDB is running locally.
import { Auth, createClient } from '@kalamdb/client'; const client = createClient({ url: 'http://localhost:2900', authProvider: async () => Auth.basic('admin', 'AdminPass123!'),}); const result = await client.query('SELECT CURRENT_USER()');console.log(result.status, result.results?.[0]); await client.disconnect();Notes:
query()works over HTTP and does not require a WebSocket connection.- When using
Auth.basic(user, password), the SDK only sends those credentials toPOST /v1/api/auth/login, then switches authenticated requests and WebSocket traffic to JWT automatically. - The high-level SDK manages the WebSocket lifecycle automatically.
connect()is public for eager or manual reconnect flows, but most apps do not need to call it directly. - With the default
wsLazyConnect: true, the first subscription call opens the shared socket automatically.
Start a live query
const inboxSql = ` SELECT id, room, role, body, created_at FROM support.inbox WHERE room = 'main'`; const stop = await client.live( inboxSql, (rows) => { renderInbox(rows); }, { lastRows: 100, },); await stop();await client.disconnect();Notes:
live()is the recommended UI API because it gives you the current materialized row set directly.- Use
liveEvents()only when you need raw low-level events such assubscription_ackorchangeframes. - Keep live SQL in
SELECT ... FROM ... WHERE ...form withoutORDER BYorLIMIT.
Parameterized queries
Use $1, $2, … placeholders:
const filtered = await client.query( 'SELECT * FROM app.messages WHERE conversation_id = $1 AND is_deleted = $2', ['conv_42', false],);Optional WASM path override
In environments where auto-WASM resolution fails, pass wasmUrl:
const client = createClient({ url: 'http://localhost:2900', authProvider: async () => Auth.basic('admin', 'AdminPass123!'), wasmUrl: '/wasm/kalam_client_bg.wasm',});Quick start: @kalamdb/consumer
Use a separate worker client when you need topic polling or agents. This package is for Node.js worker processes, not browser bundles.
import { Auth } from '@kalamdb/client';import { createConsumerClient } from '@kalamdb/consumer'; const worker = createConsumerClient({ url: 'http://localhost:2900', authProvider: async () => Auth.basic('worker', 'Secret123!'),}); const handle = worker.consumer({ topic: 'orders', group_id: 'billing', auto_ack: true, batch_size: 10,}); await handle.run(async (ctx) => { console.log(ctx.message.offset, ctx.message.value);});The consumer client reuses the same auth model as @kalamdb/client, but adds topic-specific APIs:
consumer({...}).run(...)consumeBatch(...)ack(...)runConsumer(...)
If WASM auto-resolution fails in the worker runtime, use consumerWasmUrl.
Quick start: @kalamdb/orm
Use this path when you want generated tables or Drizzle queries.
Generate a Drizzle schema from a running KalamDB server:
npx kalamdb-orm \ --url http://localhost:2900 \ --user admin \ --password AdminPass123! \ --namespace app \ --out src/db/schema.tsFor local development, pair that generator with the CLI schema watcher so DDL changes rerun your script automatically:
kalam --watch-schema --namespace app --run "npm run schema:gen" --run-on-startThen use the generated tables with the driver:
import { Auth, createClient } from '@kalamdb/client';import { kalamDriver } from '@kalamdb/orm';import { messages } from './db/schema'; const client = createClient({ url: 'http://localhost:2900', authProvider: async () => Auth.basic('admin', 'AdminPass123!'),}); const db = kalamDriver(client);const rows = await db.select().from(messages).limit(20);Common startup pitfalls
- For local dev auth, confirm server credentials and URL first.
- If browser bundling cannot find the client WASM file, provide
wasmUrlexplicitly. - If the worker runtime cannot find the consumer WASM file, provide
consumerWasmUrlexplicitly. - Set
wsLazyConnect: falseonly when you want the app client’s WebSocket established eagerly.
Next
App-facing docs
- Examples
- Chat Quickstart (Docs-Only)
- Authentication
- Drizzle ORM & Generator
- Client Lifecycle
- Querying & DML
- Realtime Subscriptions