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

  1. Use $state() for all reactive variables
  2. Prefer $derived() over $effect() when possible
  3. Keep effects simple - return cleanup functions
  4. Use $bindable() sparingly - prefer one-way data flow
  5. Pass event handlers as props instead of forwarding
  6. Use snippets instead of slots for better type safety