CodeVetter
← All unpacks
CodeVetter · Repo Unpack evidence

sveltejs/svelte

Scanned commit 636eaaaa6f dated 2026-09-18 — last upstream commit. Generated by codevetter 1.12.0 on 2026-09-22.

github.com/sveltejs/svelte ↗ · 4000 files · 2.1 MB · scan capped

What is Svelte? Svelte is a new way to build web applications.

Deep analysis by claude-opus-5 via the claude CLI on 2026-09-22 (426s) — every claim below links to its cited source files.

Overview

This is the `sveltejs/svelte` monorepo: a single publishable package (`packages/svelte`, v5.57.1) containing both a compiler that turns `.svelte` components into plain JavaScript modules and a signals-based client/server runtime those modules import at runtime. The compiler runs a strict three-phase pipeline (parse → analyze → transform) with separate client and server code generators, while the runtime implements Svelte 5 runes ($state/$derived/$effect) on top of a push-pull reactive graph with bitflag-tagged signals, batched flushing, and an experimental async/fork mode. It is aimed at framework consumers (SvelteKit, vite-plugin-svelte, svelte-check, the REPL) rather than app authors directly, and is distinctive for shipping unbundled ESM source as the published artifact, generating its error/warning catalogue and its `.d.ts` types from source, and carrying ~3,400 fixture directories as its primary test surface.

System map

The repo is a pnpm workspace (`pnpm-workspace.yaml` globs `packages/*` and `playgrounds/*`) with exactly one real package, `packages/svelte`, plus a Vite sandbox playground and a Node benchmarking harness at the root. The package has two runtime boundaries encoded in its `exports` map — `browser`/`worker` conditions split every entry into client and server implementations — and a third, the compiler, which is deliberately firewalled from runtime code by a custom ESLint rule. Storage is entirely file-based: there is no database; the only persistent artefacts are compiled test fixtures under `tests/*/samples/*/_output/`, generated docs under `documentation/docs/98-reference/.generated/`, and the checked-in `types/index.d.ts`. External integrations are all build-time libraries (acorn, zimmerframe, esrap, magic-string, devalue) rather than services. Deployment is npm publish via Changesets on push to `main`.

All 15 system map claims →

Feature catalog

There are no routes or screens — the user-facing surface is a set of npm subpath exports and a compiler API. Broadly: the compiler API (`compile`, `compileModule`, `parse`, `parseCss`, `preprocess`, `print`, `migrate`), the component runtime lifecycle API (`mount`, `hydrate`, `unmount`, `flushSync`, `fork`, `tick`, `untrack`, `settled`), context and lifecycle helpers, and a set of reactive standard-library classes. Around those sit optional subpackages for transitions, animations, easing, motion springs, stores, attachments, and events. Compiler behaviour is configurable through a validated options table, and two experimental features — async mode and `hydratable` — gate themselves on a runtime flag.

All 15 feature catalog claims →

Data flow

There are two distinct data pipelines. The compile-time pipeline moves a `.svelte` string through a hand-written state-machine parser into a Svelte AST, through a zimmerframe scope/analysis walk that attaches `metadata` and binding information, and out through target-specific ESTree builders into code + sourcemap + CSS. The runtime pipeline moves user mutations into `Source` signals, propagates dirtiness lazily through deriveds, collects affected effects into a `Batch`, and flushes them to write DOM. The two never share code — an ESLint rule enforces that runtime files cannot import from `../compiler/` or `#compiler`. State ownership is module-global on both sides: the compiler owns `compiler/state.js`, the runtime owns `active_reaction`/`active_effect`/`current_batch`.

All 15 data flow claims →

Behavior traces

Three flows dominate. (1) Compile: `compile()` resets global state, validates options, parses, strips TS, analyzes, transforms, and re-attaches a public AST. (2) Client startup: `mount()` initialises DOM operation caches, opens a root effect and an error boundary, pushes a component context, invokes the compiled component function, and returns its exports. (3) Update: a `$state` write sets a source, which schedules its reactions into a `Batch`, which is flushed on the microtask or synchronously via `flushSync`. A fourth, the SSR→hydrate round trip, is what the test harness itself exercises on every fixture.

All 14 behavior traces claims →

Testing signals

