Skip to Content
SDK & ClientTypeScript SDKSetup & Quick Start

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/client

App client plus worker runtime

npm i @kalamdb/client @kalamdb/consumer

Runtime requirements:

  • Node.js >= 18 (or a modern browser for @kalamdb/client)
  • running KalamDB server (http://localhost:8080 by 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 on createClient() 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 as subscription_ack or change frames.
  • Keep live SQL in SELECT ... FROM ... WHERE ... form without ORDER BY or LIMIT.

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 wasmUrl explicitly.
  • If the worker runtime cannot find the consumer WASM file, provide consumerWasmUrl explicitly.
  • Set wsLazyConnect: false only when you want the app client’s WebSocket established eagerly.

Next

App-facing docs

Worker docs

Last updated on