Back to blog

Svelte 5 and Runes: Why the Framework Is Gaining Ground in 2025

Hello HaWkers, while React and Vue dominate frontend conversations, a framework has been growing silently and winning over developers: Svelte. With the release of Svelte 5 and its Runes, the framework made a significant leap that deserves your attention.

In this article, we'll explore what makes Svelte special, how Runes work, and why you should consider this framework for your next projects.

What Makes Svelte Different

Unlike React and Vue that work as runtime libraries, Svelte is a compiler. This changes everything.

The fundamental difference:

Aspect React/Vue Svelte
Execution Runtime in browser Compilation at build
Bundle Includes framework Only your code
Reactivity Virtual DOM Surgical DOM updates
Typical size 40-100KB+ 5-15KB

What this means in practice:

  • Svelte apps are smaller and faster
  • Less JavaScript for the browser to process
  • Better performance especially on mobile devices
  • Reduced initial load time

Benchmark: In comparative tests, Svelte applications often load 2-3x faster than React equivalents.

Svelte 5 and Runes

Version 5 of Svelte brought a paradigm shift: Runes. They represent a new way of handling reactivity.

What Are Runes

Runes are reactivity primitives inspired by Solid.js that use a special syntax with $:

The main Runes:

  • $state - Declares reactive state
  • $derived - Computed values
  • $effect - Side effects
  • $props - Component props

Before Runes (Svelte 4)

<script>
  // State was implicitly reactive
  let count = 0;
  let doubled = 0;

  // Reactive statements with $:
  $: doubled = count * 2;
  $: console.log('Count changed:', count);

  function increment() {
    count += 1;
  }
</script>

<button on:click={increment}>
  {count} x 2 = {doubled}
</button>

With Runes (Svelte 5)

<script>
  // State explicitly declared
  let count = $state(0);

  // Derived values are explicit
  let doubled = $derived(count * 2);

  // Effects are explicit
  $effect(() => {
    console.log('Count changed:', count);
  });

  function increment() {
    count += 1;
  }
</script>

<button onclick={increment}>
  {count} x 2 = {doubled}
</button>

Code Comparison

Let's see how Svelte compares with React and Vue in real scenarios:

Counter Component

Svelte 5:

<script>
  let count = $state(0);
</script>

<button onclick={() => count++}>
  Clicks: {count}
</button>

<style>
  button {
    padding: 1rem 2rem;
    font-size: 1.2rem;
  }
</style>

React:

import { useState } from 'react';
import './Counter.css';

function Counter() {
  const [count, setCount] = useState(0);

  return (
    <button onClick={() => setCount(count + 1)}>Clicks: {count}</button>
  );
}

export default Counter;

Vue 3:

<script setup>
import { ref } from 'vue';

const count = ref(0);
</script>

<template>
  <button @click="count++">Clicks: {{ count }}</button>
</template>

<style scoped>
button {
  padding: 1rem 2rem;
  font-size: 1.2rem;
}
</style>

Observations:

  • Svelte: Built-in scoped CSS, cleaner syntax
  • React: Needs separate CSS file or CSS-in-JS
  • Vue: Similar to Svelte, but more verbose

Form with Validation

Svelte 5:

<script>
  let email = $state('');
  let password = $state('');
  let errors = $state({});

  let isValid = $derived(
    email.includes('@') &&
    password.length >= 8 &&
    Object.keys(errors).length === 0
  );

  function validate() {
    errors = {};

    if (!email.includes('@')) {
      errors.email = 'Invalid email';
    }

    if (password.length < 8) {
      errors.password = 'Password must be at least 8 characters';
    }
  }

  function handleSubmit(e) {
    e.preventDefault();
    validate();

    if (isValid) {
      console.log('Valid form:', { email, password });
    }
  }
</script>

