Reactivity (runes)
Svelte 5 ships runes — \$state, \$derived, \$effect. They look like simple function calls but the compiler rewrites them into fine-grained reactive updates. The model is “assignment IS the reaction.”
state / derived / effect runes
EXAMPLE
<script>
// 1) $state — reactive variable
let count = $state(0);
let user = $state({ name: 'Ada', email: '' });
// 2) Mutate normally — Svelte tracks the assignment
function inc() { count++; }
function rename(n) { user.name = n; }
// 3) $derived — like Vue computed, cached, only recomputes on dependency change
let double = $derived(count * 2);
let valid = $derived(user.email.includes('@'));
// 4) $derived.by — for complex multi-line derivations
let summary = $derived.by(() => {
const len = user.name.length;
const ok = valid;
return ok ? `${user.name} (${len} chars, valid email)` : 'invalid';
});
// 5) $effect — side effects, runs after the DOM updates
$effect(() => {
document.title = `Count: ${count}`;
});
// Effect with cleanup
$effect(() => {
const id = setInterval(() => count++, 1000);
return () => clearInterval(id);
});
// 6) $state.raw — opt out of deep reactivity (perf)
let bigList = $state.raw([]); // assigning replaces; mutations are NOT tracked
function loadList(arr) { bigList = arr; }
// 7) Props with the new $props rune
let { initial = 0, onChange } = $props();
// 8) Two-way binding — bindable rune
let value = $state('');
// <input bind:value />
</script>
<!-- Template -->
<button onclick={inc}>Count is {count}, double is {double}</button>
<input bind:value={user.email} />
<p>{summary}</p>
<!-- 9) Migrating from Svelte 4 -->
<!-- Svelte 4: let count = 0; $: double = count * 2; -->
<!-- Svelte 5: let count = $state(0); let double = $derived(count * 2); -->
<!-- 10) Why runes -->
<!-- The old `let count = 0` was magically reactive only in .svelte files,
which broke when you exported reactive state to a .js helper. Runes
work consistently in .svelte and .svelte.js files. -->
Why it matters
Runes make state explicit. The same \$state / \$derived work in both .svelte components and plain .svelte.js modules — finally a clean way to extract reusable reactive logic outside components.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
// Svelte 5 — runes are first-class reactivity. // $state, $derived, $effect, $propsTry it Yourself »
Exercise
Declare reactive state (Svelte 5).
let count =
(0);
Starts with $.
Discussion
Loading…