## docs/svelte/01-introduction/01-overview.md # Overview Svelte compiles declarative components (HTML, CSS, JS) into optimized JavaScript. **Basic component:** ```svelte ``` Use for standalone components or full apps with SvelteKit. ## docs/svelte/01-introduction/02-getting-started.md # Getting started ## Create project ```sh npx sv create myapp cd myapp npm install npm run dev ``` Uses [SvelteKit](../kit) (official framework) + [Vite](https://vite.dev/). ## Alternatives **Vite standalone:** `npm create vite@latest` β†’ select `svelte`. Generates HTML/JS/CSS in `dist`. Need to add [routing library](/packages#routing). **Other bundlers:** [Plugins available](/packages#bundler-plugins), but Vite recommended. ## Editor tooling - [VS Code extension](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode) - [Other editors](https://sveltesociety.dev/collection/editor-support-c85c080efc292a34) - CLI check: `npx sv check` ## Help - [Discord](/chat) - [Stack Overflow](https://stackoverflow.com/questions/tagged/svelte) ## docs/svelte/01-introduction/03-svelte-files.md # .svelte files Components are written in `.svelte` files. All three sections are optional. ```svelte /// file: MyComponent.svelte ``` ## ` ``` Can `export` bindings (becomes module exports). Cannot `export default` (component is default export). > **Note:** Svelte 4 used ` ``` `count` is just a number, update it like any variable. ## Deep state Arrays and plain objects become deeply reactive proxies. Updates trigger granular UI changes. ```js let todos = $state([ { done: false, text: 'add more todos' } ]); // triggers updates for this specific property todos[0].done = !todos[0].done; // new objects are also proxified todos.push({ done: false, text: 'eat lunch' }); ``` **Gotcha:** Destructuring breaks reactivity (evaluated at destructure time): ```js let { done, text } = todos[0]; // this will NOT affect the value of `done` todos[0].done = !todos[0].done; ``` ## Classes Use `$state` in class fields or as first assignment in constructor: ```js class Todo { done = $state(false); constructor(text) { this.text = $state(text); } reset() { this.text = ''; this.done = false; } } ``` **Gotcha:** `this` binding in methods. Use inline function or arrow function: ```svelte ``` Or use arrow function in class: ```js class Todo { done = $state(false); constructor(text) { this.text = $state(text); } reset = () => { this.text = ''; this.done = false; } } ``` ## Built-in classes Import reactive `Set`, `Map`, `Date`, `URL` from `svelte/reactivity`. ## `$state.raw` Non-deep reactive state. Cannot mutate, only reassign. ```js let person = $state.raw({ name: 'Heraclitus', age: 49 }); // no effect person.age += 1; // works - reassignment person = { name: 'Heraclitus', age: 50 }; ``` Better performance for large arrays/objects you won't mutate. Can contain reactive state. ## `$state.snapshot` Takes static snapshot of reactive proxy: ```svelte ``` Useful for external libraries expecting plain objects (e.g., `structuredClone`). ## `$state.eager` Updates UI immediately instead of waiting for `await` synchronization: ```svelte ``` Use sparingly, only for user feedback during actions. ## Passing state into functions JavaScript is pass-by-value. To pass current values, use functions: ```js function add(getA, getB) { return() => getA() + getB(); } let a = 1; let b = 2; let total = add(() => a, () => b); console.log(total()); // 3 a = 3; b = 4; console.log(total()); // 7 ``` Or use getters: ```js function add(input) { return { get value() { return input.a + input.b; } }; } let input = $state({ a: 1, b: 2 }); let total = add(input); console.log(total.value); // 3 input.a = 3; input.b = 4; console.log(total.value); // 7 ``` ## Passing state across modules Can't directly export reassignable state from `.svelte.js`/`.svelte.ts`: ```js // ❌ Won't work export let count = $state(0); ``` **Options:** 1. Export object, update properties: ```js // βœ… Works export const counter = $state({ count: 0 }); export function increment() { counter.count += 1; } ``` 2. Don't directly export: ```js // βœ… Works let count = $state(0); export function getCount() { return count; } export function increment() { count += 1; } ``` ## docs/svelte/02-runes/03-$derived.md # $derived Derived state recomputes when dependencies change: ```svelte

