Setup & Quick Start
Status: The TypeScript SDK is in beta.
Looking to use Rust instead of TypeScript/JavaScript?
Pick the right package
Use @kalamdb/client for app-facing SQL, auth, realtime subscriptions, live rows, and FILE uploads.
Use @kalamdb/consumer only when you also need topic consumption, ACKs, or the high-level worker runtime.
Install
App client only
npm i @kalamdb/clientApp client plus worker runtime
npm i @kalamdb/client @kalamdb/consumerRuntime requirements:
- Node.js
>= 18(or a modern browser for@kalamdb/client) - running KalamDB server (
http://localhost:8080by default)
Quick start: @kalamdb/client
1. Create the client
import { Auth, createClient } from '@kalamdb/client';
const client = createClient({
url: 'http://localhost:8080',
authProvider: async () => Auth.basic('admin', 'AdminPass123!'),
});createClient(...) is the canonical entrypoint for the app-facing SDK.
2. Run a query
const result = await client.query('SELECT CURRENT_USER()');
console.log(result.status, result.results?.[0]);Notes:
query()works over HTTP and does not require a WebSocket connection.- When using
Auth.basic(...), the SDK exchanges those credentials for JWT automatically before the first query or WebSocket connection. - The high-level SDK manages the WebSocket lifecycle automatically. There is no public
connect()call oncreateClient()clients. - With the default
wsLazyConnect: true, the first subscription call opens the shared socket automatically.
3. 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.
4. 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],
);5. 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.
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.
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
- Client Lifecycle
- Querying & DML
- Realtime Subscriptions
Worker docs
Last updated on