Skip to main content
Smithers custom UIs use TanStack DB as the frontend data layer: UI code reads collections via useLiveQuery, writes through the domain API, and the provider changes with workspace mode.

WorkspaceMode

WorkspaceMode selects the provider:
SmithersGatewayProvider defaults to local mode from the Gateway client base URL; pass mode to createGatewayReactRoot or SmithersGatewayProvider for multiplayer.

Collections

createSmithersCollections(mode, queryClient) returns the same collection names in every mode:
Large node blobs stay fetch-on-demand via useGatewayNodeOutput and useGatewayRpc("getNodeDiff", ...), not collection rows.

Local Provider

Local workspaces use the official QueryCollection provider over the Gateway REST domain API:
GET /v1/api/stream is an SSE invalidation feed; change frames look like this:
The client invalidates matching TanStack Query keys and QueryCollection refetches from /v1/api/*; the stream coalesces bursts, sends heartbeats, reconnects with backoff, and bounds its buffers, sending a reset event (which invalidates every collection key) when the ring can’t replay a missed sequence. SQLite and embedded PGlite mutating routes return { seq }, the invalidation sequence that confirms the local optimistic write.

Multiplayer Provider

Multiplayer workspaces use the official ElectricCollection provider through @smthrs/electric-proxy:
The proxy owns shape scoping, auth, and rate limits; the client passes the catalog shape name and its domain-API auth token. Electric rows map snake_case Postgres columns to the same camelCase types REST returns, so React components and useLiveQuery code never branch on mode. Writes still go through /v1/api/*: Postgres mutating routes return { txid }, captured inside the write transaction with pg_current_xact_id()::xid::text, which Electric transaction matching uses to confirm optimistic state once the shape stream catches up.

React Hooks

The workflow UI hook surface is preserved on top of collections:
Use these hooks for workflow UIs, and useSmithersCollections() for a custom collection query:

Domain Writes

Collection mutation handlers call the same domain API that useGatewayActions() calls:
Confirmation follows the paths above: SSE invalidation for local mode, Electric transaction matching on txid for multiplayer. Shape streams are read-only.