Actions
An action is a function that runs on an element
Section titled “An action is a function that runs on an element”Sometimes you need imperative access to a DOM node — to initialize a charting library, trap focus, set up a tooltip, or detect clicks outside. An action packages that logic as a reusable function attached with the use: directive.
An action is a function that receives the DOM node (and optional parameters) when the element mounts, and may return an object with update and destroy methods:
<script> // An action: (node, params?) => { update?, destroy? } function tooltip(node, text) { const el = document.createElement('div'); el.className = 'tooltip'; el.textContent = text;
function show() { document.body.appendChild(el); } function hide() { el.remove(); } node.addEventListener('mouseenter', show); node.addEventListener('mouseleave', hide);
return { update(newText) { el.textContent = newText; }, // params changed destroy() { // element unmounting node.removeEventListener('mouseenter', show); node.removeEventListener('mouseleave', hide); el.remove(); }, }; }</script>
<button use:tooltip={'Save your work'}>Save</button>flowchart LR mount["element mounts"] --> run["action(node, params) runs"] run --> update["params change → update(newParams)"] update --> update update --> destroy["element unmounts → destroy()"]
A practical example: click-outside
Section titled “A practical example: click-outside”Actions shine for cross-cutting DOM behavior. A clickOutside action dispatches when a click lands outside the node — perfect for closing dropdowns and modals:
<script> function clickOutside(node, callback) { function handle(e) { if (!node.contains(e.target)) callback(); } document.addEventListener('click', handle, true); return { destroy() { document.removeEventListener('click', handle, true); }, }; }
let open = $state(false);</script>
{#if open} <div class="menu" use:clickOutside={() => (open = false)}>…</div>{/if}Why actions instead of an effect
Section titled “Why actions instead of an effect”You could do some of this with bind:this plus a $effect. Actions are better when the behavior is reusable across elements and self-contained (setup + teardown in one place): the destroy method guarantees cleanup, and passing parameters with use:action={params} keeps it declarative at the call site. Reach for an action when you want to say “this element behaves like X” and reuse X everywhere.