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!