## apps/svelte.dev/content/docs/svelte/01-introduction/01-overview.md # Svelte 5 Reference ## Overview Svelte is a compiler-based framework for building web UIs. It turns declarative components into optimized JavaScript. ```svelte ``` Components contain HTML, CSS, and JavaScript. Use with SvelteKit for full-stack apps. ## apps/svelte.dev/content/docs/svelte/01-introduction/02-getting-started.md # Getting started ## Quick Start Use [SvelteKit](../kit) (recommended): ```bash npx sv create myapp cd myapp npm install npm run dev ``` ## Alternatives **Vite standalone:** ```bash npm create vite@latest # Select svelte option ``` Generates HTML, JS, CSS in `dist/` directory. You'll need a routing library. **Other build tools:** Rollup, Webpack plugins available, but Vite recommended. ## Tooling - **VS Code:** Official Svelte extension - **CLI checking:** `sv check` - **Help:** Discord chat, Stack Overflow ## apps/svelte.dev/content/docs/svelte/01-introduction/03-svelte-files.md # .svelte files Components are written in `.svelte` files using a superset of HTML. All sections are optional. ```svelte /// file: MyComponent.svelte ``` ## ` ``` Can `export` bindings (becomes module exports). Cannot `export default` - component is default export. ## ` ``` ## apps/svelte.dev/content/docs/svelte/01-introduction/04-svelte-js-files.md # .svelte.js and .svelte.ts files `.svelte.js` and `.svelte.ts` files behave like regular JS/TS modules but can use runes. Useful for reusable reactive logic and sharing reactive state across your app. > Note: You cannot export reassigned state. > New in Svelte 5 ## apps/svelte.dev/content/docs/svelte/02-runes/01-what-are-runes.md # Runes Runes are symbols with `$` prefix that control the Svelte compiler. They're keywords, not functions. ```js let message = $state('hello'); ``` Key properties: - No import needed - they're globals - Not values - can't assign to variables or pass as arguments - Only valid in specific positions (compiler enforces this) ## apps/svelte.dev/content/docs/svelte/02-runes/02-$state.md # $state Creates reactive state that triggers UI updates when changed. ```svelte ``` State is just a regular variable - no special API needed for updates. ## Deep state Arrays and simple objects become deeply reactive proxies: ```js let todos = $state([ { done: false, text: 'add more todos' } ]); ``` Individual property updates trigger granular UI updates: ```js todos[0].done = !todos[0].done; ``` New objects pushed to arrays are automatically proxified: ```js todos.push({ done: false, text: 'eat lunch' }); ``` **Gotcha:** Destructuring breaks reactivity: ```js let { done, text } = todos[0]; // `done` won't update when todos[0].done changes todos[0].done = !todos[0].done; ``` ## Classes Use `$state` in class fields or first assignment in constructor: ```js class Todo { done = $state(false); constructor(text) { this.text = $state(text); } reset() { this.text = ''; this.done = false; } } ``` **Gotcha:** Method binding loses `this` context: ```svelte ``` Or use arrow functions in class: ```js class Todo { done = $state(false); reset = () => { this.text = ''; this.done = false; } } ``` ## $state.raw Non-reactive state - can only be reassigned, not mutated: ```js let person = $state.raw({ name: 'Heraclitus', age: 49 }); // No effect person.age += 1; // Works - creates new object person = { name: 'Heraclitus', age: 50 }; ``` Better performance for large objects you won't mutate. ## $state.snapshot Takes static snapshot of reactive proxy: ```svelte ``` Useful for external APIs that don't expect proxies. ## Passing state across modules Can't directly export reassignable state: ```js // โŒ Won't work export let count = $state(0); ``` **Solutions:** Export object with state property: ```js export const counter = $state({ count: 0 }); ``` Or use getter functions: ```js let count = $state(0); export function getCount() { return count; } export function increment() { count += 1; } ``` ## apps/svelte.dev/content/docs/svelte/02-runes/03-$derived.md # $derived Derived state is declared with the `$derived` rune: ```svelte

{count} doubled is {doubled}

