# Data flow — sveltejs/svelte

> Canonical page: https://codevetter.com/unpack/svelte/data-flow

# Data flow — sveltejs/svelte

Scanned commit 636eaaaa6f064b55072e7d192bb76dc9d8c4516e (2026-09-18). Generated by codevetter codevetter 1.12.0 on 2026-09-22.

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`.
- Input boundary for compilation is `remove_bom(source)` followed by `state.reset({ warning, filename })`, which clears `warnings`, `source`, `dev`, `runes`, and installs the user's `warningFilter` — every compile starts from a wiped module-global. — [packages/svelte/src/compiler/index.js#L23-30](https://github.com/sveltejs/svelte/blob/636eaaaa6f064b55072e7d192bb76dc9d8c4516e/packages/svelte/src/compiler/index.js#L23-L30) [packages/svelte/src/compiler/state.js#L130-150](https://github.com/sveltejs/svelte/blob/636eaaaa6f064b55072e7d192bb76dc9d8c4516e/packages/svelte/src/compiler/state.js#L130-L150)
- Options arrive from two merged sources: the caller's `CompileOptions` (validated) and `<svelte:options>` attributes parsed out of the source into `parsed.options`, with the in-file values overriding the caller's for `css` and `runes`. — [packages/svelte/src/compiler/index.js#L27-42](https://github.com/sveltejs/svelte/blob/636eaaaa6f064b55072e7d192bb76dc9d8c4516e/packages/svelte/src/compiler/index.js#L27-L42) [packages/svelte/src/compiler/phases/1-parse/read/options.js](https://github.com/sveltejs/svelte/blob/636eaaaa6f064b55072e7d192bb76dc9d8c4516e/packages/svelte/src/compiler/phases/1-parse/read/options.js)
- TypeScript is detected before parsing via a `lang=` regex over `<script>` tags in the `Parser` constructor (setting `this.ts`), and TS nodes are then stripped from `fragment`/`instance`/`module` by `remove_typescript_nodes` before analysis ever sees them. — [packages/svelte/src/compiler/phases/1-parse/index.js#L13-90](https://github.com/sveltejs/svelte/blob/636eaaaa6f064b55072e7d192bb76dc9d8c4516e/packages/svelte/src/compiler/phases/1-parse/index.js#L13-L90) [packages/svelte/src/compiler/index.js#L42-55](https://github.com/sveltejs/svelte/blob/636eaaaa6f064b55072e7d192bb76dc9d8c4516e/packages/svelte/src/compiler/index.js#L42-L55)
- The parser is a mutable state machine: `Parser` holds `index`, `stack`, `fragments`, and loops `state = state(this) || fragment` over `template.length`, with states in `1-parse/state/{fragment,element,tag,text}.js`. — [packages/svelte/src/compiler/phases/1-parse/index.js#L100-120](https://github.com/sveltejs/svelte/blob/636eaaaa6f064b55072e7d192bb76dc9d8c4516e/packages/svelte/src/compiler/phases/1-parse/index.js#L100-L120)
- Analysis is a zimmerframe walk over a per-node-type visitor table; the fallthrough `_` visitor reconstructs `svelte-ignore` scope by scanning preceding `Comment` siblings and `leadingComments`, pushing onto `ignore_stack` in `compiler/state.js`. — [packages/svelte/src/compiler/phases/2-analyze/index.js#L88-125](https://github.com/sveltejs/svelte/blob/636eaaaa6f064b55072e7d192bb76dc9d8c4516e/packages/svelte/src/compiler/phases/2-analyze/index.js#L88-L125) [packages/svelte/src/compiler/state.js#L88-125](https://github.com/sveltejs/svelte/blob/636eaaaa6f064b55072e7d192bb76dc9d8c4516e/packages/svelte/src/compiler/state.js#L88-L125)
- Scope and binding resolution is separated into `phases/scope.js` (`create_scopes`, `Scope`, `ScopeRoot`, `get_rune`, `set_scope`), and cyclic reactive statements are caught by `utils/check_graph_for_cycles.js`. — [packages/svelte/src/compiler/phases/2-analyze/index.js#L17-22](https://github.com/sveltejs/svelte/blob/636eaaaa6f064b55072e7d192bb76dc9d8c4516e/packages/svelte/src/compiler/phases/2-analyze/index.js#L17-L22) [packages/svelte/src/compiler/phases/scope.js](https://github.com/sveltejs/svelte/blob/636eaaaa6f064b55072e7d192bb76dc9d8c4516e/packages/svelte/src/compiler/phases/scope.js)
- CSS flows through its own sub-pipeline inside analysis — `analyze_css`, then `prune` (matching selectors against the template), then `warn_unused` — before `render_stylesheet` emits the final stylesheet in the transform phase. — [packages/svelte/src/compiler/phases/2-analyze/index.js#L22-26](https://github.com/sveltejs/svelte/blob/636eaaaa6f064b55072e7d192bb76dc9d8c4516e/packages/svelte/src/compiler/phases/2-analyze/index.js#L22-L26) [packages/svelte/src/compiler/phases/2-analyze/css/css-prune.js](https://github.com/sveltejs/svelte/blob/636eaaaa6f064b55072e7d192bb76dc9d8c4516e/packages/svelte/src/compiler/phases/2-analyze/css/css-prune.js) [packages/svelte/src/compiler/phases/3-transform/index.js#L46-50](https://github.com/sveltejs/svelte/blob/636eaaaa6f064b55072e7d192bb76dc9d8c4516e/packages/svelte/src/compiler/phases/3-transform/index.js#L46-L50)
- The output boundary merges sourcemaps twice: `esrap`'s `print` emits a map with `sourceMapContent: source`, then `merge_with_preprocessor_map(js, options, js_source_name)` folds in any preprocessor map supplied via `options.sourcemap`. — [packages/svelte/src/compiler/phases/3-transform/index.js#L36-50](https://github.com/sveltejs/svelte/blob/636eaaaa6f064b55072e7d192bb76dc9d8c4516e/packages/svelte/src/compiler/phases/3-transform/index.js#L36-L50) [packages/svelte/src/compiler/utils/mapped_code.js](https://github.com/sveltejs/svelte/blob/636eaaaa6f064b55072e7d192bb76dc9d8c4516e/packages/svelte/src/compiler/utils/mapped_code.js)
- On the runtime side, `$state` values pass through `proxy()` in `internal/client/proxy.js`, which refuses non-objects, anything already carrying `STATE_SYMBOL`, anything with `COMPONENT_SYMBOL`, and any object whose prototype is neither `Object.prototype` nor `Array.prototype`. — [packages/svelte/src/internal/client/proxy.js#L34-55](https://github.com/sveltejs/svelte/blob/636eaaaa6f064b55072e7d192bb76dc9d8c4516e/packages/svelte/src/internal/client/proxy.js#L34-L55)
- Dependency tracking is a read-side side effect of `get(signal)`: when `active_reaction` is set and not `untracking`, the signal is appended to `new_deps` (or counted as `skipped_deps` when the read order matches the previous run, avoiding array allocation). — [packages/svelte/src/internal/client/runtime.js#L548-600](https://github.com/sveltejs/svelte/blob/636eaaaa6f064b55072e7d192bb76dc9d8c4516e/packages/svelte/src/internal/client/runtime.js#L548-L600)
- Writes go through `internal_set` in `reactivity/sources.js`, which bumps the global `write_version` (via `increment_write_version` in runtime.js) and schedules dependents; `old_values` is a module-level `Map` used to restore pre-batch values. — [packages/svelte/src/internal/client/reactivity/sources.js#L50-60](https://github.com/sveltejs/svelte/blob/636eaaaa6f064b55072e7d192bb76dc9d8c4516e/packages/svelte/src/internal/client/reactivity/sources.js#L50-L60) [packages/svelte/src/internal/client/reactivity/sources.js#L189-280](https://github.com/sveltejs/svelte/blob/636eaaaa6f064b55072e7d192bb76dc9d8c4516e/packages/svelte/src/internal/client/reactivity/sources.js#L189-L280) [packages/svelte/src/internal/client/runtime.js#L137-150](https://github.com/sveltejs/svelte/blob/636eaaaa6f064b55072e7d192bb76dc9d8c4516e/packages/svelte/src/internal/client/runtime.js#L137-L150)
- Effects are not run on write — they are collected into the singleton `current_batch` (`Batch.ensure()`), which owns `schedule`, `capture`, `apply`, `flush`, `discard`, and `settled`, and clears `collected_effects`/`legacy_updates`/`old_values` in its `finally` block. — [packages/svelte/src/internal/client/reactivity/batch.js#L45-100](https://github.com/sveltejs/svelte/blob/636eaaaa6f064b55072e7d192bb76dc9d8c4516e/packages/svelte/src/internal/client/reactivity/batch.js#L45-L100) [packages/svelte/src/internal/client/reactivity/batch.js#L668-700](https://github.com/sveltejs/svelte/blob/636eaaaa6f064b55072e7d192bb76dc9d8c4516e/packages/svelte/src/internal/client/reactivity/batch.js#L668-L700)
- Server output is accumulated as an array of strings and nested `Renderer` children in `#out`, with `head()` creating a second Renderer tagged `type = 'head'` so head content can be emitted out of document order. — [packages/svelte/src/internal/server/renderer.js#L116-210](https://github.com/sveltejs/svelte/blob/636eaaaa6f064b55072e7d192bb76dc9d8c4516e/packages/svelte/src/internal/server/renderer.js#L116-L210) [packages/svelte/src/internal/server/index.js#L84-99](https://github.com/sveltejs/svelte/blob/636eaaaa6f064b55072e7d192bb76dc9d8c4516e/packages/svelte/src/internal/server/index.js#L84-L99)
- Escaping is centralised in the standalone `src/escaping.js`: `escape_html(value, is_attr)` uses `/[&"<]/g` for attributes and `/[&<]/g` for content, escaping only `&`, `"`, and `<`. — [packages/svelte/src/escaping.js](https://github.com/sveltejs/svelte/blob/636eaaaa6f064b55072e7d192bb76dc9d8c4516e/packages/svelte/src/escaping.js)
- Compile-time and runtime data are kept structurally disjoint by a bespoke ESLint rule `no_compiler_imports`, which string-searches every file under `src/` (excluding `src/compiler/`) for `../compiler/` or `#compiler` and reports a hard error. — [eslint.config.js#L4-40](https://github.com/sveltejs/svelte/blob/636eaaaa6f064b55072e7d192bb76dc9d8c4516e/eslint.config.js#L4-L40) [eslint.config.js#L78-86](https://github.com/sveltejs/svelte/blob/636eaaaa6f064b55072e7d192bb76dc9d8c4516e/eslint.config.js#L78-L86)

Every claim links to its cited files at the pinned commit. Citations identify source evidence; they do not establish runtime correctness. Independent CodeVetter scan — not reviewed by upstream maintainers.

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
