Reactivity

Svelte 5 uses runes for reactivity. State changes automatically update the DOM.

$state

Declare reactive state:

<script>
  let count = $state(0);
</script>

<button onclick={() => count++}>
  Clicked {count} times
</button>

Objects and arrays are deeply reactive:

<script>
  let todos = $state([
    { text: "Learn Svelte", done: false }
  ]);
</script>

<button onclick={() => todos[0].done = true}>
  Complete first todo
</button>

$derived

Computed values that update automatically:

<script>
  let count = $state(0);
  let doubled = $derived(count * 2);
  let message = $derived(count === 1 ? "time" : "times");
</script>

<p>{count} {message}, doubled: {doubled}</p>

$effect

Run side effects when dependencies change:

<script>
  let count = $state(0);

  $effect(() => {
    console.log(`count is now ${count}`);
    // Runs on mount and whenever count changes
  });
</script>

Gotcha: $effect runs after the DOM updates, not before. If you need to measure DOM elements, the values will be current.

Tip: Avoid using $effect for deriving values. Use $derived instead - it’s more efficient and doesn’t cause extra re-renders.

Event Handling

Svelte uses standard DOM event attributes:

<button onclick={handleClick}>Click me</button>
<input oninput={(e) => name = e.target.value} />

Gotcha: Svelte 5 uses lowercase onclick, not on:click (that was Svelte 4 syntax).