Svelte Runes is Here!
Being a strong Svelte fan, I have been following the Svelte Runes proposal with a lot of interest. Since it was announced, there has been a lot of discussion in the community about what it means for the future of Svelte and how it will change the way we write components. Now that the proposal is finalized and the implementation is underway, I wanted to share my thoughts on what Svelte Runes actually are, how they differ from classic Svelte reactivity, and why I think this is a positive change for the framework.
What the Heck is a Rune?
Runes are explicit reactive primitives. Did that already sound like a buzzword? Maybe. But it is also a very clear description of what they are. So instead of Svelte guessing what should be reactive based on assignments and compiler tricks, you now tell it directly.
This means no more invisible reactivity. No more “why did this update” or “why did this not update”.
The core runes you will see most are:
$state$derived$effect
So simple right? They are just functions. They do not have special syntax. They do not require a new mental model. They are just… explicit.
State Before Runes
This is classic Svelte state. Its reactivity is implicit. You declare a variable, and when you assign something to it, Svelte updates the DOM and any reactive statements that depend on it.
<script>
let count = 0;
function increment() {
count += 1;
}
</script>
<button on:click={increment}>
{count}
</button> Most of the time, that is great. Until it is not. When you have a lot of state, or when you are trying to figure out why something is updating, it can get confusing. You have to mentally track which variables are reactive and which are not. You have to remember that any assignment triggers an update. It can lead to bugs and confusion, especially for new developers.
State With Runes
Now the same thing, but explicit.
<script>
const count = $state(0);
function increment() {
count += 1;
}
</script>
<button on:click={increment}>
{count}
</button> At first, this feels unnecessary. Why add more syntax? Why make it more complex? But the answer is control.
You now know exactly what is reactive and do not have to guess. You know that count is state. You know that it will trigger updates when it changes.
Deriving Values Is Now Clear
Before runes, derived values relied on $: labels.
<script>
let count = 0;
let doubled;
$: doubled = count * 2;
</script> This worked, but it was easy to accidentally create weird chains or trigger updates you did not expect.
So with runes:
<script>
const count = $state(0);
const doubled = $derived(count * 2);
</script> This reads like plain English. doubled depends on count, meaning that it will update when count changes.
Another great thing about this, is that it makes refactoring easier. You can move the derived logic around without worrying about accidentally breaking reactivity. You can also easily see which values are derived and which are not, making it easier to understand the data flow in your components.
Effects Are No Longer Hidden
Side effects used to be inside reactive statements too.
<script>
let count = 0;
$: {
console.log('count changed', count);
}
</script> This worked, but it was not clear that this was an effect. It looked like state, but it was actually doing something. It was easy to forget that this runs when count changes, and it was easy to accidentally put non-effect code in there. An example of that would be if you accidentally put a state assignment in there, which would cause an infinite loop, as it would trigger itself over and over again. It was also easy to forget that this runs on every change, which could lead to performance issues if you were doing something expensive in there.
With runes:
<script>
const count = $state(0);
$effect(() => {
console.log('count changed', count);
});
</script> Which makes this much clearer. You know that this is an effect, you know that it runs when count changes, and you know that it is not a state. It has simply become slightly easier to see the intent of the code, and to understand what is going on.
Why This Matters Long Term
Svelte was famous for being easy at the start and sometimes confusing later.
Runes flatten that learning curve by making components more predictable and easier to understand from the start.
If you come from React, this feels familiar but lighter. If you come from classic Svelte, it feels stricter but safer.
But most importantly, the compiler is still doing the heavy work. You are just giving it better instructions.
This Is Not Svelte Becoming React
This is worth saying explicitly ;)
Svelte Runes does not turn Svelte into React. There are no hooks, no dependency arrays and no render loops.
What it does is simply just removing the ambiguity around what is reactive and what is not. It does not change the core principles of Svelte. It does not change how the compiler works. It does not change how you write components. It just makes it more explicit.
My Take
So my personal take on this is that I am very excited about Svelte Runes. I think it is a great step forward for the framework. It makes it more predictable, and makes Svelte feel more grown up. It does not make it harder to write simple components, but it does make it easier to write complex ones without getting lost.
