# Extension points — sveltejs/svelte

> Canonical page: https://codevetter.com/unpack/svelte/extension-points

# Extension points — sveltejs/svelte

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

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.
- Adding a new analysable node type means creating `phases/2-analyze/visitors/<NodeType>.js` and adding it to the `visitors` object in `2-analyze/index.js` — the file currently imports ~60 such visitors explicitly by name. — [packages/svelte/src/compiler/phases/2-analyze/index.js#L27-88](https://github.com/sveltejs/svelte/blob/636eaaaa6f064b55072e7d192bb76dc9d8c4516e/packages/svelte/src/compiler/phases/2-analyze/index.js#L27-L88)
- Client codegen has a parallel registry: `const visitors = {...}` at `3-transform/client/transform-client.js:65`, backed by ~45 files in `3-transform/client/visitors/` plus a `shared/` directory for logic common to both targets. — [packages/svelte/src/compiler/phases/3-transform/client/transform-client.js#L65-135](https://github.com/sveltejs/svelte/blob/636eaaaa6f064b55072e7d192bb76dc9d8c4516e/packages/svelte/src/compiler/phases/3-transform/client/transform-client.js#L65-L135) [packages/svelte/src/compiler/phases/3-transform/client/visitors](https://github.com/sveltejs/svelte/blob/636eaaaa6f064b55072e7d192bb76dc9d8c4516e/packages/svelte/src/compiler/phases/3-transform/client/visitors)
- The server codegen mirrors it in `3-transform/server/transform-server.js` exporting `server_component` and `server_module`, so a new template feature generally requires a matching visitor in both client and server visitor directories. — [packages/svelte/src/compiler/phases/3-transform/server/transform-server.js](https://github.com/sveltejs/svelte/blob/636eaaaa6f064b55072e7d192bb76dc9d8c4516e/packages/svelte/src/compiler/phases/3-transform/server/transform-server.js) [packages/svelte/src/compiler/phases/3-transform/index.js#L30-36](https://github.com/sveltejs/svelte/blob/636eaaaa6f064b55072e7d192bb76dc9d8c4516e/packages/svelte/src/compiler/phases/3-transform/index.js#L30-L36)
- `phases/bindings.js` exports `binding_properties`, a ~47-entry `Record<string, BindingProperty>` where each entry declares `event`, `bidirectional`, `omit_in_ssr`, `valid_elements`, and `invalid_elements` — this is the single table that defines which `bind:` directives exist. — [packages/svelte/src/compiler/phases/bindings.js#L1-60](https://github.com/sveltejs/svelte/blob/636eaaaa6f064b55072e7d192bb76dc9d8c4516e/packages/svelte/src/compiler/phases/bindings.js#L1-L60) [packages/svelte/src/compiler/phases/bindings.js#L200-215](https://github.com/sveltejs/svelte/blob/636eaaaa6f064b55072e7d192bb76dc9d8c4516e/packages/svelte/src/compiler/phases/bindings.js#L200-L215)
- New compiler options are registered declaratively in `validate-options.js` using the `string()`, `boolean()`, `list()`, `fun()`, and `warning()` combinators, split between `common_options` and `component_options`. — [packages/svelte/src/compiler/validate-options.js#L11-130](https://github.com/sveltejs/svelte/blob/636eaaaa6f064b55072e7d192bb76dc9d8c4516e/packages/svelte/src/compiler/validate-options.js#L11-L130) [packages/svelte/src/compiler/validate-options.js#L260-345](https://github.com/sveltejs/svelte/blob/636eaaaa6f064b55072e7d192bb76dc9d8c4516e/packages/svelte/src/compiler/validate-options.js#L260-L345)
- New errors/warnings are added as markdown `## CODE` sections under `packages/svelte/messages/<category>/*.md` across eight categories (client/server/shared/compile × errors/warnings); `scripts/process-messages` generates both the runtime throwers and the reference docs from them. — [packages/svelte/messages/compile-errors/template.md](https://github.com/sveltejs/svelte/blob/636eaaaa6f064b55072e7d192bb76dc9d8c4516e/packages/svelte/messages/compile-errors/template.md) [packages/svelte/scripts/process-messages/index.js#L14-60](https://github.com/sveltejs/svelte/blob/636eaaaa6f064b55072e7d192bb76dc9d8c4516e/packages/svelte/scripts/process-messages/index.js#L14-L60)
- The generated message modules are explicitly excluded from linting (`src/compiler/errors.js`, `src/internal/client/errors.js`, `src/internal/client/warnings.js`, `src/internal/shared/warnings.js`, `src/internal/server/warnings.js`), which is the signal that they must never be hand-edited. — [eslint.config.js#L88-100](https://github.com/sveltejs/svelte/blob/636eaaaa6f064b55072e7d192bb76dc9d8c4516e/eslint.config.js#L88-L100)
- The public plugin interface for build tooling is `PreprocessorGroup` — an object with optional `markup`, `script`, and `style` async hooks, each receiving `{ content, attributes, markup, filename }` and returning `{ code, map }`. — [packages/svelte/src/compiler/preprocess/index.js#L260-310](https://github.com/sveltejs/svelte/blob/636eaaaa6f064b55072e7d192bb76dc9d8c4516e/packages/svelte/src/compiler/preprocess/index.js#L260-L310) [packages/svelte/src/compiler/preprocess/index.js#L331-368](https://github.com/sveltejs/svelte/blob/636eaaaa6f064b55072e7d192bb76dc9d8c4516e/packages/svelte/src/compiler/preprocess/index.js#L331-L368)
- New public subpaths are added by editing the `exports` map in `packages/svelte/package.json`; `scripts/check-treeshakeability.js` then reads that same map to resolve each entry and asserts via a rollup bundle that importing it produces no side effects. — [packages/svelte/package.json](https://github.com/sveltejs/svelte/blob/636eaaaa6f064b55072e7d192bb76dc9d8c4516e/packages/svelte/package.json) [packages/svelte/scripts/check-treeshakeability.js#L1-50](https://github.com/sveltejs/svelte/blob/636eaaaa6f064b55072e7d192bb76dc9d8c4516e/packages/svelte/scripts/check-treeshakeability.js#L1-L50)
- `createSubscriber` (in `src/reactivity/create-subscriber.js`, exported from `svelte/reactivity`) is the sanctioned hook for library authors wiring external event sources into Svelte's reactivity — it is how `MediaQuery` is built. — [packages/svelte/src/reactivity/index-client.js](https://github.com/sveltejs/svelte/blob/636eaaaa6f064b55072e7d192bb76dc9d8c4516e/packages/svelte/src/reactivity/index-client.js) [packages/svelte/src/reactivity/create-subscriber.js](https://github.com/sveltejs/svelte/blob/636eaaaa6f064b55072e7d192bb76dc9d8c4516e/packages/svelte/src/reactivity/create-subscriber.js) [packages/svelte/src/reactivity/media-query.js](https://github.com/sveltejs/svelte/blob/636eaaaa6f064b55072e7d192bb76dc9d8c4516e/packages/svelte/src/reactivity/media-query.js)
- `createAttachmentKey()` is the programmatic extension point for element lifecycle: it returns a `Symbol(ATTACHMENT_KEY)` that the runtime recognises when spread onto an element, letting library authors attach behaviour without a `use:` directive. — [packages/svelte/src/attachments/index.js#L8-32](https://github.com/sveltejs/svelte/blob/636eaaaa6f064b55072e7d192bb76dc9d8c4516e/packages/svelte/src/attachments/index.js#L8-L32)
- New block types plug into `internal/client/dom/blocks/` — the directory currently holds `async`, `await`, `boundary`, `branches`, `css-props`, `each`, `html`, `if`, `key`, `slot`, `snippet`, `svelte-component`, `svelte-element`, and `svelte-head`, each a function invoked by generated code. — [packages/svelte/src/internal/client/dom/blocks/if.js](https://github.com/sveltejs/svelte/blob/636eaaaa6f064b55072e7d192bb76dc9d8c4516e/packages/svelte/src/internal/client/dom/blocks/if.js) [packages/svelte/src/internal/client/dom/blocks/each.js](https://github.com/sveltejs/svelte/blob/636eaaaa6f064b55072e7d192bb76dc9d8c4516e/packages/svelte/src/internal/client/dom/blocks/each.js) [packages/svelte/src/internal/client/dom/blocks/boundary.js](https://github.com/sveltejs/svelte/blob/636eaaaa6f064b55072e7d192bb76dc9d8c4516e/packages/svelte/src/internal/client/dom/blocks/boundary.js)
- New effect kinds are created through the factory family in `reactivity/effects.js` — `user_effect`, `user_pre_effect`, `eager_effect`, `effect_root`, `component_root`, `render_effect`, `template_effect`, `block`, `managed`, `branch`, `async_effect` — all of which funnel into a shared internal `create_effect` with different flag combinations. — [packages/svelte/src/internal/client/reactivity/effects.js#L187-445](https://github.com/sveltejs/svelte/blob/636eaaaa6f064b55072e7d192bb76dc9d8c4516e/packages/svelte/src/internal/client/reactivity/effects.js#L187-L445)
- Agent-facing workflows are themselves extensible via `.agents/skills/`, which currently holds one skill (`performance-investigation`) that `AGENTS.md` routes to by name. — [.agents/skills/performance-investigation/SKILL.md](https://github.com/sveltejs/svelte/blob/636eaaaa6f064b55072e7d192bb76dc9d8c4516e/.agents/skills/performance-investigation/SKILL.md) [AGENTS.md](https://github.com/sveltejs/svelte/blob/636eaaaa6f064b55072e7d192bb76dc9d8c4516e/AGENTS.md)

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)