{count} doubled is {doubled}

``` **Key rules:** - Expression must be side-effect free (no `count++`) - Can mark class fields as `$derived` - Without `$derived`, values don't update when dependencies change ## `$derived.by` For complex derivations, use `$derived.by` with a function: ```svelte ``` `$derived(expression)` = `$derived.by(() => expression)` ## Dependencies Anything read synchronously inside `$derived` is a dependency. Use [`untrack`](svelte#untrack) to exempt state from being a dependency. ## Overriding Values Can temporarily reassign derived values (unless `const`). Useful for optimistic UI: ```svelte ``` ## Reactivity `$derived` values are NOT deeply reactive (unlike `$state`): ```js // @errors: 7005 let items = $state([ /*...*/ ]); let index = $state(0); let selected = $derived(items[index]); ``` Mutating `selected` affects the underlying `items` array. ## Destructuring Destructured variables are all reactive: ```js function stuff() { return { a: 1, b: 2, c: 3 } } //cut let { a, b, c } = $derived(stuff()); ``` Equivalent to: ```js function stuff() { return { a: 1, b: 2, c: 3 } } //cut let _stuff = $derived(stuff()); let a = $derived(_stuff.a); let b = $derived(_stuff.b); let c = $derived(_stuff.c); ``` ## Update Propagation **Push-pull reactivity:** Dependencies notified immediately (push), but derived values only re-evaluated when read (pull). If new value is referentially identical to previous, downstream updates skip: ```svelte ``` Button only updates when `large` changes, not `count`. ## docs/svelte/02-runes/04-$effect.md # $effect Effects run when state updates. Run in browser only, not during SSR. **Don't update state inside effects** - leads to complexity and infinite loops. See alternatives below. ## Basic Usage ```svelte ``` Tracks accessed state/derived and re-runs when they change. ## Lifecycle - Runs after component mounts - Re-runs in microtask after state changes (batched) - Can be used anywhere while parent effect is running ### Teardown Functions ```svelte

{count}

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

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

