Svelte 5 introduces a new feature called "Runes" that changes how Svelte developers manage reactivity. Runes are essentially a way to explicitely say what is reactive, rather than "everything" potentially being reactive in Svelte 4, which leaves it to the compiler to decide.
As Svelte 4 projects grow the compiler doesn't always get it right and things can slow down. In 5, developers explicitly tag variables as changeable - and causing change instead.
$state RuneWrap the function $state() around the value part of your declaration e.g.:
<script>
// Wrap your "0" default value with the $state() function call
let count = $state(0);
</script>
<button on:click={() => count++}>
clicks: {count}
</button>
In this example, count can be punched out into the HTML in the normal Svelte way.
Annoyingly yes, this is more verbose that Svelte 4 but it scales better since the compiler doesn't have to try to figure out what you want to be reactive.
The real bonus however is arrays and objects are now deeply reactive - no more settings a variable to itself! e.g.
let numbers = $state([1, 2, 3]); is all you need.
$props RuneThis replaces export let ... in sub-components:
<script>
// Old
export let title;
export let amount = 0;
// New
let { title, amount = 0 } = $props();
</script>
Annoyingly, to use bind and make the values updateable by the component you have to be explicit inside the component e.g.:
<script>
let { title, amount = $bindable(0) } = $props();
</script>
Download the code for this blog from GitHub at https://github.com/webuildsociety/svelte-headless