Lesson 4 / 25
$state
Declare reactive values, objects and arrays.
Reactive variables and deep proxies
let count = $state(0) declares a reactive variable; assigning to it updates everything that reads it. Objects and arrays passed to $state become deeply reactive proxies, so todos.push(item) or user.name = "x" also trigger updates. $state.raw skips the proxy: the value only updates when you reassign it, which is cheaper for large data you replace wholesale. $state.snapshot(value) returns a plain, non-proxied copy, for example before passing it to structuredClone or a library. Class fields can be $state too. In Svelte 4, any top-level let in a component was reactive on assignment and array mutations needed a reassignment such as todos = [...todos, item].
Explicit, fine-grained reactivity
Runes are compiler keywords that declare reactive state, values derived from it and side effects.
Primitive, deep and raw state
Todo list state.
<script lang="ts">
type Todo = { id: number; text: string; done: boolean };
let text = $state('');
let todos = $state<Todo[]>([]); // deep proxy
let results = $state.raw<string[]>([]); // reassign to update
function add() {
todos.push({ id: Date.now(), text, done: false }); // mutation is tracked
text = '';
}
function log() {
console.log($state.snapshot(todos)); // plain array, not a proxy
}
</script>
<input bind:value={text} />
<button onclick={add} disabled={!text}>Add</button>
<ul>
{#each todos as todo (todo.id)}
<li><input type="checkbox" bind:checked={todo.done} /> {todo.text}</li>
{/each}
</ul>Destructuring breaks the link
let { done } = todo copies the current value; later reads of done are not reactive. Read todo.done where you need it to stay live.
Quick check: What is the main difference between $state and $state.raw for an array?
- $state.raw is not reactive at all
- $state.raw only updates on reassignment, not on mutation
- $state.raw makes the array deeply reactive
- $state.raw can only hold strings
Answer
$state.raw only updates on reassignment, not on mutation — Raw state skips the deep proxy.