store

Signature

store(id?: string, options?: StoreOptions): Store

valdres

Create a store to hold all state

Creates a store instance that holds all atom and selector state and manages subscriptions. The store is the central hub for reading, writing, and subscribing to state.

Usage

import { atom, store } from "valdres"

const myStore = store()
const countAtom = atom(0)

Every store exposes a stable, read-only id. Pass one explicitly when an adapter or application needs to address the store later; generated IDs are unique within the loaded Valdres instance.

const checkoutStore = store("checkout")
checkoutStore.id // "checkout"

The Store facade exposes operations and identity, not its mutable graph/cache runtime. Framework and tooling integrations use Valdres' versioned adapter entrypoint instead of reaching through the public Store object.

Options

OptionTypeDescription
batchUpdatesbooleanBatch sequential set() calls within a tick into one notification pass (recommended for React)
enumerablebooleanRetain values enumerably so store.snapshot() can list current state
schemaValidationbooleanValidate atom/selector values against their schema (off by default). Inherited by scoped stores. See Schema Validation.
// Enable schema validation (e.g. outside production)
const devStore = store({ schemaValidation: import.meta.env.DEV })

Reading state

myStore.get(countAtom) // 0

Writing state

// Set directly
myStore.set(countAtom, 42)

// Update based on previous value
myStore.set(countAtom, prev => prev + 1)

Subscribing to changes

Subscription callbacks are notifications. Read the current value from the store when the callback runs:

const unsub = myStore.sub(countAtom, () => {
    console.log("count changed:", myStore.get(countAtom))
})

// Later: stop listening
unsub()

Transactions

Batch multiple updates so subscribers only fire once:

myStore.txn(({ set }) => {
    set(atomA, 1)
    set(atomB, 2)
    // Subscribers fire once after the transaction completes
})

Valdres owns commit and rollback: a successful callback commits once, while a callback that throws discards every staged write. Callback transactions intentionally expose no manual commit() or backing store data.

Warning
Selectors that depend on atoms updated in a transaction will only recompute once, after all updates are applied. This is the intended behavior for performance.

Disposing request stores

Global atoms remember each store that has materialized them so writes can fan out synchronously. Dispose short-lived stores—such as one store per SSR request or background job—when their work finishes:

const requestStore = store()

try {
    return await renderRequest(requestStore)
} finally {
    requestStore.dispose()
}

dispose() is terminal. It drains the store and all descendant scopes of active subscriptions, atom mounts and their timers, onChange / onCommitEnd listeners, pending batched writes, async selector work, and registrations on the global atoms they touched. Cleanup stays proportional to lifecycle resources the store actually created.

Detached scopes are disposed automatically when their last consumer calls detach(). Every later operation on a disposed store throws StoreDisposedError; calling dispose() again is a no-op. Create a new store for later work.

The global store

valdres exports a shared globalStore — the store that global atoms synchronize through. Import it when you need store access outside of a component (scripts, tests, workers, cross-framework code):

import { globalStore } from "valdres"

globalStore.get(myAtom)
globalStore.set(myAtom, 1)

Do not dispose the global store
globalStore is a process-wide singleton that global atoms use for synchronization. Calling globalStore.dispose() throws. Only dispose stores that your application creates with store().

Inside a component you normally read and write through your framework's provider/context instead — see Provider.

See also

  • Provider — provide a store to your component tree
  • useStore — access the current store in your components
  • Schema Validation — opt-in runtime validation via the schemaValidation option