``` The expression inside `$derived(...)` should be free of side-effects. Svelte will disallow state changes (e.g. `count++`) inside derived expressions. > **Note:** Code in Svelte components is only executed once at creation. Without the `$derived` rune, `doubled` would maintain its original value even when `count` changes. ## `$derived.by` For complex derivations that don't fit in a short expression, use `$derived.by` with a function: ```svelte ``` `$derived(expression)` is equivalent to `$derived.by(() => expression)`. ## Dependencies Anything read synchronously inside the `$derived` expression is a dependency. When dependencies change, the derived is recalculated when next read. To exempt state from being a dependency, use `untrack`. ## Overriding derived values You can temporarily override derived values by reassigning them (unless declared with `const`): ```svelte ``` ## Deriveds and reactivity Unlike `$state`, `$derived` values are left as-is (not converted to deeply reactive proxies): ```svelte let items = $state([...]); let index = $state(0); let selected = $derived(items[index]); ``` You can change properties of `selected` and it will affect the underlying `items` array. ## Destructuring Destructuring with `$derived` makes all resulting variables reactive: ```js let { a, b, c } = $derived(stuff()); ``` This is equivalent to: ```js let _stuff = $derived(stuff()); let a = $derived(_stuff.a); let b = $derived(_stuff.b); let c = $derived(_stuff.c); ``` ## Update propagation Svelte uses push-pull reactivity - when state updates, dependents are notified immediately (push), but derived values aren't re-evaluated until read (pull). If a derived's new value is referentially identical to its previous value, downstream updates are skipped: ```svelte ``` The button only updates when `large` changes, not when `count` changes. ## apps/svelte.dev/content/docs/svelte/02-runes/04-$effect.md # $effect Effects run when state updates. Used for third-party libraries, canvas drawing, network requests. Only run in browser, not SSR. **Don't update state inside effects** - leads to infinite loops. Use alternatives below. ## Basic Usage ```svelte ``` ## Lifecycle & Teardown Effects run after mount in microtasks. Re-runs are batched. Can return teardown function: ```svelte

{count}

