Svelte 5 Runes Cheatsheet
Dense interactive reference for state primitives, component boundary interfaces, and side-effect runes.
Declares fine-grained reactive state. Mutating properties on objects or arrays triggers targeted updates.
let count = $state(0);<script lang="ts"> let user = $state({ name: 'Alex', score: 10 });</script><button onclick={() => user.score++}> Score: {user.score}</button>Declares shallow reactive state. Variable is reactive, inner properties are not proxied.
let data = $state.raw(largeObject);<script lang="ts"> let dataset = $state.raw([{ id: 1, val: 'A' }]); function replaceAll() { dataset = [{ id: 2, val: 'B' }]; }</script>Computes derived state automatically when referenced reactive signals change.
let double = $derived(count * 2);<script lang="ts"> let count = $state(5); let double = $derived(count * 2); let isEven = $derived(count % 2 === 0);</script><p>{count} x 2 = {double} ({isEven ? 'Even' : 'Odd'})</p>Computes complex derived state using a multi-line closure function.
let total = $derived.by(() => { ... return val; });<script lang="ts"> let items = $state([10, 25, 40]); let totalWithTax = $derived.by(() => { const sum = items.reduce((acc, curr) => acc + curr, 0); return sum * 1.2; });</script>Declares component input props with optional default values and rest properties.
let { title, count = 0 } = $props();<script lang="ts"> interface Props { title: string; variant?: 'primary' | 'secondary'; } let { title, variant = 'primary' }: Props = $props();</script><span class={variant}>{title}</span>Marks a prop as eligible for two-way binding using `bind:prop`.
let { value = $bindable() } = $props();<script lang="ts"> // Child Component let { value = $bindable('') }: { value?: string } = $props();</script><input bind:value={value} />Runs side effects when read reactive signals update. Executes post-DOM render.
$effect(() => { ... return () => cleanup(); });<script lang="ts"> let query = $state(''); $effect(() => { console.log('Search query changed:', query); return () => console.log('Cleanup before re-run'); });</script>Runs side effects BEFORE the DOM updates.
$effect.pre(() => { ... });<script lang="ts"> let messages = $state<string[]>([]); let listEl: HTMLElement; $effect.pre(() => { const isAtBottom = listEl?.scrollHeight - listEl?.scrollTop === listEl?.clientHeight; });</script>Console-logs reactive signal changes in development builds. Stripped in production.
$inspect(count, user).with(console.trace);<script lang="ts"> let count = $state(0); $inspect(count);</script>Reads reactive signals inside `$effect` or `$derived` without creating a tracking dependency.
import { untrack } from "svelte";<script lang="ts"> import { untrack } from 'svelte'; let a = $state(0); let b = $state(0); $effect(() => { console.log('A changed to:', a); console.log('Current snapshot of B:', untrack(() => b)); });</script>