Back to all guides
Svelte 5 advanced 7 min read

Svelte 5 Runes: The Complete Developer Guide

Master $state, $derived, $effect, and $props. Learn how Svelte 5 delivers zero-boilerplate, fine-grained reactivity using compiler signals.

Svelte 5 introduces Runes, an explicit set of compiler primitives that bring fine-grained reactivity directly into standard JavaScript logic without virtual DOM overhead or complex dependency arrays.


Interactive Rune Playground

Try updating the counter below to see Svelte 5’s $state and $derived signal calculations update instantly:

Live Svelte 5 Playground

Interactive $state & $derived Demo

Count Value 0
Step Increment:
Derived Signal State
$derived(count * 2): 0
Parity Check: EVEN

✨ Mutating count directly updates these derived values in fine-grained DOM signals without re-rendering the surrounding template tree.


1. Fine-Grained Reactive State with $state

State in Svelte 5 is declared using the $state() rune. Unlike framework implementations that require explicit setter functions (setState), Svelte 5 allows direct mutations while surgical DOM updates happen behind the scenes:

Reactive State Mutation

Comparing React 19 useState setters with Svelte 5 $state signals.

❌ React 19
✨ Svelte 5 (Runes)

2. Derived Computations with $derived

Use $derived() to calculate reactive values automatically. Derived signals are memoized and only re-evaluate when their underlying dependencies change:

<script>
	let count = $state(5);
	let double = $derived(count * 2);
	let quad = $derived(double * 2);
</script>

<p>Count: {count} | Double: {double} | Quad: {quad}</p>

3. Side Effects with $effect

The $effect() rune handles side effects and synchronization with external systems. It tracks reactive reads automatically and runs after the DOM updates:

<script>
	let query = $state('');

	$effect(() => {
		console.log('Search query updated:', query);

		// Optional teardown function runs before effect re-executes
		return () => {
			console.log('Cleaning up previous search...');
		};
	});
</script>

4. Shared Universal State (.svelte.ts)

Runes aren’t restricted to Svelte components. You can declare reactive state in standard .svelte.ts files and share it across your application:

// src/lib/stores/cart.svelte.ts
export class CartStore {
	items = $state<string[]>([]);
	totalCount = $derived(this.items.length);

	addItem(item: string) {
		this.items.push(item); // Deep reactivity updates all subscribers
	}
}

export const cart = new CartStore();

Key Core Advantages

  1. Universal Usage: Runes work seamlessly inside .svelte components and .svelte.ts modules.
  2. No Dependency Arrays: Unlike React’s useEffect or useMemo, $effect and $derived track read properties automatically.
  3. Deep Mutation Tracking: Object property updates (user.name = 'Alex') and array mutations (items.push()) trigger surgical DOM patches natively.
Found an issue or want to improve this lesson? Edit this page on GitHub
S5
SuperSvelte
Svelte 5 + Hono RPC + Neon

The Batteries-Included Edge TS Framework

Stop assembling your stack from 15 npm packages. Super Svelte ships Auth, Neon DB, Redis SSE, OpenAPI 3.1 Hono RPC, Uploads, and Resend out-of-the-box with sub-10ms edge cold starts.

OpenAPI 3.1 Hono RPC
Better Auth & Multi-Tenancy
Neon DB + Drizzle ORM
Sub-10ms Edge Starts