Build fluency with Svelte 5's runes system — reactive state, derived values, effects with cleanup, and bindable props.
0 / 5 completed
1 / 5
During standup, a Svelte dev is migrating to Svelte 5 and asks about $state(). How does it differ from Svelte 4?
$state() in Svelte 5 creates deeply reactive state. Unlike Svelte 4's let count = 0 (reactive by compiler magic but only on reassignment), $state uses Proxies so mutations like array.push() or obj.nested.value = x automatically trigger UI updates — no reassignment needed.
2 / 5
In a PR review, a teammate uses $derived() for a filtered list. What should they know?
$derived(expr) wraps a synchronous expression that reads $state values. Svelte tracks which reactive values were read and recomputes the derived value only when they change. The result is cached — multiple reads return the same value until a dependency updates. No dependency array needed.
3 / 5
An incident reveals a memory leak from $effect() not cleaning up a subscription. How do you fix it?
Return a cleanup function from $effect() to handle teardown. Svelte calls it before the effect re-runs (when dependencies change) and when the component is destroyed. This pattern replaces Svelte 4's onDestroy() + manual subscription management for effects.
4 / 5
In a design review, the team migrates to Svelte 5's $props() rune from Svelte 4. What changes?
$props() replaces Svelte 4's export let prop syntax. Destructure with defaults: const { title, count = 0 } = $props(). The destructured variables are reactive — they update when the parent passes new values. For TypeScript, use $props<{ title: string; count?: number }>().
5 / 5
During a code review, a teammate uses $bindable() on a prop. What does this enable?
$bindable() marks a prop as two-way bindable. In the child: const { value = $bindable('') } = $props(). The parent can then use <Child bind:value={parentVar} />. When the child assigns to value, the parent's variable is updated — replacing the Svelte 4 pattern of emitting events to propagate changes upward.