Svelte 5 with runes is the most important JavaScript framework release of 2025, and in 2026 it is what all new Svelte code should use. The shift from magic $: reactive labels to explicit $state and $derived runes makes the code more predictable, TypeScript-friendly, and debuggable. If you learn Svelte now, you learn it right.
What changed in 2026
- Svelte 5 is the stable, required version for new projects. The Svelte 4 syntax still compiles with warnings but the runes model is the future.
- Runes work in
.svelte.ts files — not just components. Shared reactive state no longer requires a store.
$props() replaces export let for component props, giving full TypeScript inference.
- SvelteKit 2 is the full-stack framework of choice; adapters cover Vercel, Cloudflare Workers, Node, and static.
- Svelte's bundle advantage widened — with the Svelte 5 compiler, tree-shaken output is consistently smaller than React or Vue equivalents.
Setting up a project
npx sv create my-app
# choose: SvelteKit, Svelte 5, TypeScript, ESLint, Prettier
cd my-app
npm install
npm run dev
The sv CLI (previously create-svelte) scaffolds a complete SvelteKit project.
Core concepts: runes
$state — reactive variables
<script lang="ts">
let count = $state(0);
let name = $state("world");
</script>
<button onclick={() => count++}>Clicks: {count}</button>
<input bind:value={name} />
<p>Hello, {name}!</p>
$state is a rune — a special signal-like primitive compiled away by Svelte. No .value needed; assignments are reactive.
$derived — computed values
<script lang="ts">
let price = $state(100);
let quantity = $state(3);
let total = $derived(price * quantity);
</script>
<p>Total: ${total}</p>
$effect — side effects
<script lang="ts">
let query = $state("");
$effect(() => {
// runs when `query` changes; auto-tracks dependencies
console.log("Searching for:", query);
});
</script>
$props() — typed component props
<script lang="ts">
interface Props {
title: string;
count?: number;
onUpdate: (n: number) => void;
}
let { title, count = 0, onUpdate }: Props = $props();
</script>
<h2>{title}</h2>
<button onclick={() => onUpdate(count + 1)}>Increment</button>
Comparison: Svelte vs other frameworks in 2026
| Dimension |
Svelte 5 |
React 19 |
Vue 3 |
Angular 19 |
| Bundle size |
Smallest |
Medium |
Small |
Large |
| Learning curve |
Very low |
Medium |
Low |
High |
| TypeScript DX |
Good |
Excellent |
Excellent |
Excellent |
| SSR / full-stack |
SvelteKit |
Next.js |
Nuxt 4 |
Angular SSR |
| Job market |
Small but growing |
Very large |
Large |
Large |
Svelte is the easiest modern framework to learn. Its job market is smaller but growing, especially in Europe and startups.
SvelteKit routing and data loading
src/routes/
+page.svelte # /
+layout.svelte # shared layout
blog/
+page.svelte # /blog
[slug]/
+page.svelte # /blog/:slug
+page.server.ts # server-side data loading
// src/routes/blog/[slug]/+page.server.ts
import type { PageServerLoad } from "./$types";
export const load: PageServerLoad = async ({ params }) => {
const post = await db.posts.findBySlug(params.slug);
if (!post) throw error(404);
return { post };
};
How to pick the right track
- New personal project / startup → SvelteKit with Vercel or Cloudflare adapter.
- Static site / blog → SvelteKit with
adapter-static.
- Embedding Svelte in an existing site → Use the component build target, no SvelteKit needed.
- Large team with strict conventions → Consider Angular or Next.js; Svelte's flexibility can be a liability at scale.
Common mistakes
Using Svelte 4 syntax in Svelte 5 projects. The compiler accepts both (with warnings in strict mode), but mixing them in the same codebase is confusing. Commit to runes.
Forgetting that $effect tracks synchronously-accessed state. If you read count inside $effect, the effect re-runs when count changes. Reading it outside the effect does not create a dependency.
Putting all state in a component when a .svelte.ts module suffices. Shared reactive state across routes should live in a $state-based module, not passed down through props.
Skipping the SvelteKit load function. Fetching data inside onMount means no SSR, no streaming, and no error boundaries. Use +page.server.ts for server data.
What to skip
- Svelte stores (
writable, readable) for new code — rune-based modules in .svelte.ts files are cleaner and type-safe.
$: reactive declarations in Svelte 5 — they still work but $derived and $effect are the correct replacements.
- Manual
transition: animations for layout shifts — use the animate: directive for list reordering.
FAQ
Is Svelte good for production apps?
Yes. The New York Times, Apple, and Spotify have used Svelte in production. SvelteKit is a mature full-stack framework.
How long does it take to learn Svelte coming from React?
One to two weeks to be productive. The mental model is simpler; the main adjustment is switching from React's explicit re-render model to Svelte's compiler-tracked reactivity.
Does Svelte have a component library?
Several: Skeleton UI, shadcn-svelte, and Flowbite Svelte are the most popular in 2026. All work with Tailwind.
What about state management at scale?
For complex global state, .svelte.ts modules with $state cover most cases. For derived async state, TanStack Query has a Svelte adapter.
Where to go next