What are Svelte 5 Runes and How to Use Them?

Monday, September 9, 2024
8 min read
what-are-svelte-5-runes-and-how-to-use-them

Idea Behind Runes

Web development has evolved from basic HTML and CSS to more complex JavaScript frameworks. jQuery simplified DOM manipulation, while React, Angular, and Vue introduced new ways to manage complex web applications. Svelte took a unique approach by compiling code to JavaScript.

Svelte 5 introduced a feature called Runes, a new reactivity system. Basically, runes are easy to use tools that help manage data changes in our web apps. They allow developers to create automatically updating values, perform calculations, and trigger actions simultaneously. This makes building reactive websites simpler more than ever.

What are Runes?

At stated in the Svelte 5 documentation, “Runes are function-like symbols that provide instructions to the Svelte compiler. You don’t need to import them from anywhere — when you use Svelte, they’re part of the language.”

Runes are the new form of reactivity in Svelte 5. Main purpose of runes is to keep state or data between components in sync while keeping the code clean and easy to understand. It also can be used inside .svelte.js or .svelte.ts modules so, no boilerplate code is needed to use them.

Core Runes

There are mainly 4 runes in Svelte 5:

  1. $state: Used to define reactive state at the component level.
  2. $derived: Used to create computed values based on other reactive values.
  3. $effect: Used to manage side effects and react to changes in reactive values.
  4. $props: Used to define component props.

$state

The $state rune is used to define the reactive state of your component. This replaces the let variables in before Svelte 5. There are other types of $state runes like $state.raw and $state.snapshot.

  • $state.raw -> Used to create a reactive value that cannot be mutated just can be reassigned.
  • $state.snapshot -> Used to take a static snapshot of a deeply reactive $state proxy.
<script>
let favoriteMovies = $state(['Inception', 'The Matrix', 'Interstellar']);

function addMovie() {
    const movie = prompt("Enter your favorite movie:");
    if (movie) {
        favoriteMovies.push(movie);
    }
}
</script>

<div>
    <h3>Favorite Movies:</h3>
    <ul>
        {#each favoriteMovies as movie}
            <li>{movie}</li>
        {/each}
    </ul>
    <button onclick={addMovie}>Add Movie</button>
</div>

Before Runes, we used to define reactive variables like this and set the new array every time we wanted to update the list. With Runes, we can directly push the new movie to the array.

<script>
  let favoriteMovies = ['Inception', 'The Matrix', 'Interstellar'];

  function addMovie() {
      const movie = prompt("Enter your favorite movie:");
      if (movie) {
          favoriteMovies = [...favoriteMovies, movie];
      }
  }
</script>

<div>
    <h3>Favorite Movies:</h3>
    <ul>
        {#each favoriteMovies as movie}
            <li>{movie}</li>
        {/each}
    </ul>
    <button on:click={addMovie}>Add Movie</button>
</div>

$derived

Derived is basically a computed property in Svelte 5. $derived.by is the other type of $derived rune.

  • $derived.by -> Used to handle complex derivations.

In the example below, we have a derived value that is the sum of two other reactive values.

<script>
	let number = $state(0);
    const squared = $derived(number * number);
    const cubed = $derived(number * number * number);
</script>

<input type="number" bind:value={number}>

<p>Number: {number}</p>
<p>Square of: {squared}</p>
<p>Cube of: {cubed}</p>

$effect

Side effects are the code that react to changes in reactive values. $effect rune is used to manage side effects in Svelte 5. There are other types of $effect runes like $effect:pre, $effect:tracking, $effect:root.

  • $effect.pre -> Runs before the DOM updates.
  • $effect.tracking -> Runs like child effects for tracking context.
  • $effect.root -> Runs like non-tracked effects to make manual control specific effects.

In the example below, we have a $effect rune that checks if the username is valid or not.

<script>
  let username = $state('');
  let isValid = $state(true);

  $effect(() => {
    if (username.length > 3 && username.length < 10) {
      isValid = true;
    } else {
      isValid = false;
    }
  });
</script>


<input type="text" bind:value={username} />

{#if isValid}
  <p>Username is valid!</p>
{:else}
  <p>Username is invalid!</p>
{/if}

$props

$props is the new way to define component props in Svelte 5. Pass props and their types as an object to $props. The other type of $props rune is $bindable.

  • $bindable -> Used to define bindable props.

Example of using $props:

<script>
    let { name = "no name", avatar, followers = 0 } = $props();
</script>

<div>
  <img src={avatar} alt={name} />
  <h2>{name}</h2>
  <p>{followers} followers</p>
</div>

In the parent component, we can pass props to the child component like this:

<ProfileCard name="Rich Harris" avatar="https://example.com/avatar.jpg" followers={1010101010} />

We can also bind props to the parent component using $bindable:

<script>
    let { name = $bindable(), avatar, followers = 0 } = $props();
</script>

<div>
  <img src={avatar} alt={name} />
  <h2>{name}</h2>
  <p>{followers} followers</p>
</div>

In the parent component, we can bind props to the child component like this:

<script>
    let name = "Rich Harris";
</script>

<ProfileCard bind:name={name} avatar="https://example.com/avatar.jpg" followers={1010101010} />

All Runes

Total runes in Svelte 5 are:

  • $state
  • $state.raw
  • $state.snapshot
  • $derived
  • $derived.by
  • $effect
  • $effect.pre
  • $effect.tracking
  • $effect.root
  • $props
  • $bindable
  • $inspect
  • $host

You can find more about runes in the Svelte 5 docs.

Try Runes in Svelte 5

You can try out $state, $derived, $effect, and $props runes with my examples in this stackblitz project.

Recap

We learned about the core runes, including $state, $derived, $effect, and $props, and how they can be used to build reactive web applications. We also covered other types of runes, such as $state.raw, $state.snapshot, $derived.by, $effect.pre, $effect.tracking, $effect.root, $bindable, $inspect, and $host.

If you’re interested in finding out more about Svelte 5 Runes, or any other features such as snippets, event handlers check out the official Svelte 5 docs.

Happy coding with Svelte! 🪄