<form onsubmit={handleSubmit}>
  <div>
    <input
      type="email"
      bind:value={email}
      placeholder="Email"
      oninput={validate}
    />
    {#if errors.email}
      <span class="error">{errors.email}</span>
    {/if}
  </div>

  <div>
    <input
      type="password"
      bind:value={password}
      placeholder="Password"
      oninput={validate}
    />
    {#if errors.password}
      <span class="error">{errors.password}</span>
    {/if}
  </div>

  <button type="submit" disabled={!isValid}>
    Submit
  </button>
</form>

<style>
  .error {
    color: red;
    font-size: 0.8rem;
  }
</style>

SvelteKit: The Full-Stack Framework

Just as Next.js is to React, SvelteKit is to Svelte:

Project Structure

my-sveltekit-app/
├── src/
│   ├── routes/
│   │   ├── +page.svelte          # Home page
│   │   ├── +layout.svelte        # Shared layout
│   │   ├── about/
│   │   │   └── +page.svelte      # /about
│   │   └── blog/
│   │       ├── +page.svelte      # /blog
│   │       ├── +page.server.js   # Server load function
│   │       └── [slug]/
│   │           └── +page.svelte  # /blog/:slug
│   ├── lib/
│   │   └── components/           # Reusable components
│   └── app.html                  # HTML template
├── static/                       # Static assets
├── svelte.config.js
└── vite.config.js

Data Loading

SvelteKit has an elegant data loading system:

// src/routes/blog/+page.server.js
export async function load({ fetch }) {
  const response = await fetch('/api/posts');
  const posts = await response.json();

  return {
    posts,
  };
}
<!-- src/routes/blog/+page.svelte -->
<script>
  export let data;
</script>

<h1>Blog</h1>

{#each data.posts as post}
  <article>
    <h2><a href="/blog/{post.slug}">{post.title}</a></h2>
    <p>{post.excerpt}</p>
  </article>
{/each}

API Routes

// src/routes/api/posts/+server.js
import { json } from '@sveltejs/kit';

export async function GET() {
  const posts = await db.posts.findMany();

  return json(posts);
}

export async function POST({ request }) {
  const data = await request.json();
  const post = await db.posts.create({ data });

  return json(post, { status: 201 });
}

Why Developers Are Migrating

Svelte's growth in 2025 has concrete reasons:

Developer Experience

Strong points:

  • Less boilerplate than React
  • Lower learning curve
  • Simpler debugging (code compiles to vanilla JS)
  • Ultra-fast Hot Module Replacement

Real Performance

js-framework-benchmark benchmarks show Svelte consistently among the fastest:

Common operations (lower = better):

Operation Svelte React Vue
Create 1000 rows 42ms 65ms 58ms
Partial update 15ms 45ms 38ms
Select row 2ms 8ms 5ms
Remove row 12ms 35ms 28ms
Create 10000 rows 410ms 680ms 590ms

Bundle Size

For a typical medium-sized application:

  • Svelte: ~15KB gzipped (framework + app)
  • React: ~45KB gzipped (just React + ReactDOM)
  • Vue: ~35KB gzipped (just Vue core)

Companies Using Svelte

The framework gained enterprise adoption:

  • Apple - Internal documentation
  • Spotify - Internal applications
  • The New York Times - Interactives
  • Square - Dashboards
  • Ikea - Internal tools
  • Brave - Browser UI

When to Choose Svelte

Svelte isn't for every project. Here's when it makes sense:

Ideal Cases

Use Svelte when:

  • Performance is priority (mobile sites, emerging markets)
  • New project without React/Vue code baggage
  • Small/medium team willing to learn
  • Applications with lots of interactivity
  • Sites that need fast loading

Cases to Avoid

Consider alternatives when:

  • Team already deeply masters React/Vue
  • Need mature library ecosystem
  • Hiring is priority (more React devs in market)
  • Large legacy project in another framework

Growing Ecosystem

The Svelte ecosystem has evolved significantly:

Popular libraries:

  • Skeleton - UI components
  • Melt UI - Headless components
  • Superforms - Form handling
  • Threlte - Three.js integration
  • Svelte Query - Data fetching (TanStack Query port)

Getting Started With Svelte 5

If you want to experiment, here's how to start:

Creating a Project

# Create SvelteKit project
npm create svelte@latest my-app

# Recommended options for beginners:
# - Skeleton project
# - TypeScript
# - ESLint + Prettier

cd my-app
npm install
npm run dev

Basic Component Structure

<script>
  // JavaScript/TypeScript logic
  import { onMount } from 'svelte';

  // Props
  let { title, items = [] } = $props();

  // Local state
  let searchTerm = $state('');

  // Derived values
  let filteredItems = $derived(
    items.filter(item =>
      item.name.toLowerCase().includes(searchTerm.toLowerCase())
    )
  );

  // Lifecycle
  onMount(() => {
    console.log('Component mounted');
  });
</script>

<!-- HTML template -->
<div class="container">
  <h1>{title}</h1>

  <input
    type="search"
    bind:value={searchTerm}
    placeholder="Search..."
  />

  <ul>
    {#each filteredItems as item (item.id)}
      <li>{item.name}</li>
    {:else}
      <li>No items found</li>
    {/each}
  </ul>
</div>

<!-- Scoped CSS -->
<style>
  .container {
    max-width: 600px;
    margin: 0 auto;
  }

  input {
    width: 100%;
    padding: 0.5rem;
    margin-bottom: 1rem;
  }
</style>

Conclusion

Svelte 5 with Runes represents a significant evolution in frontend development. The combination of clean syntax, exceptional performance, and superior developer experience is attracting more and more developers.

If you haven't tried Svelte yet, 2025 is an excellent time to start. The framework has matured, the ecosystem has grown, and Runes brought a reactivity approach that many consider superior to alternatives.

This doesn't mean abandoning React or Vue - they're excellent tools with mature ecosystems. But having Svelte in your skill arsenal can open doors to projects where performance and simplicity are priorities.

To complement your studies in modern frameworks, I recommend checking out the article ECMAScript 2025: New JavaScript Features where you'll understand the language fundamentals that power all these frameworks.

Let's go! 🦅

📚 Want to Deepen Your JavaScript Knowledge?

This article covered Svelte, but there's much more to explore in the world of modern development.

Developers who invest in solid, structured knowledge tend to have more opportunities in the market.

Complete Study Material

If you want to master JavaScript from basics to advanced, I've prepared a complete guide:

Investment options:

  • 1x of $4.90 on card
  • or $4.90 at sight

👉 Learn About JavaScript Guide

💡 Material updated with industry best practices

Comments (0)

This article has no comments yet 😢. Be the first! 🚀🦅

Add comments