Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ


Choose your language

InfoQ Homepage News Rethinking "Rethinking Reactivity" - Svelte 5 Introduces Runes

Rethinking "Rethinking Reactivity" - Svelte 5 Introduces Runes

In their “Introducing runes” blog post, the Svelte team presents new syntax to express reactive dependencies in web applications. The extra syntax may increase the maintainability of complex web applications, further advancing Svelte’s enterprise readiness.

Svelte's upcoming runes let developers break down and encapsulate reactive logic into standard JavaScript functions that can be reused across the entire codebase.

In Svelte 3, reactive dependencies are described at the component level through .svelte files. Components would have encapsulated reactive dependencies (let var syntax) that are not visible outside of the component, or explicitly declared external reactive dependencies (export let var syntax) that client components can use through Svelte’s props syntax. For those cases where the reactive dependency is neither local to a component nor convenient to expose in the interface of a component, developers could import Svelte stores.

Svelte’s single file component strongly nudges developers into colocating the three component concerns (styling, content, and behavior) in one file. Colocation makes a lot of sense when those three concerns are intimately related (e.g., appear, change, or disappear together). Styling or behavior that is specific to a component thus benefits from being placed where the component markup is defined (cohesion principle). On the other hand, colocating style or behavior that only loosely depends on a specific component may create maintainability issues or bugs (e.g., duplicated/outdated/dead/missing code). Svelte stores ideally only focus on a single cohesive behavioral concern.

Svelte stores are contained in standard JavaScript files and are similar to RxJS’s observables in that they expose —at least— a .subscribe interface by which the caller can react to values placed in the store. Stores, being decoupled from the application’s component architecture, can evolve independently as long they maintain a constant interface. Conversely, changes in their clients need not lead to change in the stores.

Svelte runes would propose an alternative syntax to Svelte stores. The Svelte team contends that runes are a better alternative:

The reality is that as applications grow in complexity, figuring out which values are reactive and which aren’t can get tricky. […] Having code behave one way inside .svelte files and another inside .js can make it hard to refactor code, for example, if you need to turn something into a store so that you can use it in multiple places.
[…] We’ve found that the store API can get rather unwieldy when you start doing more complex things.

Additionally, the team observes:

[…] Understanding the intricacies of when Svelte chooses to update which values can become rather tricky beyond a certain level of complexity.

The proposed API relies on new $state, $derived, and $effect primitives:

	let { width, height } = $props(); // instead of `export let`

	const area = $derived(width * height);

	$effect(() => {

All three new primitives can be used in both .js and .ts files, in addition to .svelte files.

Having the developer explicit the reactive dependencies through arguably a heavier syntax makes it hard to miss or misunderstand those dependencies. It also enables a range of compiler optimizations, speculatively leading to faster applications. The Svelte team posits:

Signals unlock fine-grained reactivity, meaning that (for example) changes to a value inside a large list needn’t invalidate all the other members of the list. As such, Svelte 5 is ridonkulously fast.

Developers’ early reactions form a mixed bag. A dubitative developer noted on Reddit:

Wow, I don’t know. While I absolutely see what problems this solves, it doesn’t feel the easy Svelte way I loved so far. Svelte was pretty close to vanilla JS.

Reserved words like const, let, and export were used intentionally.

Even things like onMount were easily understandable and usable by anyone who knows a little about lifecycles.

Even $: would disappear what was the most loved part (by me) of the whole Svelte thing.

Hopefully, it will stay opt-in and not become the only way to write Svelte.

One Vue developer felt at home with the new syntax:

As a Vue developer with a few weeks working on a svelte website, runes feel a lot familiar, I like the idea of exposing reactivity so you can reuse component logic in js/ts files or create stores.

Another developer summarized some important benefits of the new syntax as follows:

This does bring two improvements that I have been waiting for eagerly (typed props && a better way of writing reactive code outside of components).

Filip Tangen additionally wrote a detailed review of Svelte 5 considering pros and cons and suggesting a new dialect (codenamed Pelte).

Svelte 5 is still in its early stages. The Svelte team warns:

You can’t use Svelte 5 in production yet. We’re in the thick of it at the moment and can’t tell you when it’ll be ready to use in your apps.

Developers can however access a preview site featuring detailed explanations of the new features and an interactive playground.

About the Author

Rate this Article