Immutable reactive store

TanStackStore

alpha

The tiny reactive core behind serious state.

Store is a framework-agnostic state primitive for immutable updates, derived values, and targeted subscriptions. It is small enough for library internals and flexible enough for product UI state that should stay reactive without becoming server state.

Total DownloadsWeekly DownloadsGitHub Stars
Read the docs

Immutable core

predictable updates and snapshots

Reactive selectors

subscribe to the slice that matters

Adapter friendly

React, Vue, Solid, Svelte, Angular, Lit

settings store

ui.theme

subscribed slice

light

ui.sidebar

subscribed slice

open

ui.density

subscribed slice

comfortable

uiStore.setState()

Previewlight
Docs
Examples
API
Routes
Queries
Tables
Headersubscribes to ui.theme
Sidebarsubscribes to ui.sidebar
List rowssubscribes to ui.density

Why Store

Some state should be local, reactive, and boring.

Store is not trying to be your server cache, database, or router. It is the small state primitive you reach for when client state needs predictable updates, granular subscriptions, and adapters without a framework-specific runtime.

Small enough to sit under other libraries.

Store is the tiny reactive primitive that powers parts of the TanStack ecosystem, including framework adapters and library internals.

Immutable updates keep changes legible.

State transitions are explicit, snapshots are predictable, and derived values can be reasoned about without mutating shared objects in place.

Subscriptions stay narrow.

Components can listen to exactly the state they render, so a busy product surface does not need to repaint just because nearby state changed.

Framework adapters are a layer, not the store.

Use the adapter for your renderer while the core store stays portable across apps, packages, and UI runtimes.

1

Write

An action updates store state through a predictable immutable transition.

2

Derive

Computed values can depend on the store without becoming another hand-synced state bucket.

3

Select

Subscribers choose the exact slice they need for rendering or effects.

4

Adapt

Framework adapters bridge the same store into React, Vue, Solid, Svelte, Angular, Lit, or vanilla code.

Store lifecycle

Write once, derive once, subscribe precisely.

A good store keeps state transitions visible and component subscriptions narrow. Store gives you the primitives without forcing a global architecture on the whole app.

Subscriptions

Let the component ask for less.

Filters, editor drafts, selected rows, hover state, panel layout, and derived labels all change at different speeds. Store lets each UI surface subscribe to its own slice.

const filters = useStore(store, state => state.filters)
const canSave = useStore(store, state => state.draft.isDirty)

component

useStore(appStore, state => state.filters)

derived

visibleCount = selectedIds.length

effect

store.subscribe(selector, listener)

adapter

same core, renderer-specific bindings

Framework adapters

One store core, renderer-specific bindings.

The store can live below React, Preact, Solid, Svelte, Vue, Angular, Lit, or vanilla TypeScript. The adapter connects it to the renderer without changing the state model.

ReactPreactSolidSvelteVueAngularLit

Field notes

The quiet primitive behind louder libraries.

Store matters because it disappears. It gives TanStack libraries a shared reactive substrate while staying small enough for your own client state.

Open source ecosystem

Store is maintained close to the libraries that rely on it.

Maintainers, framework adapters, examples, partners, and GitHub sponsors keep the primitive honest because it has to serve real TanStack packages.

GitHub Sponsors

Wow, you've come a long way!
Only one thing left to do...