TanStack DB
Overview
TanStack DB is a reactive client store built on differential dataflow that extends TanStack Query with collections, live queries, and optimistic mutations. It normalizes data into typed collections, enables sub-millisecond cross-collection queries, and provides instant optimistic updates with automatic rollback on failure.
When to use: Reactive UIs needing local-first data, cross-collection joins with live updates, optimistic mutations with automatic sync, real-time sync via ElectricSQL or other backends, apps that outgrow TanStack Query's per-query caching model.
When NOT to use: Simple fetch-and-display (TanStack Query alone suffices), server-components-only apps, purely synchronous local state (useState/Zustand), GraphQL with normalized caching (Apollo/urql).
TanStack DB is currently in beta. APIs may change between releases.
Quick Reference
| Pattern | API | Key Points |
|---|---|---|
| Create collection | createCollection(queryCollectionOptions({...})) | Define typed set of objects with getKey |
| Live query (React) | useLiveQuery((q) => q.from({...}).where(...)) | Auto-updates when underlying data changes |
| Filter | .where(({ t }) => eq(t.field, value)) | Supports eq, gt, lt, like, and, or, not |
| Select fields | .select(({ t }) => ({ id: t.id, name: t.name })) | Project specific fields from collections |
| Order results | .orderBy(({ t }) => t.field, 'asc') | Sort ascending or descending |
| Join collections | .join({ b: collB }, ({ a, b }) => eq(...), 'inner') | Cross-collection joins with type safety |
| Group and aggregate | .groupBy(...).select(({ t }) => ({ count: count(t.id) })) | Supports count, sum, avg, min, max |
| Insert | collection.insert({ ...data }) | Optimistic insert, syncs via onInsert handler |
| Update | collection.update(key, (draft) => { ... }) | Immer-style draft mutation, syncs via onUpdate |
| Delete | collection.delete(key) | Optimistic delete, syncs via onDelete handler |
| Electric sync | electricCollectionOptions({ shapeOptions: {...} }) | Real-time Postgres sync via ElectricSQL |
| Live query coll. | liveQueryCollectionOptions({ query }) | Derived collection from live query definition |
| Local storage | localStorageCollectionOptions({...}) | Persistent local data, syncs across tabs |
Sync Modes (v0.5+)
| Mode | Behavior | Use Case |
|---|---|---|
| Eager (default) | Loads all records on collection init | Small datasets (< 1k rows) |
| On-demand | Loads only what queries request (predicate pushdown) | Large datasets, selective loading |
| Progressive | Fast first paint, full dataset syncs in background | Best of both, scales to 100k+ |
Common Mistakes
| Mistake | Correct Pattern |
|---|---|
| Using TanStack Query directly for local state | Use collections with live queries for reactive local data |
Forgetting getKey in collection config | Always provide getKey to identify items uniquely |
| Not providing persistence handlers | Define onInsert/onUpdate/onDelete to sync with server |
Using useQuery instead of useLiveQuery | useLiveQuery provides reactive cross-collection queries |
| Creating collections inside components | Define collections at module scope, outside components |
Importing from @tanstack/db in React apps | Import from @tanstack/react-db (re-exports core) |
| Expecting automatic server sync without config | Collections require explicit persistence handlers for sync |
| Not installing collection type package | Install @tanstack/query-db-collection for REST API usage |
Delegation
If the
tanstack-queryskill is available, delegate TanStack Query-specific patterns (query keys, cache invalidation, SSR) to it. Otherwise, recommend:npx skills add oakoss/agent-skills --skill tanstack-queryIf theelectricsqlskill is available, delegate ElectricSQL setup, shapes, auth proxy, and write patterns to it. Otherwise, recommend:pnpm dlx skills add oakoss/agent-skills -s electricsql -a claude-code -yIf thelocal-firstskill is available, delegate architecture decisions, sync engine comparison, and conflict resolution to it. Otherwise, recommend:pnpm dlx skills add oakoss/agent-skills -s local-first -a claude-code -y
- Query pattern discovery: Use
Exploreagent - Architecture review: Use
Taskagent
References
- Setup, installation, and collection configuration
- Live queries, filtering, joins, and aggregations
- Optimistic mutations, persistence handlers, and sync patterns
- ElectricSQL integration, electric collections, and txid patterns
- Error class hierarchy, transaction states, and rollback patterns
- Local-only and localStorage collections with cross-tab sync
- Cross-collection transactions, joins, batching, and lifecycle