Skip to content
On this page

Smart stores

A smart store is a store that owns its own work: it loads or subscribes to data, decides when to start and stop, and computes derived values. A component only reads the result.

Core has no separate “smart store” API. The behavior comes from three pieces you already have:

  • onMount starts the work when the first listener subscribes and cleans up after the last one leaves. See Lazy Stores and the onMount reference.
  • task marks asynchronous work so that server-side rendering and tests can wait for it. See Tasks and the task reference.
  • computed derives values from other stores and recalculates when they change. See Computed Stores and the computed reference.

A store that opens a WebSocket connection while something is subscribed to it, and closes the connection afterwards:

stores/prices.ts
export const $prices = atom<Prices>({})
onMount($prices, () => {
const ws = new WebSocket(PRICES_URL)
ws.onmessage = (event) => $prices.set(JSON.parse(event.data) as Prices)
return () => ws.close()
})

Nothing connects until a component or another store subscribes to $prices. After the last subscriber goes away, Nano Stores waits one second before running cleanup and closing the socket. A new subscription during that delay keeps the store mounted. See Lazy Stores for the lifecycle details.

Plugins from the ecosystem for common jobs:

  • Persistent: keeps a store in localStorage and syncs it between browser tabs.
  • Query: fetches data into stores with caching and revalidation.
  • Router: keeps the current URL and route params in stores.
  • I18n: holds the current locale and translations.

To see what stores are doing, use Devtools: it shows every store and change in the Redux DevTools extension.

The full list of packages is on the Ecosystem page.