Svelte and SvelteKit course ยท Module 3: Reactivity and Runes
Rune Chamber - Magic of Reactivity
In this lesson4
Welcome to the most sacred place in Asgard - the Rune Chamber! Here you will discover the true magic of Svelte: reactivity. In Svelte 5, this magic has taken a new form - the Runes system.
What is Reactivity?
Reactivity is the automatic updating of the interface when data changes. In Svelte it works like runes - once carved, they automatically react to changes.
Svelte 4 vs Svelte 5
Old Magic (Svelte 4)
<!-- Svelte 4 (legacy) -->
<script>
let count = 0;
// Reactive declaration - $:
$: doubled = count * 2;
$: console.log('Count changed to:', count);
</script>New Magic - Runes (Svelte 5)
<script>
let count = $state(0);
// Derived reactive value
let doubled = $derived(count * 2);
// Side effect
$effect(() => {
console.log('Count changed to:', count);
});
</script>Basic Runes
| Rune | Description | Old Equivalent |
|---|---|---|
$state | Reactive state | let x = ... |
$derived | Derived value | $: x = ... |
$effect | Side effect | $: { ... } |
$props | Component props | export let |
$bindable | Prop with bind | export let + bind: |
$inspect | Watching changes in the console (debug) | $: console.log(x) |
Why Runes?
- Explicitness - it is clear what is reactive
- TypeScript - better typing
- Performance - fine-grained reactivity
- Consistency - the same rules everywhere
<script>
// Svelte 5 with Runes
let warriors = $state(['Ragnar', 'Bjorn']);
let count = $derived(warriors.length);
function addWarrior(name) {
warriors.push(name); // Works! Runes track mutations
}
</script>The runes are carved - the magic is active!
Code for this lesson: App.svelte
<script>
// Rune Chamber - Magic of Reactivity
// Svelte 5 Runes: $state, $derived, $effect
// $state - reactive state
let count = $state(0);
let warriors = $state(['Ragnar', 'Bjorn']);
// $derived - derived value
let doubled = $derived(count * 2);
let totalWarriors = $derived(warriors.length);
// $effect - side effect
$effect(() => {
console.log('Count changed to:', count);
});
function addWarrior() {
warriors.push('New Warrior');
}
</script>
<main class="rune-chamber">
<h1>Rune Chamber</h1>
<p class="subtitle">Svelte 5 Runes - A new era of reactivity</p>
<section class="rune">
<h2>$state - Reactive state</h2>
<p>Count: <strong>{count}</strong></p>
<div class="buttons">
<button onclick={() => count--}>-</button>
<button onclick={() => count++}>+</button>
</div>
</section>
<section class="rune">
<h2>$derived - Derived value</h2>
<p>Doubled: <strong>{doubled}</strong></p>
<p class="hint">Automatically = count * 2</p>
</section>
<section class="rune">
<h2>$state with array</h2>
<p>Warriors ({totalWarriors}):</p>
<ul>
{#each warriors as w}
<li>{w}</li>
{/each}
</ul>
<button onclick={addWarrior}>+ Add warrior</button>
<p class="hint">In Svelte 5 array mutations work!</p>
</section>
</main>
<style>
.rune-chamber {
font-family: 'Georgia', serif;
max-width: 600px;
margin: 0 auto;
padding: 2rem;
background: linear-gradient(135deg, #1a0a2e 0%, #2d1b4e 100%);
color: #e8d5f7;
min-height: 100vh;
}
h1 {
color: #b19cd9;
text-align: center;
}
.subtitle {
text-align: center;
color: #8b7ca8;
}
.rune {
background: rgba(177, 156, 217, 0.1);
border: 1px solid #b19cd9;
border-radius: 8px;
padding: 1.5rem;
margin: 1rem 0;
}
h2 {
color: #b19cd9;
margin-top: 0;
font-size: 1.1rem;
}
strong {
color: #ffd700;
font-size: 1.5rem;
}
.buttons {
display: flex;
gap: 0.5rem;
}
button {
padding: 0.5rem 1rem;
background: #4a2c7a;
color: white;
border: 1px solid #b19cd9;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background: #5a3c8a;
}
ul {
list-style: none;
padding: 0;
}
li {
padding: 0.25rem 0.5rem;
background: rgba(0,0,0,0.3);
margin: 0.25rem 0;
border-radius: 4px;
}
.hint {
font-size: 0.85rem;
color: #8b7ca8;
font-style: italic;
}
</style>Docs entries used in this lesson
Spotted a mistake in this lesson?
Check yourself
Answer the questions from this lesson. Pick an answer to see right away whether it is correct.
1. What are Runes in Svelte 5?
2. Which Runes are the core ones in Svelte 5?