``` ### Conditional Dependencies Effect only depends on values read in last run: ```ts import confetti from 'canvas-confetti'; let condition = $state(true); let color = $state('#ff3e00'); $effect(() => { if (condition) { confetti({ colors: [color] }); // tracks `condition` and `color` } else { confetti(); // only tracks `condition` } }); ``` ## `$effect.pre` Runs **before** DOM updates: ```svelte
{#each messages as message}

{message}

{/each}
``` ## `$effect.tracking` Returns `true` if code runs inside tracking context (effect or template): ```svelte

in template: {$effect.tracking()}

``` ## `$effect.pending` Returns count of pending promises in current boundary (excludes child boundaries): ```svelte

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

{#if $effect.pending()}

pending promises: {$effect.pending()}

{/if} ``` ## `$effect.root` Creates non-tracked scope with manual cleanup. Can create effects outside component init: ```js const destroy = $effect.root(() => { $effect(() => { // setup }); return () => { // cleanup }; }); // later... destroy(); ``` ## When NOT to Use ### ❌ Don't synchronize state ```svelte ``` ### βœ… Use $derived instead ```svelte ``` ### ❌ Don't link values with effects ```svelte ``` ### βœ… Use callbacks or function bindings ```svelte ``` **Note:** If you must update `$state` in effect and hit infinite loop, use `untrack()`. ## docs/svelte/02-runes/05-$props.md # $props Pass props to components like attributes: ```svelte ``` Receive with `$props()` rune (destructuring is common): ```svelte

this component is {adjective}

``` ## Fallback values Use destructuring defaults for undefined props: ```js let { adjective = 'happy' } = $props(); ``` > **Note:** Fallback values are NOT reactive proxies ## Renaming props For invalid identifiers or keywords: ```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 **reassign** (not mutate): ```svelte ``` ```svelte ``` ### Don't mutate props - Regular object mutation: no effect - Reactive proxy mutation: works but triggers `ownership_invalid_mutation` warning - Fallback value mutation: no effect **Solution:** Use callback props or `$bindable` for shared state. ## Type safety TypeScript: ```svelte ``` JSDoc: ```svelte ``` With interface: ```svelte ``` > **Note:** Use `Snippet` interface from `'svelte'` for snippet props. Native DOM element interfaces in `svelte/elements`. ## `$props.id()` Generates unique ID per component instance (consistent during SSR hydration): ```svelte
``` ## docs/svelte/02-runes/06-$bindable.md # $bindable Props normally flow parent β†’ child. `$bindable` allows two-way binding (child ↔ parent). **Use sparingly** β€” overuse makes data flow unpredictable. ## Basic Usage Child component marks prop as bindable: ```svelte /// file: FancyInput.svelte ``` Parent uses `bind:` directive: ```svelte /// file: App.svelte

{message}

``` ## Fallback Value Parent can pass normal prop without `bind:`. Provide fallback for when no prop passed: ```js /// file: FancyInput.svelte let { value = $bindable('fallback'), ...props } = $props(); ``` ## Key Points - Enables state proxy mutation in child - Mutating normal props triggers warning - Parent not required to use `bind:` ## docs/svelte/02-runes/07-$inspect.md # $inspect > **Note:** Dev-only. Noop in production. Roughly equivalent to `console.log`, but re-runs when arguments change. Tracks reactive state deeply. ```svelte ``` Prints stack trace on updates (except in playground). ## $inspect(...).with Custom callback instead of `console.log`. First arg is `"init"` or `"update"`, rest are inspected values. ```svelte ``` ## $inspect.trace(...) Added in 5.14. Traces function re-runs in effects/derived. Logs which reactive state caused re-run. ```svelte ``` Takes optional label as first argument. ## docs/svelte/02-runes/08-$host.md # $host Provides access to the host element when compiling a component as a custom element. ## Usage ```svelte /// file: Stepper.svelte ``` ```svelte /// file: App.svelte count -= 1} onincrement={() => count += 1} >

count: {count}

``` **Key use case:** Dispatching custom events from custom elements. ## docs/svelte/03-template-syntax/01-basic-markup.md # Basic markup ## Tags Lowercase = HTML element. Capitalized/dot notation = component. ```svelte
``` ## Element attributes Attributes work like HTML. Values can contain or be JavaScript expressions. ```svelte page {p} ``` **Boolean attributes**: included if truthy, excluded if falsy. **Other attributes**: included unless nullish (`null`/`undefined`). ```svelte
This div has no title attribute
``` **Shorthand**: `{name}` when name and value match. ```svelte ``` ## Component props Same rules as attributes. Use shorthand `{name}` when applicable. ```svelte ``` ## Spread attributes Multiple spreads allowed. Order matters for precedence. ```svelte ``` ## Events Use `on` prefix (e.g., `onclick`). Case sensitive. ```svelte ``` - Shorthand/spread work: ` ``` ```svelte ``` **Gotcha:** Cannot have a prop named `children` if component has content inside tags. ## Optional Snippets Optional chaining: ```svelte {@render children?.()} ``` With fallback: ```svelte {#if children} {@render children()} {:else} fallback content {/if} ``` ## TypeScript ```svelte ``` With generics: ```svelte ``` **Note:** `Snippet` type argument is a tuple for multiple parameters. ## Exporting Snippets Top-level snippets can be exported from ` {#snippet add(a, b)} {a} + {b} = {a + b} {/snippet} ``` **Requires:** Svelte 5.5.0+ ## Programmatic Snippets Use [`createRawSnippet`](svelte#createRawSnippet) API for advanced use cases. ## Migration Snippets replace Svelte 4 slots (now deprecated). ## docs/svelte/03-template-syntax/07-@render.md # {@render ...} Renders a [snippet](snippet). ```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 any JavaScript: ```svelte {@render (cool ? coolSnippet : lameSnippet)()} ``` ## Optional snippets Use optional chaining for potentially undefined snippets (e.g., props): ```svelte {@render children?.()} ``` Or `{#if}` with fallback: ```svelte {#if children} {@render children()} {:else}

fallback content

{/if} ``` ## docs/svelte/03-template-syntax/08-@html.md # {@html ...} Injects raw HTML into component: ```svelte
{@html content}
``` **Warning:** Escape strings or use trusted values only to prevent XSS attacks. Never render unsanitized content. ## Limitations - Expression must be valid standalone HTML (can't split tags) - Won't compile Svelte code ## Styling `{@html}` content is invisible to scoped styles. Use `:global` modifier: ```svelte
{@html 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. Can return cleanup function. ```svelte
...
``` ## Attachment factories Functions can return attachments. Re-runs when state changes: ```svelte ``` ## Inline attachments ```svelte { const context = canvas.getContext('2d'); $effect(() => { context.fillStyle = color; context.fillRect(0, 0, canvas.width, canvas.height); }); }} > ``` ## Conditional attachments Falsy values = no attachment: ```svelte
...
``` ## Passing to components `{@attach ...}` on components creates a Symbol prop. Spread props to pass attachments to elements: ```svelte ``` ```svelte ``` ## Controlling re-runs Attachments are fully reactive: `{@attach foo(bar)}` re-runs on changes to `foo`, `bar`, or any state read inside. To prevent expensive re-runs, pass data in a function and read in child effect: ```js // @errors: 7006 2304 2552 function foo(getBar) { return (node) => { veryExpensiveSetupWork(node); $effect(() => { update(node, getBar()); }); } } ``` ## Utilities - [`createAttachmentKey`](svelte-attachments#createAttachmentKey) - add attachments to objects for spreading - [`fromAction`](svelte-attachments#fromAction) - convert actions to attachments ## docs/svelte/03-template-syntax/10-@const.md # {@const ...} 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: - `{#if ...}`, `{#each ...}`, `{#snippet ...}` blocks - `` - `` ## docs/svelte/03-template-syntax/11-@debug.md # {@debug ...} Logs variable values when they change and pauses execution in devtools. ```svelte {@debug user}

Hello {user.firstname}!

``` ## Usage **Accepts:** Comma-separated variable names (not expressions) ```svelte {@debug user} {@debug user1, user2, user3} {@debug user.firstname} {@debug myArray[0]} {@debug !isReady} {@debug typeof user === 'object'} ``` **No arguments:** Triggers on any state change ```svelte {@debug} ``` ## docs/svelte/03-template-syntax/12-bind.md # bind: Data flows down (parent β†’ child). `bind:` flows data up (child β†’ parent). Syntax: `bind:property={expression}` or `bind:property` (shorthand when names match) ```svelte ``` Svelte creates event listeners to 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
...
``` ## `` Binds input's `value` property: ```svelte

{message}

``` Numeric inputs (`type="number"` or `type="range"`) coerce to number: ```svelte

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

``` Empty/invalid value is `undefined`. Since 5.6.0: `defaultValue` reverts on form reset (unless binding is `null`/`undefined`): ```svelte
``` ## `` For checkboxes: ```svelte ``` Since 5.6.0: `defaultChecked` reverts on form reset: ```svelte
``` > Use `bind:group` for radio inputs, not `bind:checked`. ## `` For checkbox indeterminate state: ```svelte
{#if indeterminate} waiting... {:else if checked} checked {:else} unchecked {/if}
``` ## `` For radio/checkbox groups: ```svelte ``` > Only works if inputs are in same component. ## `` For `type="file"`: ```svelte ``` Must use `FileList` object. Create via `DataTransfer` to modify programmatically. > Leave uninitialized for SSR compatibility. ## ` ``` ` ``` Omit `value` if it matches text: ```svelte ``` Use `selected` attribute for default/reset value: ```svelte ``` ## `