/typescript-client
SpacetimeDB TypeScript/React client SDK reference. Use when building web clients that connect to SpacetimeDB.
$ npx -y skills add clockworklabs/spacetimedb --skill typescript-client --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/typescript-client
Context preview
The summary Claude sees to decide when to auto-load this skill.
SpacetimeDB TypeScript/React client SDK reference. Use when building web clients that connect to SpacetimeDB.
SKILL.md
typescript-client.SKILL.mdname: typescript-client
description: SpacetimeDB TypeScript/React client SDK reference. Use when building web clients that connect to SpacetimeDB.
license: Apache-2.0
metadata:
author: clockworklabs
version: "2.0"
role: client
language: typescript
cursor_globs: "**/*.tsx,**/*.ts"
cursor_always_apply: true
SpacetimeDB TypeScript Client
Generated bindings convert snake_case names to camelCase, including row fields: a server column `trip_id` is `tripId` on client rows.
React: main.tsx
import React, { useEffect, useMemo } from 'react';
import ReactDOM from 'react-dom/client';
import { SpacetimeDBProvider } from 'spacetimedb/react';
import { DbConnection } from './module_bindings';
import { MODULE_NAME, SPACETIMEDB_URI } from './config';
import App from './App';
function Root() {
const connectionBuilder = useMemo(() =>
DbConnection.builder()
.withUri(SPACETIMEDB_URI)
.withDatabaseName(MODULE_NAME)
.withToken(localStorage.getItem('auth_token') || undefined),
[]
);
return (
<SpacetimeDBProvider connectionBuilder={connectionBuilder}>
<App />
</SpacetimeDBProvider>
);
}
ReactDOM.createRoot(document.getElementById('root')!).render(<Root />);React: App.tsx
import { useTable, useSpacetimeDB } from 'spacetimedb/react';
import { DbConnection, tables } from './module_bindings';
function App() {
const { isActive, identity: myIdentity, token, getConnection } = useSpacetimeDB();
const conn = getConnection() as DbConnection | null;
// Save auth token
useEffect(() => { if (token) localStorage.setItem('auth_token', token); }, [token]);
// Subscribe when connected. Prefer typed query builders over raw SQL
useEffect(() => {
if (!conn || !isActive) return;
conn.subscriptionBuilder()
.onApplied(() => setSubscribed(true))
.subscribe([tables.entity, tables.record]);
// Or with filters: tables.entity.where(r => r.active.eq(true))
// Or raw SQL: 'SELECT * FROM entity'
}, [conn, isActive]);
// Reactive data. Returns [rows, isReady]
const [entities, entitiesReady] = useTable(tables.entity);
const [records, recordsReady] = useTable(tables.record);
// useTable with row callbacks
const [onlineUsers] = useTable(
tables.entity.where(r => r.active.eq(true)),
{
onInsert: (user) => console.log('User connected:', user.name),
onDelete: (user) => console.log('User disconnected:', user.name),
onUpdate: (oldUser, newUser) => console.log('Updated:', newUser.name),
}
);
// Call reducers with object syntax
conn?.reducers.addRecord({ data }).catch(console.error);
// Compare identities
const isMe = row.owner.toHexString() === myIdentity?.toHexString();
}Vanilla (non-React)
import { DbConnection, tables } from './module_bindings';
const conn = DbConnection.builder()
.withUri('wss://maincloud.spacetimedb.com')
.withDatabaseName('my_module')
.onConnect((ctx) => {
ctx.subscriptionBuilder()
.onApplied(() => console.log('Ready'))
.subscribe([tables.user, tables.message]);
})
.build();
// Row callbacks
conn.db.user.onInsert((ctx, user) => console.log('Joined:', user.name));
conn.db.user.onDelete((ctx, user) => console.log('Left:', user.name));
conn.db.user.onUpdate((ctx, oldUser, newUser) => console.log('Updated:', newUser.name));Gotchas
- **`useTable` rows are `readonly`.** Copy before sorting/mutating, or it fails to type-check:
`const [rows] = useTable(tables.message); const sorted = [...rows].sort(...)`.
- **bigint in JSX.** ids/counts from `t.u64()`/`t.i64()` columns are `bigint`, which React
cannot render. Wrap it: `{Number(row.id)}` or `{String(count)}`.
Read more
name: typescript-client description: SpacetimeDB TypeScript/React client SDK reference. Use when building web clients that connect to SpacetimeDB. license: Apache-2.0 metadata: author: clockworklabs version: "2.0" role: client language: typescript cursor_globs: "**/*.tsx,**/*.ts" cursor_always_apply: true
SpacetimeDB TypeScript Client
Generated bindings convert snake_case names to camelCase, including row fields: a server column `trip_id` is `tripId` on client rows.
React: main.tsx
import React, { useEffect, useMemo } from 'react';
import ReactDOM from 'react-dom/client';
import { SpacetimeDBProvider } from 'spacetimedb/react';
import { DbConnection } from './module_bindings';
import { MODULE_NAME, SPACETIMEDB_URI } from './config';
import App from './App';
function Root() {
const connectionBuilder = useMemo(() =>
DbConnection.builder()
.withUri(SPACETIMEDB_URI)
.withDatabaseName(MODULE_NAME)
.withToken(localStorage.getItem('auth_token') || undefined),
[]
);
return (
<SpacetimeDBProvider connectionBuilder={connectionBuilder}>
<App />
</SpacetimeDBProvider>
);
}
ReactDOM.createRoot(document.getElementById('root')!).render(<Root />);React: App.tsx
import { useTable, useSpacetimeDB } from 'spacetimedb/react';
import { DbConnection, tables } from './module_bindings';
function App() {
const { isActive, identity: myIdentity, token, getConnection } = useSpacetimeDB();
const conn = getConnection() as DbConnection | null;
// Save auth token
useEffect(() => { if (token) localStorage.setItem('auth_token', token); }, [token]);
// Subscribe when connected. Prefer typed query builders over raw SQL
useEffect(() => {
if (!conn || !isActive) return;
conn.subscriptionBuilder()
.onApplied(() => setSubscribed(true))
.subscribe([tables.entity, tables.record]);
// Or with filters: tables.entity.where(r => r.active.eq(true))
// Or raw SQL: 'SELECT * FROM entity'
}, [conn, isActive]);
// Reactive data. Returns [rows, isReady]
const [entities, entitiesReady] = useTable(tables.entity);
const [records, recordsReady] = useTable(tables.record);
// useTable with row callbacks
const [onlineUsers] = useTable(
tables.entity.where(r => r.active.eq(true)),
{
onInsert: (user) => console.log('User connected:', user.name),
onDelete: (user) => console.log('User disconnected:', user.name),
onUpdate: (oldUser, newUser) => console.log('Updated:', newUser.name),
}
);
// Call reducers with object syntax
conn?.reducers.addRecord({ data }).catch(console.error);
// Compare identities
const isMe = row.owner.toHexString() === myIdentity?.toHexString();
}Vanilla (non-React)
import { DbConnection, tables } from './module_bindings';
const conn = DbConnection.builder()
.withUri('wss://maincloud.spacetimedb.com')
.withDatabaseName('my_module')
.onConnect((ctx) => {
ctx.subscriptionBuilder()
.onApplied(() => console.log('Ready'))
.subscribe([tables.user, tables.message]);
})
.build();
// Row callbacks
conn.db.user.onInsert((ctx, user) => console.log('Joined:', user.name));
conn.db.user.onDelete((ctx, user) => console.log('Left:', user.name));
conn.db.user.onUpdate((ctx, oldUser, newUser) => console.log('Updated:', newUser.name));Gotchas
- **`useTable` rows are `readonly`.** Copy before sorting/mutating, or it fails to type-check:
`const [rows] = useTable(tables.message); const sorted = [...rows].sort(...)`.
- **bigint in JSX.** ids/counts from `t.u64()`/`t.i64()` columns are `bigint`, which React
cannot render. Wrap it: `{Number(row.id)}` or `{String(count)}`.
Repo: clockworklabs/spacetimedb
Other skills on spacetimedb.
- /cli
SpacetimeDB CLI reference for initializing projects, building modules, publishing databases, querying data, and managing servers
Open skill - /concepts
Understand SpacetimeDB architecture and core concepts. Use when learning SpacetimeDB or making architectural decisions.
Open skill - /cpp-server
SpacetimeDB C++ server module SDK reference. Use when writing tables, reducers, or module logic in C++.
Open skill - /csharp-client
SpacetimeDB C#/.NET client SDK reference. Use when building C# clients that connect to SpacetimeDB (console, desktop, or any .NET app).
Open skill - /csharp-server
SpacetimeDB C# server module SDK reference. Use when writing tables, reducers, or module logic in C#.
Open skill - /mcp
Operate a running SpacetimeDB database through MCP tools rather than the CLI - list databases, read schemas, run SQL, and call reducers. Use when the client exposes spacetimedb MCP tools and the task is to inspect or change data in a live database.
Open skill

