Reactivity with Runes
Runes: explicit reactivity
Section titled “Runes: explicit reactivity”A rune is a compiler signal — a function-like keyword prefixed with $ — that tells Svelte “this value is reactive.” Runes are not imported and not called at runtime like normal functions; the compiler recognizes them and generates the reactivity machinery around them.
<script> let count = $state(0); // reactive state let double = $derived(count * 2); // recomputed when count changes $effect(() => console.log(double)); // runs when double changes</script>The whole model is: mark reactive values with runes, and the compiler wires up the dependency graph. You never write dependency arrays or subscription code — the compiler sees that double reads count and that the effect reads double, and connects them.
The Svelte 4 → 5 shift
Section titled “The Svelte 4 → 5 shift”Runes are the headline change in Svelte 5. They replaced three separate Svelte 4 mechanisms with one consistent system:
| Svelte 4 | Svelte 5 |
|---|---|
let count = 0 (top-level let was implicitly reactive) | let count = $state(0) |
$: double = count * 2 (reactive statement) | let double = $derived(count * 2) |
$: { … } (reactive block, side effects) | $effect(() => { … }) |
export let name (props) | let { name } = $props() |
Why the change? In Svelte 4, reactivity was implicit — a plain let at the top of a component was reactive, but the same code in a .js file was not, and $: had confusing edge cases. Runes make reactivity explicit and portable: $state means the same thing in a component and in a .svelte.js module, and the rules are uniform.
flowchart LR state["$state — a reactive source"] --> derived["$derived — recomputes from sources"] derived --> effect["$effect — runs when its reads change"] props["$props — reactive inputs from parent"] --> derived
What this module covers
Section titled “What this module covers”$state— reactive state, deep by default for objects and arrays.$derived— cached values computed from other reactive values.$effect— synchronize with the outside world (and why you usually should not).$props/$bindable— component inputs and two-way binding.- Advanced —
$inspect,untrack, and shared reactive state in.svelte.jsmodules.