Mastering Svelte Reactive Statements: From Basics to Pitfalls
Learn how Svelte’s $: reactive statements automatically recompute values when dependencies change. This guide covers the core mechanism, a live example, store integration, performance limits, and common pitfalls to avoid.
14 Apr 2026, 10:03 UTC

Why Reactive Statements Matter
When building Svelte components, you often need a value that updates automatically whenever its inputs change. Instead of writing explicit watch logic, Svelte lets you declare reactive statements with the $: prefix. The takeaway: a reactive statement runs after every component update that touches any referenced variable, keeping derived values and the DOM in sync without boilerplate.
How Reactive Statements Execute
Inside a <script> block, a line beginning with $: tells the compiler to treat the expression as a dependency‑aware block. The compiler generates code that
- evaluates the statement after the component’s state has changed.
- re‑runs it whenever any variable referenced in the expression changes.
- ensures the DOM reflects the new value during the same rendering cycle.
Because the statement executes after the component’s state update, you can safely use the new values inside the expression and rely on the DOM being updated in the same tick.
Concrete Example: A Live Sum
Below is a minimal component that demonstrates a reactive sum of two numbers entered by the user.
<script>
import { onMount } from 'svelte';
let a = 0;
let b = 0;
// Reactive statement – recomputes whenever a or b change
$: sum = a + b;
</script>
<label>A: <input type="number" bind:value={a} /></label>
<label>B: <input type="number" bind:value={b} /></label>
<p>Sum: {sum}</p>
When the user types into either input, a or b updates. Svelte then runs the reactive statement, assigns the new sum, and re‑renders the paragraph. No explicit event listeners or $: if blocks are needed.
Unwrapping Stores Inside Reactive Statements
Svelte stores expose a $ prefix that automatically subscribes and unwraps the current value. Inside a reactive statement you can write:
<script>
import { writable } from 'svelte/store';
const counter = writable(0);
// $counter unwraps the store value
$: doubled = $counter * 2;
</script>
<button on:click={() => counter.update(n => n + 1)}>Increment</button>
<p>Doubled: {doubled}</p>
Each click updates the store, the reactive statement recomputes doubled, and the UI updates instantly.
Performance Limits and When to Avoid Heavy Logic
Reactive statements run on every dependency change, even if the result is not used in the template. Heavy computations inside a reactive block can degrade performance. Use memoization or derived stores for expensive work:
const expensive = derived([dep1, dep2], ([$dep1, $dep2]) => heavyCalc($dep1, $dep2));- Wrap the logic in a function and call it only when needed.
Also, be aware that reactive statements are not lazy; they execute during component initialization, so remove unused statements to keep startup fast.
Common Pitfalls and How to Avoid Them
- Infinite Loops
- Assigning to the same variable you reference inside the statement causes a loop:
$: a = a + 1;. - Guard with a condition:
$: if (a < 10) a += 1;or move the logic to an event handler.
- Assigning to the same variable you reference inside the statement causes a loop:
- Order Matters
- A reactive statement can only reference variables defined earlier in the script block. Define
let a;before using it in$: sum = a + b;.
- A reactive statement can only reference variables defined earlier in the script block. Define
- Unintended Re‑runs
- Including a variable that never changes in a reactive statement still forces a run on every component update. Keep statements lean.
- Store Unwrapping Mistakes
- Using
counterinstead of$counterinside a reactive statement will reference the store object, not its value, leading to unexpected results.
- Using
Practical Checklist
| Checklist Item | Check |
|---|---|
| Variables referenced in reactive statements are defined earlier. | ✔ |
| No self‑referencing assignment that causes loops. | ✔ |
Store values are unwrapped with $ when used. | ✔ |
| Heavy logic is extracted to derived stores or functions. | ✔ |
| Unused reactive statements are removed. | ✔ |
Conclusion
Reactive statements are Svelte’s declarative way to keep derived data in sync. By understanding their execution order, unwrapping store values correctly, and guarding against common pitfalls, you can write concise, maintainable components that automatically respond to state changes.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.