React Live Queries
@kalamdb/react gives React apps hook-first live-query APIs on top of the shared KalamDB TypeScript client. Use it for typed Drizzle screens, raw SQL live views, multi-query dashboards, and AI assistant workspaces with typing, tool calls, and human approvals.
Install @kalamdb/react
npm i @kalamdb/client @kalamdb/react react react-domnpm i @kalamdb/orm drizzle-ormWrap your app with a single KalamDBClient:
import { Auth, createClient } from '@kalamdb/client';import { KalamProvider } from '@kalamdb/react'; const client = createClient({ url: 'http://localhost:8080', authProvider: async () => Auth.basic('admin', 'AdminPass123!'),}); export function App() { return ( <KalamProvider client={client}> <ChatScreen /> </KalamProvider> );}Typed Drizzle Mode
Use generated tables from @kalamdb/orm when you want typed rows and typed mutations.
import { LiveQuery } from '@kalamdb/react';import { asc, eq } from 'drizzle-orm';import { messages } from './schema.generated'; export function MessagesPane({ conversationId }: { conversationId: string }) { return ( <LiveQuery table={messages} where={(table) => eq(table.conversationId, conversationId)} orderBy={(table) => asc(table.createdAt)} deps={[conversationId]} > {({ rows, state, insert }) => ( <section> {rows.map((row) => <article key={row.id}>{row.body}</article>)} <button disabled={state.inserting} onClick={() => insert(messages).values({ id: crypto.randomUUID(), conversationId, role: 'user', body: 'Hello', status: 'sent', createdAt: new Date(), updatedAt: new Date(), })} > Send </button> </section> )} </LiveQuery> );}Raw SQL Mode
Raw SQL mode is useful for quick admin views and non-Drizzle code. It supports KalamDB’s live-compatible subset and normalizes safe ORDER BY and LIMIT clauses into client-side projection.
import { LiveQuery } from '@kalamdb/react'; export function SqlMessagesPane() { return ( <LiveQuery query="SELECT * FROM chat.messages WHERE room = 'main' ORDER BY created_at ASC" getKey="id"> {({ rows, state }) => ( <section>{state.loading ? 'Loading' : rows.length}</section> )} </LiveQuery> );}Multi-Query Assistant Screens
useLiveQueries opens one live controller per named dataset. useLiveSelection derives screen-ready state without copying live rows into effect-managed local state.
import { useLiveQueries, useLiveSelection } from '@kalamdb/react';import { asc, eq } from 'drizzle-orm';import { approvals, messages, toolCalls, typing } from './schema.generated'; export function AssistantWorkspace({ conversationId }: { conversationId: string }) { const live = useLiveQueries({ queries: { messages: { table: messages, where: (table) => eq(table.conversationId, conversationId), orderBy: (table) => asc(table.createdAt), deps: [conversationId], }, typing: { table: typing, where: (table) => eq(table.conversationId, conversationId), deps: [conversationId] }, toolCalls: { table: toolCalls, where: (table) => eq(table.conversationId, conversationId), deps: [conversationId] }, approvals: { table: approvals, where: (table) => eq(table.conversationId, conversationId), deps: [conversationId] }, }, deps: [conversationId], }); const assistant = useLiveSelection(live, (context) => ({ messages: context.messages.rows, typingUsers: context.typing.rows.map((row) => row.userName), activeTools: context.toolCalls.rows.filter((row) => row.status !== 'completed'), pendingApprovals: context.approvals.rows.filter((row) => row.status === 'pending'), approve: (approvalId: string) => context.update(approvals, approvalId).set({ status: 'approved' }), })); return <AssistantLayout {...assistant} busy={live.state.loading || live.state.updating} />;}Rows stay authoritative from KalamDB live streams. Mutation state is local UI state for disabling buttons, showing progress, and surfacing errors.
React AI Chat Example
The KalamDB repo includes examples/react-ai-chat, a runnable validation app for the React package. It demonstrates a conversation sidebar, conversation history loading, multi-file sends, typing state, streamed assistant activity, message edit/cancel actions, tool-call timelines, and human approvals.
cd examples/react-ai-chatnpm installnpm run setupnpm run devThe app defaults to demo mode so you can try the React components without a server. Apply chat-app.sql, set VITE_KALAMDB_DEMO_MODE=false, and run npm run agent when you want the server-backed topic-agent path.