Designing Global State with Svelte Derived Stores: Requirements, Boundaries, and Checks
Learn how to use Svelte derived stores for global state: requirements, minimal design, data boundaries, operational checks, failure modes, and when to revisit the design.
20 May 2026, 22:51 UTC

Problem
When building a Svelte app, sharing state across many components often leads to prop‑drilling or manual subscription boilerplate. You need a solution that automatically updates dependent UI when the source changes, keeps subscriptions lightweight, and works both in the browser and during server‑side rendering.
Useful Takeaway
Derived stores give you a minimal, reactive view of one or more source stores. They recompute only when a source changes, expose the standard store contract (subscribe, set, update), and automatically clean up subscriptions when components unmount.
Requirements
- Global state that can be read and written from any component.
- Automatic recomputation when any source store updates.
- Zero‑boilerplate subscription handling (no manual
unsubscribecalls). - Compatibility with SvelteKit’s server‑side rendering (SSR) and hydration.
- Ability to test the store logic in isolation.
Smallest Suitable Design
Start with a writable store for the mutable source and a derived store that computes the needed value.
import { writable, derived } from 'svelte/store';
// Source store – e.g., user‑selected theme preference
const themePreference = writable('system'); // 'light' | 'dark' | 'system'
// Derived store – resolves the actual CSS theme
const actualTheme = derived(
themePreference,
$preference => {
if ($preference !== 'system') return $preference;
// Detect system dark‑mode preference
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
}
);
// Component usage
Theme‑dependent UI
Trust / Data Boundaries
The derived store only trusts the values emitted by its source stores. It does not access external APIs directly; if you need async data (e.g., fetching user settings), wrap the async result in a writable store and let the derived store depend on that writable. This keeps the purity of the derivation function and avoids race conditions.
Operational Checks
- **Subscription cleanup** – mount a component that subscribes to the derived store, then unmount it. In Chrome DevTools → Memory → Take heap snapshot, verify no lingering closure referencing the component.
- **Reactivity correctness** – update the source store (
themePreference.set('dark')) and assert that the DOM reflects the new theme immediately. - **SSR hydration** – render a SvelteKit page on the server with a store that reads
localStorage. On the client, ensure the hydrated DOM matches the server HTML; mismatches cause hydration warnings in the console. - **Performance** – profile the derived function with the Performance tab. If the function takes > 16 ms, consider memoizing heavy work or debouncing the source updates.
Failure Modes
- **Blocking UI** – a computationally heavy derived function runs on every source update and can block the main thread, causing frame drops.
- **Stale data** – if the derived store reads from
localStoragedirectly, changes made in another tab won’t trigger a recompute unless you also subscribe to thestorageevent and update a writable store. - **Hydration mismatch** – server‑side initialization of a store (e.g., reading a cookie) that differs from the client‑side value leads to React‑like hydration errors or visual flicker.
Conditions That Would Change the Design
- If the derived logic requires frequent asynchronous calls (e.g., querying an IndexedDB on every change), replace the derived store with a custom store that manages its own async subscription lifecycle.
- When the state volume grows large (megabyte‑scale objects) and many components subscribe, consider splitting the store into domain‑specific slices to reduce unnecessary recomputations.
- If you need to support older browsers without
matchMedia, move the system‑theme detection into a writable store updated via aresizeormediaquerylistener, keeping the derived store pure.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.