Testing is Vitest-driven with a fixture-directory convention: 22 suites under `packages/svelte/tests/`, each a `test.ts` plus a `samples/` directory where every subdirectory is one test, optionally configured by a `_config.js`. Coverage is enormous by fixture count — 1,209 legacy runtime samples, 1,054 runes runtime samples, 335 validator samples, 184 CSS samples — and the runtime suites multiply each by four variants (dom, hydrate, ssr, async-ssr). Real-browser coverage is narrow: only `runtime-browser` (35 samples) and the custom-elements samples run under Playwright Chromium. CI runs the full suite on Node 20/22/24 across Windows, macOS, and Ubuntu, plus a no-async pass, a tsgo typecheck, a lint/types-drift gate, and a benchmark job.

All 15 testing signals claims →

Risk map

The highest-severity surfaces are the two `innerHTML` sinks (`{@html}` and the template reconciler) and the server-side CSP/hash path, all of which are correct-by-design but unforgiving of misuse. Structurally, the biggest fragility is module-global mutable state on both sides of the codebase — `compiler/state.js` makes `compile()` non-reentrant, and `active_reaction`/`active_effect`/`current_batch`/`old_values` make the runtime a single-threaded global machine where any missed `finally` leaks state across components. Blast radius is concentrated in `runtime.js`, `reactivity/batch.js`, and `phases/2-analyze/index.js`, each of which sits under thousands of fixtures. Legacy code is not dead but is a permanent second code path: legacy mode, legacy AST conversion, and `beforeUpdate`/`afterUpdate` all have their own branches.

All 16 risk map claims →

Extension points

Almost every extension point is a plain object literal keyed by node type or property name, which makes adding language features mechanical: drop a file into the right `visitors/` directory and register it in the table. The three big ones are the analysis visitor table, the client and server transform visitor tables, and the `binding_properties` registry that defines what `bind:` can target. Below those sit the compiler options validator table, the markdown-driven message catalogue, the preprocessor hook interface, and the export map itself. On the runtime side, `createSubscriber` and `createAttachmentKey` are the sanctioned APIs for library authors who need to plug into reactivity and element lifecycle without touching internals.

All 14 extension points claims →

Contributor handoff

Read `AGENTS.md`, `CONTRIBUTING.md`, and `.github/PULL_REQUEST_TEMPLATE.md` first — the repo's own agent guide makes the PR template mandatory and forbids submitting without a full test run. The dominant convention is `snake_case` internally, `camelCase` publicly; the dominant workflow is add a fixture directory, not a new test file. The two hard edit boundaries are generated files (types, error/warning modules, generated docs) and the compiler/runtime import firewall. Expect long feedback loops: the full suite covers ~3,400 fixtures across 4 variants, so filter aggressively while iterating and only run the full suite before opening a PR.

All 16 contributor handoff claims →

Languages

LanguageFilesShare of source
Svelte454756%
JavaScript343843%
JSON461docs/config
HTML254docs/config
CSS189docs/config
Markdown136docs/config
TypeScript861%
YAML10docs/config

Start reading here

Probable source entrypoint: packages/ — inferred from the directory tree and manifest, not the upstream docs.

Source roots

packages/ (3813 files)

Source layout — packages/

PathFiles
packages/svelte/134

Repository structure

Top-level pathFiles
packages/3813
documentation/106
benchmarking/33
playgrounds/16
.github/10
.changeset/2
.well-known/1
.agents/1

Docs found: AGENTS.mdCONTRIBUTING.mdLICENSE.mdREADME.mddocumentation/docs/01-introduction/01-overview.mddocumentation/docs/01-introduction/02-getting-started.mddocumentation/docs/01-introduction/03-svelte-files.mddocumentation/docs/01-introduction/04-svelte-js-files.mddocumentation/docs/01-introduction/index.mddocumentation/docs/02-runes/01-what-are-runes.md

Package

package.json — svelte-monorepo v0.0.1, 19 declared dependencies.

@changesets/changelog-github@changesets/cli@eslint/js@sveltejs/eslint-config@types/node@types/picomatch@vitest/coverage-v8eslinteslint-plugin-lubeeslint-plugin-sveltejsdomplaywright

CI & config entrypoints

Structural health signals

Average score 9/10 across 30 analyzed source files; 1 hotspot surfaced.

These are deterministic review leads — size, churn, and structural signals — not proof of a bug in this project.

Recent history