Svelte 5 Cheat Sheet
Runes Overview
| Rune |
Purpose |
Replaces |
$state() |
Reactive state |
let declarations |
$derived() |
Computed values |
$: reactive statements |
$effect() |
Side effects |
$: side effects |
$props() |
Component props |
export let |
$bindable() |
Two-way binding |
export let with bind: |
$inspect() |
Debug state |
Console logging |
$host() |
Host element |
Custom elements only |
Quick Reference
State
<script lang="ts">
let count = $state(0);
let user = $state({ name: 'Alice' });
let items = $state([1, 2, 3]);
</script>
Derived
<script lang="ts">
let doubled = $derived(count * 2);
let sum = $derived.by(() => items.reduce((a, b) => a + b, 0));
</script>
Effect
<script lang="ts">
$effect(() => {
console.log(count);
return () => console.log('cleanup');
});
</script>
Props
<script lang="ts">
let { title, count = 0 } = $props();
let { class: className, ...rest } = $props();
</script>
Bindable
<script lang="ts">
let { value = $bindable(0) } = $props();
</script>
Inspect
<script lang="ts">
$inspect(count);
$inspect('Label:', user);
</script>
Host (Custom Elements)
<script lang="ts">
const host = $host();
</script>
Snippets
{#snippet card(title)}
<div>{title}</div>
{/snippet}
{@render card('Hello')}
Events
<button onclick={() => count++}>Click</button>
<input oninput={(e) => value = e.target.value} />
Migration Guide
| Svelte 4 |
Svelte 5 |
let count = 0 |
let count = $state(0) |
$: doubled = count * 2 |
let doubled = $derived(count * 2) |
$: console.log(count) |
$effect(() => console.log(count)) |
export let title |
let { title } = $props() |
<slot /> |
{@render children()} |
<slot name="header" /> |
{@render header()} |
on:click={handler} |
onclick={handler} |
on:click (forward) |
onclick={onclick} (pass as prop) |
Common Patterns
Counter
<script lang="ts">
let count = $state(0);
</script>
<button onclick={() => count++}>{count}</button>
Form Input
<script lang="ts">
let value = $state('');
</script>
<input bind:value />
<p>{value}</p>
Todo List
<script lang="ts">
interface Todo {
id: number;
text: string;
}
let todos = $state<Todo[]>([]);
let input = $state('');
function add() {
todos.push({ id: Date.now(), text: input });
input = '';
}
</script>
<input bind:value={input} />
<button onclick={add}>Add</button>
{#each todos as todo}
<div>{todo.text}</div>
{/each}
Reusable Component
<script lang="ts">
interface Props {
title: string;
onclick: () => void;
}
let { title, onclick }: Props = $props();
</script>
<button {onclick}>{title}</button>
Best Practices
- Use
$state() for all reactive variables
- Prefer
$derived() over $effect() when possible
- Keep effects simple - return cleanup functions
- Use
$bindable() sparingly - prefer one-way data flow
- Pass event handlers as props instead of forwarding
- Use snippets instead of slots for better type safety