Svelte 5 2025 Review: Runes and Other Exciting New Features

Profile Picture of Facundo Corradini
Facundo Corradini
Senior Developer
Svelte logo

Svelte has ranked as the most admired front-end framework for several years in a row, according to both Stack Overflow and State of JS surveys. Developers love it for its simplicity, efficiency, and—above all—its remarkably satisfying developer experience.

So when the Svelte core team decided to rebuild the framework from the ground up – effectively reworking the very things that made it so loved – it raised some eyebrows. Many developers in the community (myself included) were asking, “Why change something that’s working so well?” 

Table Of Contents

In this article, I want to explore why these changes were necessary. We’ll dig into some key questions to understand the changes, including how they work, and how these changes helped turn Svelte into a smaller, faster, and even more efficient UI framework.

What is Svelte?

Svelte is a modern JavaScript framework used to build interactive user interfaces (UIs). Unlike traditional frameworks like React, Angular or Vue, that are shipped to act as code interpreters at runtime, Svelte acts as a compiler that ships JavaScript code, resulting in faster apps with smaller bundles and minimal runtime overhead. This unique approach eliminates the need for a virtual DOM, making Svelte applications far more performant.

screenshot of the svelte website homepage

Why Developers Love Svelte (Simplicity, Speed, DX)

There are a ton of reasons developers love Svelte. Primarily, though, it’s that Svelte does things very differently from React, Vue, Angular, and most front-end frameworks. In my opinion, Svelte’s popularity boils down to three things: simplicity, performance, and developer experience.

1. Simplicity

Svelte cuts through the noise by stripping away the ceremony other frameworks make you deal with. No useState, no context boilerplate, no lifecycle method acrobatics. If you know JavaScript and HTML, you can build something in Svelte—not because it hides complexity, but because it removes the need for it. 

The hardest part about learning Svelte? Unlearning the clutter you thought was necessary.