``` ## Dependencies Auto-tracks reactive values read **synchronously**. Async reads (after `await`, inside `setTimeout`) not tracked: ```ts $effect(() => { const context = canvas.getContext('2d'); context.clearRect(0, 0, canvas.width, canvas.height); // this will re-run whenever `color` changes... context.fillStyle = color; setTimeout(() => { // ...but not when `size` changes context.fillRect(0, 0, size, size); }, 0); }); ``` **Object vs property tracking:** ```svelte

{state.value} doubled is {derived.value}

``` **Conditional dependencies:** ```ts import confetti from 'canvas-confetti'; let condition = $state(true); let color = $state('#ff3e00'); $effect(() => { if (condition) { confetti({ colors: [color] }); } else { confetti(); } }); ``` ## $effect.pre Runs **before** DOM updates: ```svelte
{#each messages as message}

{message}

{/each}
``` ## $effect.tracking Returns if code runs inside tracking context: ```svelte

in template: {$effect.tracking()}

``` ## $effect.pending Returns number of pending promises in current boundary: ```svelte

{a} + {b} = {await add(a, b)}

{#if $effect.pending()}

pending promises: {$effect.pending()}

{/if} ``` ## $effect.root Creates non-tracked scope for manual control: ```js const destroy = $effect.root(() => { $effect(() => { // setup }); return () => { // cleanup }; }); // later... destroy(); ``` ## When NOT to use $effect **โŒ Don't synchronize state:** ```svelte ``` **โœ… Use $derived instead:** ```svelte ``` **โŒ Don't link values with effects:** ```svelte ``` **โœ… Use function bindings:** ```svelte ``` ## apps/svelte.dev/content/docs/svelte/02-runes/05-$props.md # $props Pass props to components like attributes: ```svelte ``` Receive props with `$props` rune: ```svelte

this component is {props.adjective}

``` More commonly, destructure props: ```svelte

this component is {adjective}

``` ## Fallback values ```js let { adjective = 'happy' } = $props(); ``` > Fallback values are not turned into reactive state proxies ## Renaming props ```js let { super: trouper = 'lights are gonna find me' } = $props(); ``` ## Rest props ```js let { a, b, c, ...others } = $props(); ``` ## Updating props Props update when parent changes. Child can temporarily override prop values: ```svelte ``` ```svelte ``` **Don't mutate props** unless they are `$bindable`. Mutating regular objects has no effect. Mutating reactive state proxies causes `ownership_invalid_mutation` warning. ## Type safety TypeScript: ```svelte ``` JSDoc: ```svelte ``` ## `$props.id()` Generates unique ID per component instance, consistent between server/client: ```svelte
``` ## apps/svelte.dev/content/docs/svelte/02-runes/06-$bindable.md # $bindable Props normally flow one-way from parent to child. `$bindable` allows two-way data flow and state mutation in the child component. ## Basic Usage Mark a prop as bindable with `$bindable()`: ```svelte /// file: FancyInput.svelte ``` Parent can bind to it using `bind:`: ```svelte /// file: App.svelte

{message}

``` ## Fallback Values Provide fallback when no prop is passed: ```js /// file: FancyInput.svelte let { value = $bindable('fallback'), ...props } = $props(); ``` **Note:** Parent can pass normal props without `bind:` - binding is optional. ## apps/svelte.dev/content/docs/svelte/02-runes/07-$inspect.md # $inspect > [!NOTE] `$inspect` only works during development. In a production build it becomes a noop. The `$inspect` rune is equivalent to `console.log` but re-runs when its arguments change. Tracks reactive state deeply. ```svelte ``` ## $inspect(...).with Use custom callback instead of `console.log`. First argument is `"init"` or `"update"`: ```svelte ``` Find origin of changes: ```js // @errors: 2304 $inspect(stuff).with(console.trace); ``` ## $inspect.trace(...) Traces function re-runs in effects/derived. Must be first statement in function body: ```svelte ``` Takes optional label as first argument. ## apps/svelte.dev/content/docs/svelte/02-runes/08-$host.md # $host The `$host` rune provides access to the host element when compiling a component as a custom element. Commonly used to dispatch custom events. ```svelte /// file: Stepper.svelte ``` ```svelte /// file: App.svelte count -= 1} onincrement={() => count += 1} >

count: {count}

``` ## apps/svelte.dev/content/docs/svelte/03-template-syntax/01-basic-markup.md # Basic markup Markup inside Svelte components is HTML++. ## Tags - Lowercase tags (`
`) = HTML elements - Capitalized/dot notation (``, ``) = components ```svelte
``` ## Element attributes Work like HTML. Values can contain or be JavaScript expressions: ```svelte
``` ```svelte ``` ```svelte page {p} ``` ```svelte ``` **Attribute rules:** - Boolean attributes: included if truthy, excluded if falsy - Other attributes: included unless nullish (`null`/`undefined`) ```svelte
This div has no title attribute
``` **Shorthand:** `name={name}` โ†’ `{name}` ```svelte ``` ## Component props Same rules as attributes. Use `{name}` shorthand when possible: ```svelte ``` ## Spread attributes Pass multiple attributes at once. Order matters: ```svelte ``` ## Events Use `on` prefix for DOM events: ```svelte ``` **Key points:** - Case sensitive: `onclick` โ‰  `onClick` - Support shorthand: ` ``` ```svelte ``` ### Optional Snippets Use optional chaining: ```svelte {@render children?.()} ``` Or `#if` with fallback: ```svelte {#if children} {@render children()} {:else} fallback content {/if} ``` ## TypeScript Use the `Snippet` interface: ```svelte ``` With generics: ```svelte ``` ## Exporting Snippets Export from ` {#snippet add(a, b)} {a} + {b} = {a + b} {/snippet} ``` ## Programmatic Snippets Use [`createRawSnippet`](svelte#createRawSnippet) API for advanced use cases. ## apps/svelte.dev/content/docs/svelte/03-template-syntax/07-@render.md # {@render ...} Render [snippets](snippet) using `{@render ...}` tags. ```svelte {#snippet sum(a, b)}

{a} + {b} = {a + b}

{/snippet} {@render sum(1, 2)} {@render sum(3, 4)} {@render sum(5, 6)} ``` Expression can be identifier or JavaScript expression: ```svelte {@render (cool ? coolSnippet : lameSnippet)()} ``` ## Optional snippets Use optional chaining for potentially undefined snippets: ```svelte {@render children?.()} ``` Or `{#if}` with fallback: ```svelte {#if children} {@render children()} {:else}

fallback content

{/if} ``` ## apps/svelte.dev/content/docs/svelte/03-template-syntax/08-@html.md # {@html ...} Inject raw HTML into components: ```svelte
{@html content}
``` **Security**: Always escape or control content to prevent XSS attacks. Never render unsanitized content. **Requirements**: - Expression must be valid standalone HTML - Cannot split HTML tags across multiple `{@html}` blocks - Does not compile Svelte code ## Styling `{@html}` content is invisible to Svelte scoped styles. Use `:global` modifier: ```svelte ``` ## apps/svelte.dev/content/docs/svelte/03-template-syntax/09-@attach.md # {@attach ...} Attachments are functions that run in an effect when an element mounts or when state updates. They can return a cleanup function. ```svelte
...
``` ## Attachment factories Functions can return attachments: ```svelte ``` Attachment recreates when `content` changes. ## Inline attachments ```svelte { const context = canvas.getContext('2d'); $effect(() => { context.fillStyle = color; context.fillRect(0, 0, canvas.width, canvas.height); }); }} > ``` ## Passing to components Attachments create Symbol props that spread to elements: ```svelte ``` ```svelte ``` ## Controlling re-runs Attachments are fully reactive. To avoid expensive re-runs, pass data in a function: ```js function foo(getBar) { return (node) => { veryExpensiveSetupWork(node); $effect(() => { update(node, getBar()); }); } } ``` ## Programmatic creation Use [`createAttachmentKey`](svelte-attachments#createAttachmentKey) to add attachments to spread objects. Convert actions to attachments with [`fromAction`](svelte-attachments#fromAction). ## apps/svelte.dev/content/docs/svelte/03-template-syntax/10-@const.md # {@const ...} The `{@const ...}` tag defines a local constant within blocks. ```svelte {#each boxes as box} {@const area = box.width * box.height} {box.width} * {box.height} = {area} {/each} ``` **Restriction**: Only allowed as immediate child of blocks (`{#if}`, `{#each}`, `{#snippet}`), components (``), or ``. ## apps/svelte.dev/content/docs/svelte/03-template-syntax/11-@debug.md # {@debug ...} The `{@debug ...}` tag logs variable values when they change and pauses execution if devtools are open. ```svelte {@debug user}

Hello {user.firstname}!

``` ## Usage Accepts comma-separated variable names (not arbitrary expressions): ```svelte {@debug user} {@debug user1, user2, user3} {@debug user.firstname} {@debug myArray[0]} {@debug !isReady} {@debug typeof user === 'object'} ``` Empty `{@debug}` triggers on any state change: ```svelte {@debug} ``` ## apps/svelte.dev/content/docs/svelte/03-template-syntax/12-bind.md # bind: Data flows down from parent to child. `bind:` allows data to flow from child to parent. Syntax: `bind:property={expression}` or `bind:property` (shorthand when names match). ```svelte ``` Svelte creates event listeners that update bound values. Most bindings are two-way, some are readonly. ## Function bindings Use `bind:property={get, set}` for validation/transformation: ```svelte value, (v) => value = v.toLowerCase()} /> ``` For readonly bindings, set `get` to `null`: ```svelte
...
``` ## Input bindings ### `bind:value` ```svelte

{message}

``` Numeric inputs coerce to numbers: ```svelte

{a} + {b} = {a + b}

``` Empty/invalid numeric inputs return `undefined`. Form reset with `defaultValue`: ```svelte
``` ### `bind:checked` ```svelte ``` Form reset with `defaultChecked`: ```svelte
``` ### `bind:indeterminate` ```svelte
{#if indeterminate} waiting... {:else if checked} checked {:else} unchecked {/if}
``` ### `bind:group` ```svelte ``` > Only works within same component. ### `bind:files` ```svelte ``` Use `DataTransfer` to create/modify `FileList` objects. ## Select bindings Single select: ```svelte ``` Multiple select: ```svelte ``` Default selection with `selected` attribute: ```svelte ``` ## Media bindings ### `
{/if} ``` ## Local vs Global Local (default): only play when their block is created/destroyed Global: play when any parent block changes ```svelte {#if x} {#if y}

fades in and out only when y changes

fades in and out when x or y change

{/if} {/if} ``` ## Parameters ```svelte {#if visible}
fades in and out over two seconds
{/if} ``` ## Custom Transitions ```js transition = (node: HTMLElement, params: any, options: { direction: 'in' | 'out' | 'both' }) => { delay?: number, duration?: number, easing?: (t: number) => number, css?: (t: number, u: number) => string, tick?: (t: number, u: number) => void } ``` `t`: 0-1 after easing (1 = natural state) `u`: 1-t Use `css` over `tick` when possible (runs off main thread). ```svelte {#if visible}
whooshes in
{/if} ``` Using `tick`: ```svelte {#if visible}

The quick brown fox jumps over the lazy dog

{/if} ``` ## Events Elements with transitions dispatch: - `introstart` - `introend` - `outrostart` - `outroend` ```svelte {#if visible}

(status = 'intro started')} onoutrostart={() => (status = 'outro started')} onintroend={() => (status = 'intro ended')} onoutroend={() => (status = 'outro ended')} > Flies in and out

{/if} ``` ## apps/svelte.dev/content/docs/svelte/03-template-syntax/15-in-and-out.md # in: and out: The `in:` and `out:` directives work like [`transition:`](transition) but are unidirectional. Unlike bidirectional transitions, `in` transitions don't reverse when interrupted - they continue playing alongside `out` transitions. ```svelte {#if visible}
flies in, fades out
{/if} ``` **Key difference**: If an out transition is aborted, transitions restart from scratch rather than reversing. ## apps/svelte.dev/content/docs/svelte/03-template-syntax/16-animate.md # animate: Animations trigger when keyed each block contents are re-ordered. Only runs when existing item index changes, not on add/remove. Must be on immediate child of keyed each block. ```svelte {#each list as item, index (item)}
  • {item}
  • {/each} ``` ## Animation Parameters ```svelte {#each list as item, index (item)}
  • {item}
  • {/each} ``` ## Custom Animation Functions ```js animation = (node: HTMLElement, { from: DOMRect, to: DOMRect } , params: any) => { delay?: number, duration?: number, easing?: (t: number) => number, css?: (t: number, u: number) => string, tick?: (t: number, u: number) => void } ``` Function receives `node`, `animation` object with `from`/`to` DOMRects, and `parameters`. `from` is start position, `to` is end position after reorder. If returns `css` method, Svelte creates web animation. `t` goes from 0-1 after easing, `u` equals `1-t`. ```svelte {#each list as item, index (item)}
    {item}
    {/each} ``` Can return `tick` function instead of `css`. Prefer `css` - runs off main thread, prevents jank. ```svelte {#each list as item, index (item)}
    {item}
    {/each} ``` ## apps/svelte.dev/content/docs/svelte/03-template-syntax/17-style.md # style: The `style:` directive provides shorthand for setting multiple styles on an element. ## Basic Usage ```svelte
    ...
    ...
    ``` ## Dynamic Values ```svelte
    ...
    ``` ## Shorthand Form ```svelte
    ...
    ``` ## Multiple Styles ```svelte
    ...
    ``` ## Important Modifier ```svelte
    ...
    ``` ## Precedence `style:` directives take precedence over `style` attributes, even over `!important`: ```svelte
    This will be red
    This will still be red
    ``` ## apps/svelte.dev/content/docs/svelte/03-template-syntax/18-class.md # class Two ways to set classes: `class` attribute and `class:` directive. ## Attributes ### Primitive values ```svelte
    ...
    ``` > Falsy values stringify (`class="false"`), except `undefined`/`null` which omit the attribute. ### Objects and arrays Since Svelte 5.16, `class` accepts objects/arrays, converted using [clsx](https://github.com/lukeed/clsx). **Objects** - truthy keys are added: ```svelte
    ...
    ``` **Arrays** - truthy values combined: ```svelte
    ...
    ``` **Nested arrays/objects** - flattened by clsx: ```svelte ``` ```svelte ``` **TypeScript** - use `ClassValue` type: ```svelte
    ...
    ``` ## The `class:` directive Legacy conditional class setting (pre-5.16): ```svelte
    ...
    ...
    ``` Shorthand when class name matches value: ```svelte
    ...
    ``` > Consider using `class` attribute instead - more powerful and composable. ## apps/svelte.dev/content/docs/svelte/03-template-syntax/19-await-expressions.md # await As of Svelte 5.36, use `await` in three new places: - Top level of component `

    {a} + {b} = {await add(a, b)}

    ``` When `a` increments, `

    ` won't show `2 + 2 = 3` but waits to show `2 + 2 = 4` when resolved. ## Concurrency Independent `await` expressions run in parallel: ```svelte

    {await one()}

    {await two()}

    ``` Both functions run simultaneously. Sequential `await` in ` {#if error} {/if} ``` Useful for error reporting or handling errors outside the boundary. Rethrowing errors bubbles to parent boundaries. ## apps/svelte.dev/content/docs/svelte/05-special-elements/02-svelte-window.md # `` ```svelte ``` Adds event listeners to `window` object. Auto-removes on component destroy. SSR-safe. Must be at component top level, not inside blocks/elements. ## Event Listeners ```svelte ``` ## Bindable Properties ```svelte ``` **Readonly:** `innerWidth`, `innerHeight`, `outerWidth`, `outerHeight`, `online`, `devicePixelRatio` **Writable:** `scrollX`, `scrollY` > **Note:** Initial binding values don't trigger scrolling. Use `scrollTo()` in `$effect` if needed. ## apps/svelte.dev/content/docs/svelte/05-special-elements/03-svelte-document.md # `` Adds event listeners and actions to the `document` object. Must be at component top level, never inside blocks or elements. ## Syntax ```svelte ``` ## Usage ```svelte ``` ## Bindable Properties (readonly) - `activeElement` - `fullscreenElement` - `pointerLockElement` - `visibilityState` ## apps/svelte.dev/content/docs/svelte/05-special-elements/04-svelte-body.md # `` ```svelte ``` Adds event listeners to `document.body` for events that don't fire on `window` (like `mouseenter`/`mouseleave`). Also allows [actions](use) on ``. **Requirements:** - Must be at top level of component - Cannot be inside blocks or elements ```svelte ``` ## apps/svelte.dev/content/docs/svelte/05-special-elements/05-svelte-head.md # `` ```svelte ... ``` Inserts elements into `document.head`. During SSR, head content is exposed separately from body content. Must be at component top level, never inside blocks or elements. ```svelte Hello world! ``` ## apps/svelte.dev/content/docs/svelte/05-special-elements/06-svelte-element.md # `` ```svelte ``` Renders dynamic elements unknown at author time (e.g., from CMS). ## Usage ```svelte This text cannot appear inside an hr element ``` ## Key Points - Properties and event listeners are applied to the element - Only `bind:this` binding supported - If `this` is nullish, element and children won't render - Void elements (e.g., `br`) with children throw runtime error in dev - Use `xmlns` attribute for explicit namespace: ```svelte ``` - `this` must be valid DOM element tag (not `#text` or `svelte:head`) ## apps/svelte.dev/content/docs/svelte/05-special-elements/07-svelte-options.md # `` ```svelte ``` Specifies per-component compiler options. ## Options - `runes={true}` โ€” forces runes mode - `runes={false}` โ€” forces legacy mode - `namespace="..."` โ€” "html" (default), "svg", or "mathml" - `customElement={...}` โ€” custom element options, or string for tag name - `css="injected"` โ€” injects styles inline (`