Svelte 5’s New Runtime and Compiler Features

Svelte 5 has arrived, bringing a new reactivity model based on runes, reusable markup through snippets, and deeper compiler optimizations. The release continues Svelte’s compiler-first philosophy: components compile to optimized vanilla JavaScript with no runtime library, keeping bundles small and allowing compiled components to work in any JavaScript project.

The upgrade is substantial, but the core changes boil down to a few key concepts.

Runes for Explicit Reactivity

Runes are the new way Svelte manages reactivity. They give developers explicit, fine-grained control over application state, replacing the implicit let declarations and $: syntax of Svelte 4. The three foundational runes are $state, $derived, and $effect.

  • $state declares a reactive variable. When the value changes, Svelte automatically updates everywhere it is used, removing the need for manual DOM updates.
  • $derived creates reactive values calculated from other $state or $derived values. It only recalculates when a dependency changes, which reduces unnecessary work and avoids the gotchas of the old $: syntax.
  • $effect runs code in response to state changes, which is useful for cases like drawing to a <canvas> or interfacing with an external library. Svelte advises using this sparingly, favoring declarative patterns.

Under the hood, runes compile to signals—containers that notify subscribers on change. This allows the framework to track dependencies precisely and update only the parts of the app that need it. Writing stateful components is now more straightforward:

<script>

let count = $state(0);

let doubled = $derived(count * 2);

</script>

<button onclick={() => count++}>

Clicks: {count}

</button>

<p>Click doubled: {doubled}</p>

State Beyond Components

In Svelte 4, global state relied on stores, which had a different API from component reactivity. That disconnect is gone. With .svelte.js and .svelte.ts files, you can define shared state and logic using the same runes API and access it from any component. This eliminates prop drilling, cuts boilerplate, and treats reactivity as a language-level construct rather than a component-only feature.

Compiler Improvements

Svelte has always pushed work to compile time rather than runtime. Svelte 5 extends this with changes that improve performance and developer experience.

Components Are Functions

In Svelte 5, components compile to plain JavaScript functions. Because build tools and JS engines optimize functions aggressively, this simplifies optimization—for example, function components can be inlined into their callers. Svelte claims to be the first major framework where components call each other directly, without intermediary abstraction layers.

Native TypeScript

Previous Svelte versions needed a preprocessor for TypeScript, which added extra moving parts and slowed builds. Svelte 5 handles TypeScript natively. Builds are faster, and you can write typed code directly in markup, including inline event handlers.

Snippets Replace Slots

Snippets are reusable blocks of markup defined within a component, rendered multiple times or passed to other components. They replace Svelte 4’s slot system.

A snippet encapsulates markup for a repeated element, such as a row in a list:

<script>

let items = [

{ id: 1, name: 'Apple', price: 0.5 },

{ id: 2, name: 'Banana', price: 0.25 },

{ id: 3, name: 'Orange', price: 0.75 }

]

</script>

<ul>

{#each items as item}

{@render row(item)}

{/each}

</ul>

{#snippet row(item)}

<li>

<span>{item.name}:</span>

<span>${item.price.toFixed(2)}</span>

</li>

{/snippet}

Within the {#each} block, the snippet is rendered with the {@render} tag for each item.

Snippets also work as props, letting a parent component pass markup to a child component:

<script>

import ItemList from './ItemList.svelte';

let items = [

{ id: 1, name: 'Apple', price: 0.5 },

{ id: 2, name: 'Banana', price: 0.25 },

{ id: 3, name: 'Orange', price: 0.75 }

];

</script>

<ItemList {items}>

// Implicitly pass this snippet as a prop.

{#snippet row(item)}

<li>

<span>{item.name}:</span>

<span>${item.price.toFixed(2)}</span>

</li>

{/snippet}

</ItemList>

The receiving component renders the passed snippet:

<script>

let { row, items } = $props()

</script>

{#each items as item}

{@render row(item)}

{/each}

This separation makes a component like ItemList reusable with different rendering styles—you swap the snippet passed in rather than modifying the component’s internals.

The Broader Ecosystem

SvelteKit is built on Vite, so anything that works in Vite works in SvelteKit. That includes Vitest for testing, Storybook for component development, and @sveltejs/enhanced-img for image optimization. Svelte also inherits Vite’s development server and hot module replacement.

The framework’s popularity continues to grow. The 2024 Stack Overflow Developer Survey (itself built with Svelte) shows 73% developer satisfaction, and the State of JavaScript 2023 survey ranks Svelte high on positivity and retention. Production users include Apple Podcasts, Apple Music, IKEA, Yelp’s Top 100 list, GitPod, and Appwrite.

“Svelte has allowed to us to ship quickly and with confidence, helping us keep pace with a dynamic AI ecosystem, despite a minority of the team being frontend developers. Our latest version of Gradio is also built on top of SvelteKit, bringing all of the power and performance of a best-in-class framework to around 1 million developers every month. The future is equally exciting; now that we are using SvelteKit, we can release a whole host of new features that would otherwise be costly to implement and support.”

Peter Allen (pngwn) Hugging Face

For developers deploying to Vercel, the Build Output API lets SvelteKit implement Vercel features like Incremental Static Regeneration (ISR), streaming serverless responses, dynamic image optimization, and Skew Protection. Several Svelte core team members work at Vercel to keep the framework and its deployment experience aligned. Recent SvelteKit-specific improvements on the platform include enhanced toolbar debugging, improved analytics, integrated feature flagging, and Speed Insights for performance monitoring.

Whether you are starting fresh or upgrading, the interactive Svelte tutorial and the official migration guide can help you navigate the move to Svelte 5.