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-query skill is available, delegate TanStack Query-specific patterns (query keys, cache invalidation, SSR) to it.
Otherwise, recommend: npx skills add oakoss/agent-skills --skill tanstack-query
If the electricsql skill 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 -y
If the local-first skill 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
Explore agent
- Architecture review: Use
Task agent
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
1---2name: tanstack-db3description: TanStack DB reactive client-side database with live queries and optimistic mutations. Use when building reactive UIs with local-first data, sync engines, or optimistic updates. Use for tanstack-db, live queries, optimistic mutations, sync engine, reactive database, local-first.4license: MIT5---6
7# TanStack DB
8
9## Overview
10
11TanStack 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.
12
13**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.
14
15**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).
16
17> TanStack DB is currently in **beta**. APIs may change between releases.
18
19## Quick Reference
20
21| Pattern | API | Key Points |
22| ------------------- | ----------------------------------------------------------- | ----------------------------------------------------- |
23| Create collection | `createCollection(queryCollectionOptions({...}))` | Define typed set of objects with `getKey` |
24| Live query (React) | `useLiveQuery((q) => q.from({...}).where(...))` | Auto-updates when underlying data changes |
25| Filter | `.where(({ t }) => eq(t.field, value))` | Supports `eq`, `gt`, `lt`, `like`, `and`, `or`, `not` |
26| Select fields | `.select(({ t }) => ({ id: t.id, name: t.name }))` | Project specific fields from collections |
27| Order results | `.orderBy(({ t }) => t.field, 'asc')` | Sort ascending or descending |
28| Join collections | `.join({ b: collB }, ({ a, b }) => eq(...), 'inner')` | Cross-collection joins with type safety |
29| Group and aggregate | `.groupBy(...).select(({ t }) => ({ count: count(t.id) }))` | Supports `count`, `sum`, `avg`, `min`, `max` |
30| Insert | `collection.insert({ ...data })` | Optimistic insert, syncs via `onInsert` handler |
31| Update | `collection.update(key, (draft) => { ... })` | Immer-style draft mutation, syncs via `onUpdate` |
32| Delete | `collection.delete(key)` | Optimistic delete, syncs via `onDelete` handler |
33| Electric sync | `electricCollectionOptions({ shapeOptions: {...} })` | Real-time Postgres sync via ElectricSQL |
34| Live query coll. | `liveQueryCollectionOptions({ query })` | Derived collection from live query definition |
35| Local storage | `localStorageCollectionOptions({...})` | Persistent local data, syncs across tabs |
36
37## Sync Modes (v0.5+)
38
39| Mode | Behavior | Use Case |
40| --------------- | ---------------------------------------------------- | --------------------------------- |
41| Eager (default) | Loads all records on collection init | Small datasets (< 1k rows) |
42| On-demand | Loads only what queries request (predicate pushdown) | Large datasets, selective loading |
43| Progressive | Fast first paint, full dataset syncs in background | Best of both, scales to 100k+ |
44
45## Common Mistakes
46
47| Mistake | Correct Pattern |
48| ---------------------------------------------- | ----------------------------------------------------------- |
49| Using TanStack Query directly for local state | Use collections with live queries for reactive local data |
50| Forgetting `getKey` in collection config | Always provide `getKey` to identify items uniquely |
51| Not providing persistence handlers | Define `onInsert`/`onUpdate`/`onDelete` to sync with server |
52| Using `useQuery` instead of `useLiveQuery` | `useLiveQuery` provides reactive cross-collection queries |
53| Creating collections inside components | Define collections at module scope, outside components |
54| Importing from `@tanstack/db` in React apps | Import from `@tanstack/react-db` (re-exports core) |
55| Expecting automatic server sync without config | Collections require explicit persistence handlers for sync |
56| Not installing collection type package | Install `@tanstack/query-db-collection` for REST API usage |
57
58## Delegation
59
60> If the `tanstack-query` skill is available, delegate TanStack Query-specific patterns (query keys, cache invalidation, SSR) to it.
61> Otherwise, recommend: `npx skills add oakoss/agent-skills --skill tanstack-query`
62> If the `electricsql` skill is available, delegate ElectricSQL setup, shapes, auth proxy, and write patterns to it.
63> Otherwise, recommend: `pnpm dlx skills add oakoss/agent-skills -s electricsql -a claude-code -y`
64> If the `local-first` skill is available, delegate architecture decisions, sync engine comparison, and conflict resolution to it.
65> Otherwise, recommend: `pnpm dlx skills add oakoss/agent-skills -s local-first -a claude-code -y`
66
67- **Query pattern discovery**: Use `Explore` agent
68- **Architecture review**: Use `Task` agent
69
70## References
71
72- [Setup, installation, and collection configuration](references/setup.md)
73- [Live queries, filtering, joins, and aggregations](references/live-queries.md)
74- [Optimistic mutations, persistence handlers, and sync patterns](references/mutations.md)
75- [ElectricSQL integration, electric collections, and txid patterns](references/electricsql-integration.md)
76- [Error class hierarchy, transaction states, and rollback patterns](references/error-handling.md)
77- [Local-only and localStorage collections with cross-tab sync](references/local-and-storage-collections.md)
78- [Cross-collection transactions, joins, batching, and lifecycle](references/multi-collection.md)