In Svelte 5, the introduction of Runes, particularly the $state
rune, has changed how we manage state in applications. Here's a detailed explanation of when to use $state
vs stores, building on the context provided:
$state
(Using Runes)$state
is the recommended approach for managing reactive state in Svelte 5. Here’s when and why to use it:
$state
:Simple Reactive State: When you need reactive variables that automatically update the UI when their values change.
<script>
let count = $state(0); // Reactive state
</script>
<button onclick={() => count++}>Clicks: {count}</button>
Here, count
is a reactive variable that triggers UI updates whenever it changes.
Shared State Across Components: Use $state
to create shared state that can be imported and used in multiple components.
// state.svelte.js
export const userState = $state({
name: 'John Doe',
});
<!-- App.svelte -->
<script>
import { userState } from './state.svelte.js';
</script>
<p>User name: {userState.name}</p>
This makes userState
accessible across multiple components without the need for stores.
Deep State Management: $state
works seamlessly with arrays and objects, making them deeply reactive.
let todos = $state([
{ done: false, text: 'Learn Svelte 5' }
]);
Changes to todos
or its nested properties will automatically trigger updates.
$state
:$state
.Stores, from svelte/store
, are still useful but are now considered a legacy solution in Svelte 5. Here’s when you might still use them:
writable
, readable
, and derived
stores.<script>
import { writable } from 'svelte/store';
const count = writable(0); // Create a writable store
</script>
<button onclick={() => count.update(n => n + 1)}>Clicks: {$count}</button>
Feature | $state (Runes) |
Stores (Legacy) |
---|---|---|
Ease of Use | Simple and intuitive | Requires boilerplate (writable , derived , etc.) |
Reactivity Scope | Universal (works anywhere) | Limited to components or context |
Performance | Optimized for granular updates | Slightly more overhead |
Use Case | General-purpose reactive state | Complex async streams or legacy |
$state
Over Stores:$state
for new Svelte 5 projects.$state
for shared state across components.$state
for straightforward reactive variables.$state
:$state
:Legacy Store:
import { writable } from 'svelte/store';
export const count = writable(0);
$state
Equivalent:
// state.svelte.js
export const count = $state(0);
In Svelte 5, $state
is the default and preferred way to manage reactive state due to its simplicity and universal reactivity. Stores are still available but should be reserved for specific use cases like complex async data streams or legacy code. Always favor $state
for new development in Svelte 5!