2. Performance

    Most frameworks ship a virtual DOM and do reconciliation in the browser. Svelte skips that entirely. It compiles your components at build time into direct DOM operations—which means less JavaScript sent to the browser, less work done at runtime, and apps that load and run faster, especially on mobile or resource-constrained devices. There’s no diffing engine eating up CPU cycles. It just runs.

    3. Developer Experience

      Svelte’s reactivity model is built into the language. No hooks. No proxies. Just variables that update automatically. Combine that with scoped CSS, single-file components, and a ridiculously fast dev server, and you’re looking at a tool that prioritizes flow. You write less code, it does more. You stay in the zone longer.

      Also – Svelte doesn’t force a meta-framework or a complex folder structure. You want to use Tailwind? Fine. You prefer plain CSS? That works too. It’s un-opinionated where it counts, so you can build your stack your way without fighting the framework.

      Hire Pre-Vetted, Remote Svelte Developers
      Need top-tier Svelte talent for your front-end? We’ll connect you with experienced developers who know how to ship fast, modern web apps—without the hiring overhead.
      Start Hiring

      Limitations of Svelte 3 & 4

      Svelte has been a favorite for many (myself included). In small projects, everything looks and works great – but anyone who dared to put it through serious use (read: build a complex application) eventually hit the same limitations.

      The reactivity model, showcased in early tutorials, seemed almost too good to be true—like magic. But digging deeper revealed the same pain points as other frameworks. Here’s where things started to break down.

      summary table of pain points in previous versions of Svelte
      An overview of limitations of Svelte 3 and 4, which often fell short in complex applications.

      1. Unexpected Reactive Behavior

      One of Svelte’s major pain points was its reactivity model. At first glance, it felt almost magical—just write JavaScript, and your UI updates. But under the hood, Svelte only tracked changes triggered by reassignment. 

      So while modifying an object or array (e.g., pushing to an array) looked like it should update the UI, it didn’t—unless you manually reassigned the variable. This behavior was unintuitive and led to subtle bugs that were hard to trace, especially in apps with more complex state.

      2. Convoluted State Management

      State management was another challenge. Svelte 3 introduced Stores to help share reactive state, which worked well—as long as you stayed inside .svelte files. 

      But the moment you needed to interact with that state from a plain JavaScript module, utility, or backend service, things got messier. You had to manually subscribe to the store and handle cleanup yourself:

      1import { myStore } from './store.js';
      2const unsubscribe = myStore.subscribe(value => {
      3 // do something with value
      4});
      5// later, clean up manually
      6unsubscribe();

      This broke the illusion of simplicity. What felt seamless inside a component suddenly required boilerplate and discipline. It also made it harder to scale Svelte in projects where shared state needed to flow across multiple environments, not just the UI layer.

      3. Limited Integration with Non-Svelte Files

      Trying to integrate Svelte into legacy applications brought even more complexity. On paper, it sounded like a good idea: drop in a modern component, get the benefits. Right? Not really.

      In practice, it often led to broken reactivity, clashing DOM updates, and style conflicts. Unless you were willing to refactor the legacy stack to accommodate Svelte’s patterns, it was often more trouble than it was worth.

      4. Scalability Challenges

      Finally, as applications grew, so did the pain of scaling. Svelte didn’t provide strong conventions for things like state normalization, lifecycle abstraction, or logic composition. Developers were often left inventing their own architecture or borrowing patterns from other ecosystems—and it didn’t always map cleanly. For a framework that prides itself on simplicity, the complexity crept in quickly once you got past the basics.

      a visual summarizing how the Svelte framework has evolved through versions 3, 4, and 5
      The evolution of the Svelte framework since version 3 was introduced in 2019.

      So – how does Svelte 5 address these challenges? We’ll cover that in the next section.

      Enter Svelte 5: Runes Explained

      Svelte 5 introduces Runes, a new reactivity model that directly addresses many of the issues above—without sacrificing what made Svelte feel so good to use in the first place.

      table describing new runes in Svelte 5, including state, derived, effect, props, and inspect.
      Svelte 5 introduced 5 primary runes: state, derived, effect, props, and inspect.

      What Are Runes?

      Runes are a set of primitives built around the idea of Signals—values that change over time and automatically notify anything that depends on them. Instead of relying on magic and heuristics, Runes give the compiler explicit instructions about what to track and when.

      There are 5 primary runes: state, derived, effect, props, and inspect. Here’s how each Rune works, and what it replaces.

      1. State Rune: An Explicit, Testable State

      Svelte’s old model relied on let variables and assignment to trigger updates. It worked, but debugging and testing were harder than they needed to be.

      With the state rune, you manage state like a signal with a clear API.

      Old way:

      1let count = 0;
      2
      3function increment() {
      4 count += 1;
      5}

      New Way:

      1const count = state(0);
      2
      3function increment() {
      4 count.set(count.get() + 1);
      5}

      2. Derived Rune: Safer, Smarter Computed Values

      The $: syntax has always been a favorite of newcomers to Svelte, but it had a tendency to lead to out-of-sync dependencies that were a nightmare to debug. 

      derived makes dependencies clear and enables better type inference, and ultimately leads to more predictable behavior. By explicitly defining how one piece of state depends on another, derived reduces the mental overhead when debugging.

      Old Way:

      1$: doubled = count * 2;

      New Way:

      1const doubled = derived(count, (value) => value * 2);

      3. Effect Rune: Controlled Side Effects

      I’ll be honest: when I first saw that effect was one of Svelte’s new runes, I had a moment of “oh no, is Svelte going to become React?” But let’s be real — React is now introducing a compiler in v19, so the copy-paste cuts both ways.

      Like React’s useEffect, Svelte’s effect rune is designed to separate side effects from core logic. That’s not a bad thing. It makes dependencies explicit and helps keep your state updates and DOM interactions predictable and isolated.

      The difference? With Svelte’s compiler in the mix, effect is leaner and more deterministic — no dependency array bugs, no re-running effects because you forgot to memoize a function. It’s a familiar pattern, just stripped down and sharpened.

      Old Way:

      1$: {
      2 console.log(`Count is ${count}`);
      3}

      New Way:

      1effect(() => {
      2 console.log(`Count is ${count.get()}`);
      3});

      4. Props Rune: Centralized, Validated Props

      The props rune centralizes prop management, making it easier to validate and handle defaults. This is especially useful in large applications where components have numerous props with varying types and default values.

      Old Way:

      1export let name;

      New Way:

      1const name = props('name');

      Bonus: the Inspect Rune for Debugging

      The inspect rune is a powerful debugging tool introduced in Svelte 5. It allows developers to monitor state changes and derived values in real time, making it easier to identify and resolve issues during development. It’s similar to console.log, but it will trigger whenever the value updates. 

      Example:

      1<script>
      2 const count = state(0);
      3 inspect(count);
      4</script>
      5
      6<button onclick={() => count++}>Increment</button>

      inspect can also accept a with property, which can be invoked with a callback to specify a debugging pattern or tool.

      Example:

      1<script>
      2 let count = $state(0);
      3 $inspect(count).with((type, count) => {
      4 if (type === 'update') {
      5 debugger; // or `console.trace`, or whatever you want
      6 }
      7 });
      8</script>
      9
      10
      11<button onclick={() => count++}>Increment</button>

      In this example, the debugger will be opened whenever the type is an update. The alternate suggestion of console.trace will provide information of the origin of the change. 

      Other New Features in Svelte 5

      Svelte 5 also introduces a lot of new features aimed at further improving the developer experience and expanding the framework’s capabilities.

      summary graphic of the new features introduced in Svelte 5
      Svelte 5 introduced a number of new features, including enhanced SSR, a new CLI, and native TypeScript support.

      1. Enhanced Server-Side Rendering (SSR)

        Svelte 5 provides a more robust server-side rendering pipeline, ensuring better SEO and faster initial page loads. This update makes Svelte a strong contender for projects where performance and search engine visibility are crucial – though it still trails behind frameworks like Next.js (React) and Nuxt (Vue) when it comes to ecosystem tools or e-commerce sites with dozens of integrations and edge caching. 

        That said, SvelteKit closes the gap and makes Svelte a viable choice for SSR-heavy use cases. 

        2. The New CLI

          Svelte 5 introduces a revamped CLI called SV that simplifies project setup and development workflows. The new CLI enables faster bootstrapping of projects, better scaffolding for SvelteKit, and intuitive defaults that reduce configuration overhead. Features like interactive prompts for templates and configurations ensure that even new developers can get started quickly. 

          The main commands are:

          • sv create to automate the creation of new projects
          • sv add to install addons such as TailwindCSS to an existing project
          • sv migrate, which can auto-magically migrate your Svelte 4 (or prior) project to Svelte 5. The command makes most of the necessary changes and annotates the codebase where developer interaction may be required.
          summary table of Svelte 5 new features
          Overview of the new features introduced in Svelte 5.

          3. Better Component Composition Through Snippets

            Snippets and render tags, are a way to create reusable chunks of markup inside your components. Instead of writing duplicative code like this:

            1{#each images as image}
            2 {#if image.href}
            3 <a href={image.href}>
            4 <figure>
            5 <img src={image.src} alt={image.caption} width={image.width} height={image.height} />
            6 <figcaption>{image.caption}</figcaption>
            7 </figure>
            8 </a>
            9 {:else}
            10 <figure>
            11 <img src={image.src} alt={image.caption} width={image.width} height={image.height} />
            12 <figcaption>{image.caption}</figcaption>
            13 </figure>
            14 {/if}
            15{/each}

            …you can write this:

            1{#snippet figure(image)}
            2 <figure>
            3 <img src={image.src} alt={image.caption} width={image.width} height={image.height} />
            4 <figcaption>{image.caption}</figcaption>
            5 </figure>
            6{/snippet}
            7
            8{#each images as image}
            9 {#if image.href}
            10 <a href={image.href}>
            11 {@render figure(image)}
            12 </a>
            13 {:else}
            14 {@render figure(image)}
            15 {/if}
            16{/each}

            Like function declarations, snippets can have an arbitrary number of parameters, which can have default values, and you can destructure each parameter. 

            However, you can’t use rest parameters (e.g., …args) in Svelte runes because runes aren’t regular JavaScript functions — they’re special syntax that the Svelte compiler analyzes and transforms at build time. So while runes can support default values and destructuring, they require a fixed number of clearly defined parameters. No …args, because there’s no “guessing” allowed at compile time.

            4. Native TypeScript Support

              Svelte 5 comes with built-in TypeScript support, eliminating the need for additional configurations or plugins. This ensures type safety and better developer productivity, especially in larger applications where managing types is critical.

              5. Improved Accessibility

                Accessibility remains a first-class priority in Svelte 5. With smarter defaults, improved ARIA support, and built-in linting tools, developers can build more inclusive web experiences with less manual work. One standout feature: real-time accessibility warnings during development. These alerts flag issues like missing form labels or incorrect ARIA usage as you code, making it easier to catch and fix problems early—before they ship to users.

                overview of accessibility improvements in Svelte 5
                Svelte 5 introduced accessibility improvements like smarter defaults, built-in linting tools, and real-time warnings.

                6. Expanded Animation Capabilities

                  Svelte 5 takes animations to the next level, refining existing tools and adding new ones that let developers create smooth, polished interfaces with minimal effort. Let’s explore each of the expanded animation capabilities below. 

                  View Transitions API integration

                  Svelte 5 now supports the View Transitions API, one of the most powerful animation tools in modern web development. It enables seamless transitions between pages or states—native-like fluidity that feels at home on both desktop and mobile. And since the API is supported in all modern browsers, there’s no extra work to make it cross-platform.

                  Improved FLIP animations

                  Svelte’s FLIP (First, Last, Invert, Play) function has been upgraded for better performance and smoother transitions—especially when reordering elements. It calculates positional changes and animates them intelligently, reducing jank and improving flow.

                  Support for external animation libraries 

                  Need something more complex? Svelte 5 plays well with external tools like Lottie, making it easy to drop in rich, After Effects-style animations without breaking your workflow.

                  a graphic summarizing 3 new accessibility capabilities introduced in Svelte 5
                  Svelte 5 introduced significant improvements for animations, including external libraries and view transitions API

                  Svelte 5: What You’ll Still Have to Figure Out

                  Svelte 5 is a massive leap forward, but it’s not a silver bullet—and it’s worth being clear-eyed about where things still fall short.

                  graphical summary of limitations of svelte 5
                  Svelte 5 is a major step forward, but there are still some limitations.

                  Ecosystem maturity is still catching up

                  While SvelteKit has made real progress, it doesn’t yet rival the depth of tooling or third-party integrations you get with frameworks like Next.js or Nuxt. If you’re building something that leans heavily on a mature plugin system, or you need seamless support for CMSs, auth providers, and edge caching strategies out of the box, you may hit friction.

                  DevTools are getting better, but still feel limited

                  The new inspect rune is a great step forward for debugging, but the overall Svelte devtooling experience still trails what you get in React or Vue ecosystems—especially when it comes to visualizing app state, time-travel debugging, or tracking render performance over time.

                  Complex app patterns still require manual work

                  Svelte 5’s new reactivity model (via Runes) makes shared state and composition much more predictable. But in large apps—where state needs to move between services, routes, and non-component logic—it’s still not as ergonomic or opinionated as other frameworks that have more established patterns for things like data fetching, caching, or auth flows.

                  In short: Svelte 5 gives you a sharper knife. But if you’re building a very large or deeply integrated app, you’ll need to bring your own cutting board.

                  Final Thoughts: How Svelte 5 Changes the Game

                  Svelte 5 isn’t just an upgrade — it’s a redefinition.

                  The latest version keeps everything developers already love about Svelte—speed, simplicity, and a genuinely enjoyable developer experience—while addressing some of the framework’s most painful limitations. 

                  Runes make reactivity more transparent and predictable. SSR is faster and more capable. And features like real-time a11y warnings, improved animation support, and a smarter CLI make it easier to build polished, production-grade apps without a ton of boilerplate.Is it perfect? No. Svelte still lags behind React and Vue in terms of ecosystem depth, and some parts (like state management in large apps) still require careful thinking. But Svelte 5 shows that the team isn’t afraid to challenge its own assumptions—and that alone makes it worth paying attention to.

                  Originally published on May 14, 2025Last updated on Oct 20, 2025

                  Looking to hire?

                  The Scalable Path Newsletter

                  Join thousands of subscribers and receive original articles about building awesome digital products. Check out past issues.