Svelte 5 changed how you write state. Runes replaced the magic auto-subscription model and pulled state management closer to the language. The new question is not "which library do I install" but "which built-in primitive should I reach for first."
This guide is the short answer for teams shipping Svelte in 2026.
What changed in 2026
Svelte 5 went stable in late 2024 and the ecosystem has fully caught up.
- Runes are the default. Almost every Svelte 5 component uses
$state instead of let.
- Stores are still supported. Old
writable and readable stores work and remain idiomatic for cross-component state.
- Most state libraries faded. The need for Pinia/Zustand-style libraries dropped sharply.
How we picked
Five questions to ask before reaching for any pattern.
- Is the state local to one component? Use
$state.
- Does it depend on other state? Use
$derived.
- Does it need to run a side effect? Use
$effect.
- Is it shared across distant components? Use a store.
- Does it need to persist or sync? Use a library.
1. Runes — best for component and module state
$state, $derived, and $effect cover 80% of what apps need. Define $state at module scope and you have a singleton store with no boilerplate. The reactivity is fine-grained and predictable.
The trade-off: runes only work in .svelte and .svelte.ts files. If you want to share state with non-Svelte code, you still need stores or a library.
2. Stores — best for cross-component and external integrations
The writable, readable, and derived store helpers from svelte/store are not deprecated. They are the right answer when you need to share state with code outside of Svelte (RxJS streams, web workers, third-party libraries) or when you want subscribe semantics.
The catch: in pure Svelte 5 codebases, stores feel slightly redundant. Use them where they earn their keep.
3. Context — best for dependency injection
Svelte's setContext and getContext exist for one job: passing data down a deep component tree without prop drilling. They are not a state container. Pair them with a $state rune for the actual state.
Comparison: Svelte state options in April 2026
| Approach |
Scope |
Type safety |
Best for |
$state rune |
Component or module |
Excellent |
Default choice |
$derived rune |
Component or module |
Excellent |
Computed values |
Store (writable) |
Global |
Good |
Cross-component shared state |
| Context |
Tree-scoped |
Good |
Avoiding prop drilling |
| Tanstack Query |
Server cache |
Excellent |
Async data |
Common mistakes to avoid
Using context as a global store. Context is tree-scoped. The moment a component renders outside the provider, your "global" state vanishes.
Wrapping every value in a store. Runes are simpler and faster. Default to them and reach for stores only when you need their features.
Importing a Redux-style library. It works, but you fight the framework the entire way. Svelte's whole design is the opposite of immutable-state-with-reducers.
FAQ
Are stores deprecated in Svelte 5?
No. They are still part of the core API and still idiomatic in many cases.
Can I use Tanstack Query with Svelte?
Yes — there is an official Svelte adapter and it pairs cleanly with runes for UI state.
Should I migrate stores to runes in old code?
Only if it pays off. Working store-based code does not need to be rewritten.
Where to go next
For related guides see Svelte vs React in 2026, Best React state management in 2026, and Best React frameworks in 2026.