sveltejs/svelte
Attachments and actions
Active contributors: Rich Harris, Simon H, Dominic Gannaway
Purpose
Attachments ({@attach foo}) and actions (use:foo) both let user code run a function with a DOM element after it's mounted, and an optional teardown when it unmounts. Attachments are the modern, reactive-aware variant introduced in Svelte 5; actions are the original Svelte 3 API and remain fully supported.
User docs:
Attachments
The public entry is packages/svelte/src/attachments/index.js:
export function createAttachmentKey() { return Symbol(ATTACHMENT_KEY); }
export function fromAction(action, fn?) { /* turn an action into an attachment */ }createAttachmentKey() returns a Symbol that, when used as an object key alongside other props (e.g., spread onto an element), tags the value as an attachment. The Symbol-based design lets attachments coexist with regular props without collision.
fromAction() adapts a legacy action into an attachment so library authors can transition incrementally.
Runtime
packages/svelte/src/internal/client/dom/elements/attachments.js is the runtime piece that:
- Detects attachment keys at element creation time.
- Wraps the attachment function in a
render_effectso reactive reads inside it are tracked. - Calls the attachment with the node; if it returns a function, that becomes the teardown.
The {@attach foo} directive compiles to a call into attach(...) from internal/client/index.js (re-exporting from this module).
Actions (legacy)
use:foo={params} directives are emitted as calls into action(...) from packages/svelte/src/internal/client/dom/elements/actions.js. The action function receives (node, params), and the returned object's update(params) is called whenever params change reactively. The action lifecycle is wrapped in a render_effect similarly to attachments.
The Action/ActionReturn types are exported from packages/svelte/src/action/ (a type-only module).
Comparison
| Aspect | Action (legacy) | Attachment (modern) |
|---|---|---|
| Directive syntax | use:foo={...} |
{@attach foo} or {[createAttachmentKey()]: fn} |
| Reactivity inside the function | Manual via update |
Automatic — runs in a render_effect |
| Teardown | return { destroy() } |
Return a teardown function |
Plays well with $state? |
Awkward (need update to receive new params) |
Yes (read $state inside the attachment, it re-runs) |
| TypeScript types | Action<Element, Params> from svelte/action |
Attachment<Element> from svelte/attachments |
Compiler emit
- Attachments use
packages/svelte/src/compiler/phases/3-transform/client/visitors/AttachTag.js. - Actions use
packages/svelte/src/compiler/phases/3-transform/client/visitors/UseDirective.js.
Both emit code into the surrounding template effect so they teardown when the parent block unmounts.
Tests
packages/svelte/tests/runtime-runes/includes attachment tests.packages/svelte/tests/runtime-legacy/covers actions.
Key source files
| File | Purpose |
|---|---|
packages/svelte/src/attachments/index.js |
createAttachmentKey, fromAction. |
packages/svelte/src/internal/client/dom/elements/attachments.js |
Runtime attach() helper. |
packages/svelte/src/internal/client/dom/elements/actions.js |
Runtime action() helper for use:. |
packages/svelte/src/action/public.d.ts (loaded via svelte/action) |
Action/ActionReturn types. |
packages/svelte/src/compiler/phases/3-transform/client/visitors/AttachTag.js |
Attachment compiler emit. |
packages/svelte/src/compiler/phases/3-transform/client/visitors/UseDirective.js |
Action compiler emit. |
Entry points for modification
The two runtimes are simple and small — most evolution will go into internal/client/dom/elements/attachments.js. New attachment-style primitives should follow attach()'s pattern: take a node, run the user function inside render_effect, register teardown.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.