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:8080by 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:8080',
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);
},
{
subscriptionOptions: { last_rows: 100 },
},
);
await stop();
await client.disconnect();Notes:
live()is the recommended UI API because it gives you the current materialized row set directly.- Use
subscribeWithSql()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:8080',
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:8080',
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(...)runAgent(...)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:8080 \
--user admin \
--password AdminPass123! \
--namespace app \
--out src/db/schema.tsThen 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:8080',
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