sveltejs/svelte
Architecture
Active contributors: Rich Harris, Simon H, Dominic Gannaway
One-paragraph summary
A Svelte component is processed in two independent target lanes — client and server — that share a single front-end (parse + analyze) and diverge in transform and runtime. The compiler walks the component AST and generates JavaScript that calls into a small set of runtime primitives (mount, hydrate, blocks like each, if, await, and reactive primitives like state, derived, effect). The runtime, in turn, schedules updates through a fine-grained signals system implemented in packages/svelte/src/internal/client/reactivity.
Major subsystems
| Area | Path | Responsibility |
|---|---|---|
| Compiler front-end | packages/svelte/src/compiler/phases/1-parse |
.svelte → AST + script/style extraction |
| Compiler analysis | packages/svelte/src/compiler/phases/2-analyze |
Scope tracking, CSS pruning, validation, runes detection |
| Client transform | packages/svelte/src/compiler/phases/3-transform/client |
AST → DOM-targeted JS (per-node visitors) |
| Server transform | packages/svelte/src/compiler/phases/3-transform/server |
AST → HTML-emitting JS |
| Client runtime | packages/svelte/src/internal/client |
mount/hydrate, blocks, bindings, events, transitions |
| Server runtime | packages/svelte/src/internal/server |
streaming-friendly HTML renderer |
| Reactivity primitives | packages/svelte/src/internal/client/reactivity |
Source, Derived, Effect, Batch, props, store |
| Public reactive types | packages/svelte/src/reactivity |
SvelteMap, SvelteSet, SvelteDate, SvelteURL, etc. |
| Animation/motion | packages/svelte/src/transition, animate, motion, easing |
Built-in transitions, flip, spring, tweened |
| Stores (legacy) | packages/svelte/src/store |
Svelte-3 style writable/readable stores |
| Preprocessor | packages/svelte/src/compiler/preprocess |
Pluggable script/style/markup transforms before compile |
Compile-then-run pipeline
graph LR
SRC[".svelte source"] --> PARSE["parse<br/><code>1-parse/index.js</code>"]
PARSE --> AST["AST<br/>(fragment + instance + module)"]
AST --> ANALYZE["analyze_component<br/><code>2-analyze/index.js</code>"]
ANALYZE --> ANALYSIS["ComponentAnalysis<br/>+ scope graph"]
ANALYSIS --> TC["transform_component(client)<br/><code>3-transform/client/transform-client.js</code>"]
ANALYSIS --> TS["transform_component(server)<br/><code>3-transform/server/transform-server.js</code>"]
TC --> JSC["client JS<br/>(imports svelte/internal/client)"]
TS --> JSS["server JS<br/>(imports svelte/internal/server)"]
JSC --> RUNC["client runtime<br/>mount/hydrate"]
JSS --> RUNS["server runtime<br/>render → HTML"]The entry point that orchestrates the pipeline is compile() in packages/svelte/src/compiler/index.js. It calls parse, optionally strips TypeScript via remove_typescript_nodes, then analyze_component and transform_component. compileModule follows the same pattern for .svelte.js/.svelte.ts files that contain runes outside a component.
Reactivity at runtime
The runtime is a fine-grained signals system. The three node types are kept in packages/svelte/src/internal/client/reactivity:
graph TD
Source["Source<br/><code>$state(...)</code>"] -->|read by| Derived["Derived<br/><code>$derived(...)</code>"]
Source -->|read by| Effect["Effect<br/><code>$effect(...)</code>, blocks, bindings"]
Derived -->|read by| Effect
Effect -->|writes| Source
Effect -->|enqueues into| Batch["Batch<br/>reactivity/batch.js"]
Batch -->|flushes| Effect- Source — leaf reactive value (
reactivity/sources.js). - Derived — pure computation that re-runs when its sources change (
reactivity/deriveds.js). - Effect — side-effectful reaction; blocks, attribute updates, transitions all schedule effects (
reactivity/effects.js). - Batch — coalesces multiple writes into a single flush so the DOM updates once per microtask (
reactivity/batch.js).
$state writes are made deeply reactive via JS Proxy (see packages/svelte/src/internal/client/proxy.js), which walks property reads/writes and creates Sources on the fly.
Mount / hydrate
The client runtime renders or attaches a component via three entry points exported from packages/svelte/src/internal/client/render.js: mount, hydrate, unmount. Each one runs the compiled component function inside a freshly-minted ComponentContext (internal/client/context.js) and a root Effect so that subsequent reactive updates have a stable owner.
Server rendering
The server pipeline produces an HTML string plus collected <head> content and CSP nonces. The core is Renderer in packages/svelte/src/internal/server/renderer.js. The compiled server module pushes strings, comments, and child renders onto a tree of Renderer nodes; the top-level render() (exported via packages/svelte/src/server/index.js) collects them. Async-aware rendering is handled by promise-flushing logic in the same file.
Cross-cutting flows
- Bindings (
bind:value,bind:this, etc.) — compiled intobind_*calls frominternal/client/dom/elements/bindings/*and create reciprocal effects that read+write aSource. - Transitions/animations — compiled
<div transition:...>becomes a call totransition()ininternal/client/dom/elements/transitions.js, which manages theintro/outrolifecycle and integrates with the reactivity scheduler. - Stores — both legacy
writable/readable(packages/svelte/src/store) and the newcreateSubscriber(packages/svelte/src/reactivity/create-subscriber.js) interoperate with effects.
For the deepest dive on each subsystem, see the packages and systems sections.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.