CodeVetter · Repo Unpack · Extension points
sveltejs/svelte
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.
- 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.
- 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.
- `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.
- 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`.
- 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.
- 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.
- 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 }`.
- 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.
- `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.
- `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.
- 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.
- 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.
- Agent-facing workflows are themselves extensible via `.agents/skills/`, which currently holds one skill (`performance-investigation`) that `AGENTS.md` routes to by name.