Coaction documentation

Build a precise local store today and move the same state model into workers, shared tabs, or collaboration when you need it.

Coaction is a Zustand-style state library with three pieces designed to work as one system:

  • automatic render tracking at the store or slice-field boundary;
  • cached computed values declared as normal accessor getters;
  • mutable-looking updates that publish immutable state.

The default path is intentionally local and synchronous. Shared workers, multiple tabs, and collaboration are capabilities you opt into when the architecture calls for them.

Why Coaction

Coaction is most useful when an application has selector-heavy components, repeated derived state, or a likely path toward worker-backed state. Instead of assembling independent tracking, computed, immutable-update, and selector plugins, Coaction connects those concerns through one reactive graph.

That cohesion has a cost. Zustand remains smaller and more mature, and its explicit selector model is often exactly right for a small store. Coaction's differentiation is concentrated in observer(), cached getters, natural this-bound actions, and the optional shared runtime—not in claiming every store should be more complicated.

Choose your path

GoalStart with
Vanilla, local-only statecoaction/local
React with automatic render trackingcoaction + @coaction/react
Vue, Angular, Svelte, or SolidThe matching @coaction/* framework package
Worker or SharedWorker authoritycoaction/shared or a framework package with worker
Keep an existing Zustand/MobX/Pinia/etc. runtimeThe matching whole-store adapter
Synchronize Coaction-owned state through Yjs@coaction/yjs on the owning store

Documentation version

This site documents Coaction 3.x. A shared authority and every client connected to it must use the same Coaction major and wire protocol.

Design rules worth knowing early

  1. Writes to Coaction-owned state happen inside set().
  2. The public root schema is fixed after initialization; keep dynamic keys inside a declared object or array field.
  3. A shared client is a mirror, not a write authority. Call methods and await them; do not call setState() on the client.
  4. Shared data is a strict JSON tree. Local stores do not inherit that restriction.
  5. External-state adapters bind a whole store and are not supported inside native slices.

Continue with installation or jump directly to the quick start.

On this page