DEV Community

Alex Spinov
Alex Spinov

Posted on

Svelte 5 Has a Free API — Here's How to Use Runes for Fine-Grained Reactivity

Svelte 5 introduces Runes — a new reactivity system that is more explicit, composable, and powerful. Svelte compiles your components into minimal JavaScript with no virtual DOM overhead.

Getting Started

npx sv create my-app
cd my-app
npm install
npm run dev
Enter fullscreen mode Exit fullscreen mode

Runes — The New Reactivity

<script>
  // $state — reactive state
  let count = $state(0);
  let name = $state("World");

  // $derived — computed values
  let doubled = $derived(count * 2);
  let greeting = $derived(`Hello, ${name}!`);

  // $effect — side effects
  $effect(() => {
    console.log(`Count changed to ${count}`);
    document.title = `Count: ${count}`;
  });

  function increment() {
    count++;
  }
</script>

<h1>{greeting}</h1>
<p>Count: {count} (doubled: {doubled})</p>
<button onclick={increment}>+1</button>
<input bind:value={name} />
Enter fullscreen mode Exit fullscreen mode

$state with Objects and Arrays

<script>
  let todos = $state([
    { id: 1, text: "Learn Svelte 5", done: false },
    { id: 2, text: "Build an app", done: false }
  ]);

  function addTodo(text) {
    todos.push({ id: Date.now(), text, done: false });
  }

  function toggleTodo(id) {
    const todo = todos.find(t => t.id === id);
    if (todo) todo.done = !todo.done;
  }

  let remaining = $derived(todos.filter(t => !t.done).length);
</script>

<p>{remaining} remaining</p>
{#each todos as todo}
  <label>
    <input type="checkbox" checked={todo.done} onchange={() => toggleTodo(todo.id)} />
    {todo.text}
  </label>
{/each}
Enter fullscreen mode Exit fullscreen mode

$props — Component Props

<!-- Button.svelte -->
<script>
  let { children, onclick, variant = "primary" } = $props();
</script>

<button class={variant} {onclick}>
  {@render children()}
</button>
Enter fullscreen mode Exit fullscreen mode

Snippets (Replace Slots)

{#snippet header()}
  <h2>My Header</h2>
{/snippet}

{#snippet row(item)}
  <tr><td>{item.name}</td><td>{item.value}</td></tr>
{/snippet}

<Table {header} {row} data={items} />
Enter fullscreen mode Exit fullscreen mode

Need to extract or automate web content at scale? Check out my web scraping tools on Apify — no coding required. Or email me at spinov001@gmail.com for custom solutions.

Top comments (0)