Spokes.wiki Search About
Created
Updated

Svelte

The second member of coverage edge 4, and the one that turns react from a baseline into a comparison. sveltejs/svelte, MIT, 87,975★ / 5,210 forks / 1,073 open issues, created 2016-11-20, last pushed 2026-08-21; v5.56.10 on npm. Read from svelte.dev on 2026-08-22. Re-checked 2026-10-05: v5.57.1 on npm (published 2026-09-18), 88,284★ / 7,244 forks / 1,123 open issues and pull requests, last pushed 2026-10-03. The overview's first two sentences are unchanged and it names no Svelte 6.

Its own one-line description is deliberately ordinary — "Svelte is a framework for building user interfaces on the web" — and the second sentence is where it parts company with everything else in this wiki:

"It uses a compiler to turn declarative components written in HTML, CSS and JavaScript … into lean, tightly optimized JavaScript."

The reconciler is not there

react's model is three steps — trigger, render, commit — and its load-bearing sentence is "Rendering is React calling your components." A state change re-runs the component function, the framework diffs what came back, and only differing DOM nodes are touched. The cost model follows: calling components is cheap and frequent, touching the surface is expensive and rare.

Svelte moves that work to build time. There is no component function re-run and no diff, because the compiler already knows, statically, which pieces of DOM depend on which pieces of state and emits the update code directly. The framework's runtime presence is what the compiler could not decide ahead of time, not a general-purpose reconciler waiting to be handed a tree.

That is a third bet on the trade ui-framework describes. opentui ships a reconciler for a surface that had none; flutter ships one and makes rebuilds cheap enough to do constantly (flutter-performance-200-hours is about how frequent they become anyway); Svelte declines to ship one and pays for it in what the compiler must be able to see.

Nothing here measures the result. The docs say "lean, tightly optimized" and give no numbers, which is the vendor claim this spoke has learned to flag rather than repeat — same footing as astryx's "consistency at scale" and flutter-3-44's agent-readiness.

Runes: reactivity as compiler keywords

Svelte 5 replaced the reactivity model, and the replacement is the most unusual thing on this page. Runes are "symbols that you use in .svelte and .svelte.js / .svelte.ts files to control the Svelte compiler." There are seven: $state, $derived, $effect, $props, $bindable, $inspect, $host.

They look like function calls and are not. The docs are explicit that they are language keywords: you do not import them, you cannot store one in a variable or pass one as an argument, and they are only valid in particular syntactic positions, where the compiler will tell you if you have put one in the wrong place.

This is a real departure from how every other toolkit in the corpus works. React's hooks are ordinary functions constrained by convention and a lint rule; the Rules of Hooks are enforced socially and by tooling that sits beside the language. Svelte's equivalents are enforced by a compiler that rejects the program. The framework's API is not a library surface at all — it is a dialect, and using it means accepting that .svelte.js is not quite JavaScript.

$state is the one to understand. From the docs: "count is just a number, rather than an object or a function, and you can update it like you would update any other variable." Assign to it and the UI follows. For arrays and plain objects it produces a deeply reactive Proxy, because "Proxies allow Svelte to run code when you read or write properties, including via methods like array.push(...), triggering granular updates" — recursively, until it hits something that is not a plain object.

The consequences are stated, and they are the seams a real codebase hits:

  • Class instances are not proxied. You declare $state on class fields instead, and the compiler rewrites them into getters and setters over private fields.
  • $state.raw opts out of deep reactivity for performance, at a price: "State declared with $state.raw cannot be mutated; it can only be reassigned."
  • $state.snapshot exists because the proxy is visible from outside — you need a plain object to hand to a library that does not expect one.
  • Reassignable exported state does not cross module boundaries, because the compiler works one file at a time and cannot wrap a reference it does not compile.

That last list is the compiler bet's bill. React's runtime diffing works on any value you can produce; Svelte's build-time analysis needs the shapes it can see through, so the escape hatches are the cases where it cannot.

What it gives the spoke

Coverage edge 4 wanted a second member, and the value is in the disagreement rather than the count. Two first-party sources now describe the same job with no shared mechanism: one calls your code repeatedly and diffs the result, the other reads your code once and writes the updates. The vocabulary this wiki has been using — reconciler, render, rebuild — turns out to be React's vocabulary, not the field's.

It also sharpens the middle of the stack question. shadcn-ui made "what a design system sits on" into an install flag; Svelte makes it a compile-time question, so a component library for it cannot be framework-agnostic in the way a copied React component can. And it puts a second compile-first framework beside flutter — same instinct, opposite surface, and only one of them brings its own rendering engine.

What no source here supplies is the outside evidence: nobody has measured a Svelte application against a React one on bundle size, update cost or anything else. Retracted 2026-09-03. js-framework-benchmark has measured exactly that, on the same specified application, for years, and the wiki had simply not looked. The claim was never checked before it was written.

What the numbers say is narrower than either framework's documentation implies. Brotli-compressed, Svelte ships 9.7 KB against React's 51.4 KB — 5.3×, not the 10–20× the compile-away framing suggests, and vanilla JavaScript at 2.5 KB shows how much of the 9.7 is still framework. On most operations the two are within a few milliseconds. The compile-first design wins decisively on exactly one benchmark, swapping two rows in a keyed list — 12.6 ms against 89.9 — which is the case where a diffing reconciler has to prove that almost nothing changed. The mechanism argument above is correct and its measured consequence is concentrated in one place, not spread across the workload. The benchmark is a table, not an application, so this is evidence about update paths rather than about products.

react · js-framework-benchmark · strawberry-react-to-svelte · ui-framework · flutter · opentui · design-system · shadcn-ui · synthesis