## docs/svelte/01-introduction/01-overview.md
# Svelte Overview
Svelte is a UI framework that compiles components into optimized JavaScript. Use it for anything from standalone components to full stack apps with SvelteKit.
```svelte
```
For beginners, start with the [interactive tutorial](/tutorial). Try Svelte online in the [playground](/playground) or on [StackBlitz](https://sveltekit.new).
## docs/svelte/01-introduction/02-getting-started.md
# Getting Started with Svelte 5
## Quick Start
```bash
npx sv create myapp
cd myapp
npm install
npm run dev
```
SvelteKit is the recommended framework for most projects. Alternatively:
```bash
npm create vite@latest
# Select svelte option
```
## Editor Support
- [VS Code extension](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode)
- Command line: `sv check`
## Help Resources
- [Discord](/chat)
- [Stack Overflow](https://stackoverflow.com/questions/tagged/svelte)
## docs/svelte/01-introduction/03-svelte-files.md
# Svelte Components (.svelte files)
Components are written in `.svelte` files with three optional sections:
```svelte
```
## `
```
You can `export` bindings from this block (except `export default`).
## `
```
## docs/svelte/01-introduction/04-svelte-js-files.md
# .svelte.js and .svelte.ts files
Svelte 5 operates on `.svelte.js` and `.svelte.ts` files in addition to `.svelte` files.
These files:
- Behave like regular JS/TS modules
- Support runes for reactive logic
- Allow sharing reactive state across your app
```js
// store.svelte.js
export let $state count = 0;
export const increment = () => count += 1;
```
> Note: You cannot export reassigned state across modules.
## docs/svelte/02-runes/01-what-are-runes.md
# Svelte 5 Runes
Runes are compiler-controlled symbols in `.svelte` and `.svelte.js`/`.svelte.ts` files with a `$` prefix.
## Key Characteristics
- No imports needed - built into Svelte
- Not assignable to variables or passable as arguments
- Only valid in specific positions (compiler will warn)
- Always prefixed with `$`
```js
let message = $state('hello');
```
> Runes are new in Svelte 5 and replace the reactive syntax from previous versions.
## docs/svelte/02-runes/02-$state.md
# Svelte 5 Runes - Condensed Documentation
## $state
Creates reactive state that triggers UI updates when changed.
```svelte
```
### Deep state
Arrays and objects become deeply reactive state proxies:
```svelte
```
- Modifying nested properties triggers UI updates
- New objects added to arrays are automatically proxified
- Destructuring breaks reactivity
### Classes
Use $state in class fields:
```js
class Todo {
done = $state(false);
text = $state();
constructor(text) {
this.text = text;
}
reset() {
this.text = '';
this.done = false;
}
}
```
When using methods, handle `this` context:
```svelte
```
Or use arrow functions in class:
```js
class Todo {
// ...
reset = () => {
this.text = '';
this.done = false;
}
}
```
## $state.raw
For non-deeply reactive state:
```js
let person = $state.raw({
name: 'Heraclitus',
age: 49
});
// No effect
person.age += 1;
// Works - creates new object
person = {
name: 'Heraclitus',
age: 50
};
```
## $state.snapshot
Create static copy of reactive state:
```svelte
```
## Passing state
State is passed by value, not by reference:
```js
let a = $state(1);
let b = $state(2);
// Accessing current values
```
For reactive objects:
```js
function add(input) {
return {
get value() {
return input.a + input.b;
}
};
}
let input = $state({ a: 1, b: 2 });
let total = add(input);
```
## Cross-module state
Can't export directly reassigned state:
```js
// Not allowed
export let count = $state(0);
export function increment() {
count += 1;
}
```
Instead, export objects:
```js
// Allowed - updating property, not reassigning
export const counter = $state({
count: 0
});
export function increment() {
counter.count += 1;
}
```
Or use getter functions:
```js
let count = $state(0);
export function getCount() {
return count;
}
export function increment() {
count += 1;
}
```
## docs/svelte/02-runes/03-$derived.md
# $derived Rune in Svelte 5
The `$derived` rune creates reactive values that automatically update when their dependencies change.
## Basic Usage
```svelte
{count} doubled is {doubled}
```
> Without `$derived`, `doubled` would not update when `count` changes.
## Complex Derivations with $derived.by
For multi-line derivations, use `$derived.by`:
```svelte
```
`$derived(expression)` is equivalent to `$derived.by(() => expression)`.
## Dependencies
Any state read synchronously inside the `$derived` expression becomes a dependency. Use `untrack` to exempt state from being a dependency.
## Overriding Derived Values
You can temporarily override derived values by reassigning them (useful for optimistic UI):
```svelte
```
## Reactivity Behavior
Unlike `$state`, `$derived` values are not converted to deeply reactive proxies. When accessing properties of a derived object that references a reactive state, mutations affect the underlying state.
## Update Propagation
Svelte uses push-pull reactivity:
- Changes are immediately pushed to dependents
- Derived values are only recalculated when read
- Updates are skipped if the new value is referentially identical to the previous value
```svelte
```
The button text only updates when `large` changes value, not on every `count` change.
## docs/svelte/02-runes/04-$effect.md
# Svelte 5 $effect Rune
## Basic Usage
Effects run when state updates, useful for third-party libraries, canvas manipulation, or network requests. They only run in the browser.
```svelte
```
## Lifecycle
- Effects run after DOM mounting and in a microtask after state changes
- Re-runs are batched and happen after DOM updates
- Can return a teardown function that runs before effect re-runs or when destroyed
```svelte
{count}
```
## Dependencies
- Automatically tracks reactive values read synchronously
- Async operations (after `await` or in `setTimeout`) won't track dependencies
- Only reruns when the object it reads changes, not when properties change
- Dependencies are based on what was read in the previous run
```svelte
{state.value} doubled is {derived.value}
```
## Variants
### `$effect.pre`
Runs before DOM updates:
```svelte
{#each messages as message}
{message}
{/each}
```
### `$effect.tracking`
Tells if code is running in a tracking context:
```svelte
in template: {$effect.tracking()}
```
### `$effect.root`
Creates a non-tracked scope without auto-cleanup:
```js
const destroy = $effect.root(() => {
$effect(() => {
// setup
});
return () => {
// cleanup
};
});
// later...
destroy();
```
## When Not To Use `$effect`
Avoid using for state synchronization. Instead of:
```svelte
```
Use `$derived`:
```svelte
```
For linked values, use function bindings instead of effects:
```svelte
```
## docs/svelte/02-runes/05-$props.md
# $props in Svelte 5
The `$props` rune defines component inputs.
## Basic Usage
```svelte
```
```svelte
this component is {adjective}
```
## Fallback Values
```js
let { adjective = 'happy' } = $props();
```
> Note: Fallback values are not 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 values change. Child components can temporarily override prop values:
```svelte
```
```svelte
```
### Important Rules
1. You can reassign props but should not mutate them unless they are `$bindable`
2. Mutating regular objects has no effect
3. Mutating reactive state proxies works but triggers an `ownership_invalid_mutation` warning
4. Fallback values are not reactive state proxies, so mutations won't cause updates
## Type Safety
```svelte
```
Or with JSDoc:
```svelte
```
With separate type declaration:
```svelte
```
## $props.id()
Generates a unique ID for the component instance:
```svelte
```
## docs/svelte/02-runes/06-$bindable.md
# Svelte 5 Condensed: $bindable
## Basic Usage
`$bindable` enables two-way data flow between parent and child components.
```svelte
/// file: FancyInput.svelte
```
Parent component can bind to the prop:
```svelte
/// file: App.svelte
{message}
```
## Default Values
Provide fallback values when no prop is passed:
```js
/// file: FancyInput.svelte
let { value = $bindable('fallback'), ...props } = $props();
```
## Key Points
- Props normally flow one-way (parent to child)
- `$bindable` allows data to flow up from child to parent
- Parent components can choose whether to use `bind:` or not
- Use sparingly to maintain clear data flow in your app
- State proxies can be mutated in child components
## docs/svelte/02-runes/07-$inspect.md
# Svelte 5 Documentation: $inspect
## Basic Usage
```svelte
```
> **Note**: `$inspect` only works during development. In production, it becomes a no-op.
## $inspect(...).with
Customize logging behavior with a callback:
```svelte
```
Quick trace shorthand:
```js
$inspect(stuff).with(console.trace);
```
## $inspect.trace(...)
Traces reactive dependencies in development:
```svelte
```
Accepts an optional label parameter.
## docs/svelte/02-runes/08-$host.md
# $host
When compiling a component as a custom element, the `$host` rune provides access to the host element.
```svelte
/// file: Stepper.svelte
```
```svelte
/// file: App.svelte
count -= 1}
onincrement={() => count += 1}
>
```
## Component Props
```svelte
```
## Events
```svelte
```
- Event attributes are case sensitive (`onclick` โ `onClick`)
- Can use shorthand: ``
- Can spread events: ``
- `ontouchstart` and `ontouchmove` are passive by default
### Event Delegation
Svelte uses event delegation for performance. Important notes:
- When manually dispatching events, use `{ bubbles: true }`
- Avoid `stopPropagation` with `addEventListener`
- Use `on` from `svelte/events` instead of `addEventListener`
Delegated events: `beforeinput`, `click`, `change`, `dblclick`, `contextmenu`, `focusin`, `focusout`, `input`, `keydown`, `keyup`, `mousedown`, `mousemove`, `mouseout`, `mouseover`, `mouseup`, `pointerdown`, `pointermove`, `pointerout`, `pointerover`, `pointerup`, `touchend`, `touchmove`, `touchstart`
## Text Expressions
```svelte
Hello {name}!
{a} + {b} = {a + b}.
{(/^[A-Za-z ]+$/).test(value) ? x : y}
{@html potentiallyUnsafeHtmlString}
```
- `null` or `undefined` expressions are omitted
- All others are coerced to strings
- Escape curly braces with HTML entities: `{`, `{`, `{`, `}`, `}`, `}`
## Comments
```svelte
Hello world
Hello, {name}
```
- Use `` to disable warnings
- Use `` for component documentation
## docs/svelte/03-template-syntax/02-if.md
# {#if ...}
```svelte
{#if expression}...{/if}
{#if expression}...{:else if expression}...{/if}
{#if expression}...{:else}...{/if}
```
Conditionally render content with if blocks:
```svelte
{#if answer === 42}
what was the question?
{/if}
```
Chain conditions with `:else if` and `:else`:
```svelte
{#if porridge.temperature > 100}
too hot!
{:else if 80 > porridge.temperature}
too cold!
{:else}
just right!
{/if}
```
Note: Blocks can wrap elements or text within elements.
## docs/svelte/03-template-syntax/03-each.md
# Svelte 5 Each Blocks
## Basic Usage
```svelte
{#each expression as name}...{/each}
{#each expression as name, index}...{/each}
```
Iterate over arrays, array-likes, or iterables (Map, Set, etc.):
```svelte
Shopping list
{#each items as item}
{item.name} x {item.qty}
{/each}
```
With index:
```svelte
{#each items as item, i}
{i + 1}: {item.name} x {item.qty}
{/each}
```
## Keyed Each Blocks
```svelte
{#each expression as name (key)}...{/each}
{#each expression as name, index (key)}...{/each}
```
Keys help Svelte efficiently update lists when data changes:
```svelte
{#each items as item (item.id)}
{item.name} x {item.qty}
{/each}
{#each items as item, i (item.id)}
{i + 1}: {item.name} x {item.qty}
{/each}
```
## Destructuring
```svelte
{#each items as { id, name, qty }, i (id)}
{i + 1}: {name} x {qty}
{/each}
{#each objects as { id, ...rest }}
{id}
{/each}
{#each items as [id, ...rest]}
{id}
{/each}
```
## Each Without Item
For repeating n times:
```svelte
{#each { length: 8 }, rank}
{#each { length: 8 }, file}
{/each}
{/each}
```
## Else Blocks
```svelte
{#each todos as todo}
{todo.text}
{:else}
No tasks today!
{/each}
```
## docs/svelte/03-template-syntax/04-key.md
# {#key ...}
```svelte
{#key expression}...{/key}
```
Key blocks destroy and recreate their contents when an expression value changes:
```svelte
{#key value}
{/key}
```
Useful for:
- Reinstantiating components when a value changes
- Triggering transitions on value changes:
```svelte
{#key value}
{value}
{/key}
```
## docs/svelte/03-template-syntax/05-await.md
# {#await ...}
```svelte
{#await expression}...{:then name}...{:catch name}...{/await}
{#await expression}...{:then name}...{/await}
{#await expression then name}...{/await}
{#await expression catch name}...{/await}
```
Await blocks handle the three states of a Promise:
```svelte
{#await promise}
waiting for the promise to resolve...
{:then value}
The value is {value}
{:catch error}
Something went wrong: {error.message}
{/await}
```
> During SSR, only the pending branch renders. Non-Promise expressions only render the `:then` branch.
**Simplified variants:**
```svelte
{#await promise}
waiting for the promise to resolve...
{:then value}
The value is {value}
{/await}
```
```svelte
{#await promise then value}
{/await}
```
> Use with dynamic imports for lazy loading:
> ```svelte
> {#await import('./Component.svelte') then { default: Component }}
>
> {/await}
> ```
## docs/svelte/03-template-syntax/06-snippet.md
# Svelte 5 Snippets
## {#snippet ...}
```svelte
{#snippet name()}...{/snippet}
{#snippet name(param1, param2, paramN)}...{/snippet}
```
Snippets create reusable markup chunks within components:
```svelte
{#snippet figure(image)}
{image.caption}
{/snippet}
{#each images as image}
{#if image.href}
{@render figure(image)}
{:else}
{@render figure(image)}
{/if}
{/each}
```
Snippets can have parameters with default values and destructuring (no rest parameters).
## Scope
Snippets can access outer scope values:
```svelte
{#snippet hello(name)}
hello {name}! {message}!
{/snippet}
{@render hello('alice')}
{@render hello('bob')}
```
Snippets are visible to siblings and their children. They can reference themselves and other snippets:
```svelte
{#snippet countdown(n)}
{#if n > 0}
{n}...
{@render countdown(n - 1)}
{:else}
{@render blastoff()}
{/if}
{/snippet}
{#snippet blastoff()}
๐
{/snippet}
{@render countdown(10)}
```
## Passing Snippets to Components
### Explicit Props
```svelte
{#snippet header()}
fruit
qty
price
total
{/snippet}
{#snippet row(d)}
{d.name}
{d.qty}
{d.price}
{d.qty * d.price}
{/snippet}
```
### Implicit Props
Snippets declared inside a component become props on the component:
```svelte
{#snippet header()}
fruit
qty
price
total
{/snippet}
{#snippet row(d)}
{d.name}
{d.qty}
{d.price}
{d.qty * d.price}
{/snippet}
```
### Implicit `children` Snippet
Non-snippet content becomes the `children` snippet:
```svelte
```
```svelte
```
> Don't create a prop named `children` if you also have content inside the component
### Optional Snippet Props
Handle optional snippets with optional chaining:
```svelte
{@render children?.()}
```
Or with fallback content:
```svelte
{#if children}
{@render children()}
{:else}
fallback content
{/if}
```
## Typing Snippets
```svelte
```
## Exporting Snippets
Top-level snippets can be exported from `
{#snippet add(a, b)}
{a} + {b} = {a + b}
{/snippet}
```
> Requires Svelte 5.5.0+
## Advanced Usage
- Programmatic snippets can be created with `createRawSnippet` API
- Snippets replace slots in Svelte 5 (slots are deprecated)
## docs/svelte/03-template-syntax/07-@render.md
# {@render ...}
Use `{@render ...}` to render [snippets](snippet).
```svelte
{#snippet sum(a, b)}
{a} + {b} = {a + b}
{/snippet}
{@render sum(1, 2)}
{@render sum(3, 4)}
{@render sum(5, 6)}
```
The expression can be an identifier or any JavaScript expression:
```svelte
{@render (cool ? coolSnippet : lameSnippet)()}
```
## Optional snippets
For potentially undefined snippets, use optional chaining:
```svelte
{@render children?.()}
```
Or use an `{#if ...}` block with fallback content:
```svelte
{#if children}
{@render children()}
{:else}
fallback content
{/if}
```
## docs/svelte/03-template-syntax/08-@html.md
# {@html ...}
Use `{@html ...}` to inject raw HTML into your component:
```svelte
{@html content}
```
> [!NOTE] Always sanitize HTML content to prevent XSS attacks.
## Limitations
- Expression must be valid standalone HTML
- Will not compile Svelte code
- Cannot split HTML tags across multiple `{@html}` tags
## Styling
Content rendered with `{@html ...}` is invisible to Svelte's style scoping:
```svelte
```
## docs/svelte/03-template-syntax/09-@const.md
# {@const ...}
The `{@const ...}` tag defines a local constant within a block.
```svelte
{#each boxes as box}
{@const area = box.width * box.height}
{box.width} * {box.height} = {area}
{/each}
```
Only allowed as an immediate child of:
- Blocks (`{#if ...}`, `{#each ...}`, `{#snippet ...}`, etc.)
- Components (``)
- ``
## docs/svelte/03-template-syntax/10-@debug.md
# {@debug ...}
The `{@debug ...}` tag provides debugging capabilities in Svelte components:
```svelte
{@debug user}
Hello {user.firstname}!
```
## Usage
- Logs values when they change and pauses execution if devtools are open
- Accepts comma-separated variable names (not expressions):
```svelte
{@debug user}
{@debug user1, user2, user3}
```
- Without arguments, triggers on any state change:
```svelte
{@debug}
```
## docs/svelte/03-template-syntax/11-bind.md
# Svelte 5 and SvelteKit Condensed Documentation
## bind:
Data flows down from parent to child. `bind:` allows data to flow upward.
```svelte
```
### Function bindings (v5.9.0+)
```svelte
value,
(v) => value = v.toLowerCase()}
/>
...
```
### Input bindings
```svelte
```
### Select bindings
```svelte
```
### Media element bindings
```svelte
```
### Other element bindings
```svelte
Title
Content
```
### bind:this
```svelte
```
### Component bindings
```svelte
```
## docs/svelte/03-template-syntax/12-use.md
# use: Directive in Svelte 5
Actions are functions called when an element is mounted, added with the `use:` directive.
## Basic Usage
```svelte
...
```
## With Parameters
```svelte
...
```
> Note: Actions run once when mounted (not during SSR). They don't re-run if parameters change.
## Typing
```svelte
...
```
The `Action` interface accepts three optional type arguments:
1. Node type (can be `Element` for all elements)
2. Parameter type
3. Custom event handlers created by the action
## docs/svelte/03-template-syntax/13-transition.md
# Svelte 5 Transitions
## Basic Usage
Transitions are triggered when elements enter or leave the DOM due to state changes.
```svelte
{#if visible}
fades in and out
{/if}
```
## Local vs Global
Transitions are local by default - they only play when their immediate block is created/destroyed.
```svelte
{#if x}
{#if y}
{/if}
```
## Transition Events
Elements with transitions dispatch these events:
- `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}
```
## docs/svelte/03-template-syntax/14-in-and-out.md
# in: and out: Directives
These directives create one-way transitions that don't reverse when interrupted.
```svelte
{#if visible}
flies in, fades out
{/if}
```
Key differences from `transition:`:
- Transitions are not bidirectional
- An `in` transition continues playing alongside the `out` transition
- If an `out` transition is aborted, transitions restart from scratch
## docs/svelte/03-template-syntax/15-animate.md
# animate:
Animations trigger when contents of a keyed each block are re-ordered (not when elements are added/removed).
```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
}
```
Custom animations receive:
- `node`: The HTML element
- `animation`: Object with `from` and `to` DOMRect properties
- `parameters`: Any custom parameters
Return an object with either:
- `css` method (preferred, runs off main thread)
- `tick` function (runs during animation)
```svelte
{#each list as item, index (item)}
{item}
{/each}
```
Using `tick` instead of `css`:
```svelte
{#each list as item, index (item)}
{item}
{/each}
```
> Prefer `css` over `tick` for better performance on slower devices.
## docs/svelte/03-template-syntax/17-style.md
# style: directive
The `style:` directive provides a shorthand for setting styles on elements.
## Basic Usage
```svelte
...
...
```
## Dynamic Values
```svelte
...
```
## Shorthand Form
```svelte
...
```
## Multiple Styles
```svelte
...
```
## Important Modifier
```svelte
...
```
## Precedence
When combined with `style` attributes, directives take precedence:
```svelte
This will be red
```
## docs/svelte/03-template-syntax/18-class.md
# Svelte Class Handling
## Class Attribute
### Basic Usage
```svelte
...
```
> Note: Falsy values are stringified, but `undefined`/`null` omit the attribute entirely.
### Objects and Arrays (Svelte 5.16+)
**Objects** - truthy keys are added:
```svelte
...
```
**Arrays** - truthy values are combined:
```svelte
...
```
**Combining with props**:
```svelte
```
Usage:
```svelte
```
### TypeScript Support
```svelte
...
```
## Class Directive (Legacy)
```svelte
...
```
Shorthand when name matches value:
```svelte
...
```
> Note: Prefer using the class attribute with objects/arrays over class: directives in Svelte 5.16+.
## docs/svelte/04-styling/01-scoped-styles.md
# Scoped Styles in Svelte
## Basic Scoping
Styles in `
```
## Specificity
- Scoped selectors get a specificity boost of 0-1-0 from the added class
- Component styles override global styles with the same selector, even if loaded later
- Multiple occurrences of the scoping class after the first use `:where(.svelte-xyz123)` to avoid further specificity increases
## Scoped Keyframes
Keyframe animations are also scoped to the component:
```svelte
```
## docs/svelte/04-styling/02-global-styles.md
# Global Styles in Svelte
## :global(...)
Apply styles globally to specific selectors:
```svelte
```
For global keyframes, prepend names with `-global-`:
```svelte
```
## :global
Apply styles to multiple selectors globally using a block:
```svelte
```
## docs/svelte/04-styling/03-custom-properties.md
# Custom Properties
Pass CSS custom properties to components:
```svelte
```
This desugars to:
```svelte
```
For SVG elements, it uses `` instead:
```svelte
```
Inside components, access these properties with fallbacks:
```svelte
```
Custom properties can also be defined on parent elements (like `:root`) to apply globally.
> Note: The wrapper element won't affect layout but may impact CSS selectors using the `>` combinator.
## docs/svelte/04-styling/04-nested-style-elements.md
# Nested `
```
## docs/svelte/05-special-elements/01-svelte-boundary.md
# Svelte 5 Error Boundaries
## ``
```svelte
...
```
Error boundaries isolate errors in components to prevent app-wide crashes and enable recovery.
- Catches errors during rendering, updating, and `$effect` execution
- Does NOT catch errors in event handlers, timeouts, or async operations
## Properties
### `failed`
Renders fallback UI with error details and reset function:
```svelte
{#snippet failed(error, reset)}
{/snippet}
```
### `onerror`
Handles errors programmatically:
```svelte
report(e)}>
...
```
Managing error state outside the boundary:
```svelte
{#if error}
{/if}
```
Errors in `onerror` propagate to parent boundaries.
## docs/svelte/05-special-elements/02-svelte-window.md
# Svelte Window Element
## ``
Adds event listeners to the `window` object without manual cleanup.
```svelte
```
Must appear at the top level of your component.
### Event Example
```svelte
```
### Bindable Properties
```svelte
```
**Read/Write Properties:**
- `scrollX`
- `scrollY`
**Readonly Properties:**
- `innerWidth`
- `innerHeight`
- `outerWidth`
- `outerHeight`
- `online` (alias for `window.navigator.onLine`)
- `devicePixelRatio`
> **Note:** Page won't scroll to initial bound values of `scrollX`/`scrollY`. For initial scrolling, use `scrollTo()` in an `$effect`.
## docs/svelte/05-special-elements/03-svelte-document.md
#
```svelte
```
Allows adding event listeners and actions to the `document` object.
- Must appear only at the top level of your component
- Never place inside blocks or elements
- Useful for events that don't fire on `window` (e.g., `visibilitychange`)
```svelte
```
## Bindable Properties (readonly)
- `activeElement`
- `fullscreenElement`
- `pointerLockElement`
- `visibilityState`
## docs/svelte/05-special-elements/04-svelte-body.md
#
```svelte
```
Allows adding event listeners to `document.body` for events that don't fire on `window` (like `mouseenter`/`mouseleave`). Also supports [actions](use).
**Rules:**
- Must appear only at top level of component
- Cannot be inside blocks or elements
**Example:**
```svelte
```
## 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.
**Rules:**
- Must appear only at top level of component
- Cannot be inside blocks or elements
**Example:**
```svelte
Hello world!
```
## docs/svelte/05-special-elements/06-svelte-element.md
#
```svelte
```
Renders an element that's unknown at author time (e.g., from a CMS).
## Usage
```svelte
Content inside the dynamic element
```
## Key Points
- Only `bind:this` binding is supported
- If `this` is nullish, nothing renders
- If `this` is a void element (e.g., `br`) with children, a runtime error occurs in dev mode
```svelte
This text cannot appear inside an hr element
```
- Specify namespace explicitly when needed:
```svelte
```
- `this` must be a valid DOM element tag (`#text` or `svelte:head` won't work)
## docs/svelte/05-special-elements/07-svelte-options.md
# ``
```svelte
```
## Available Options
- `runes={true|false}` - Forces component into runes or legacy mode
- `namespace="html|svg|mathml"` - Sets component namespace (default: "html")
- `customElement={...}` - Options for custom element compilation
- `css="injected"` - Injects styles inline
```svelte
```
> Note: `immutable`, `accessors` options are deprecated in Svelte 5 and non-functional in runes mode.
## docs/svelte/06-runtime/01-stores.md
# Svelte Stores
## Overview
A store is an object that allows reactive access to a value via a store contract. Access store values in components with the `$` prefix.
```svelte
```
## When to Use Stores
In Svelte 5, runes are preferred for most use cases:
```ts
/// file: state.svelte.js
export const userState = $state({
name: 'name',
/* ... */
});
```
```svelte
User name: {userState.name}
```
Use stores for complex async data streams or when manual control over updates is needed.
## svelte/store API
### `writable`
Creates a store with values that can be set externally.
```js
import { writable } from 'svelte/store';
const count = writable(0);
count.subscribe((value) => {
console.log(value);
}); // logs '0'
count.set(1); // logs '1'
count.update((n) => n + 1); // logs '2'
```
With start/stop functions:
```js
import { writable } from 'svelte/store';
const count = writable(0, () => {
console.log('got a subscriber');
return () => console.log('no more subscribers');
});
count.set(1); // does nothing
const unsubscribe = count.subscribe((value) => {
console.log(value);
}); // logs 'got a subscriber', then '1'
unsubscribe(); // logs 'no more subscribers'
```
### `readable`
Creates a store whose value cannot be set externally.
```ts
import { readable } from 'svelte/store';
const time = readable(new Date(), (set) => {
set(new Date());
const interval = setInterval(() => {
set(new Date());
}, 1000);
return () => clearInterval(interval);
});
const ticktock = readable('tick', (set, update) => {
const interval = setInterval(() => {
update((sound) => (sound === 'tick' ? 'tock' : 'tick'));
}, 1000);
return () => clearInterval(interval);
});
```
### `derived`
Derives a store from one or more other stores.
```ts
import { derived } from 'svelte/store';
const doubled = derived(a, ($a) => $a * 2);
```
Asynchronous derivation:
```ts
import { derived } from 'svelte/store';
const delayed = derived(
a,
($a, set) => {
setTimeout(() => set($a), 1000);
},
2000
);
const delayedIncrement = derived(a, ($a, set, update) => {
set($a);
setTimeout(() => update((x) => x + 1), 1000);
});
```
With cleanup function:
```ts
import { derived } from 'svelte/store';
const tick = derived(
frequency,
($frequency, set) => {
const interval = setInterval(() => {
set(Date.now());
}, 1000 / $frequency);
return () => {
clearInterval(interval);
};
},
2000
);
```
Multiple source stores:
```ts
import { derived } from 'svelte/store';
const summed = derived([a, b], ([$a, $b]) => $a + $b);
const delayed = derived([a, b], ([$a, $b], set) => {
setTimeout(() => set($a + $b), 1000);
});
```
### `readonly`
Makes a store readonly.
```js
import { readonly, writable } from 'svelte/store';
const writableStore = writable(1);
const readableStore = readonly(writableStore);
readableStore.subscribe(console.log);
writableStore.set(2); // console: 2
// readableStore.set(2); // ERROR
```
### `get`
Retrieves the current value of a store without subscribing.
```ts
import { get } from 'svelte/store';
const value = get(store);
```
## Store Contract
A valid store must:
1. Have a `.subscribe` method that accepts a subscription function
2. Call the subscription function immediately with the current value
3. Return an unsubscribe function
4. Optionally have a `.set` method (for writable stores)
## docs/svelte/06-runtime/02-context.md
# Context
Context allows components to access values from parent components without prop-drilling.
## Basic Usage
```svelte
```
```svelte
{message}, inside Child.svelte
```
Usage:
```svelte
```
Available functions: `setContext`, `getContext`, `hasContext`, `getAllContexts`
## Context with State
```svelte
```
โ ๏ธ Update properties directly rather than reassigning the object:
```svelte
```
## Type-safe Context
```js
/// file: context.js
// @filename: ambient.d.ts
interface User {}
// @filename: index.js
import { getContext, setContext } from 'svelte';
const key = {};
/** @param {User} user */
export function setUserContext(user) {
setContext(key, user);
}
export function getUserContext() {
return /** @type {User} */ (getContext(key));
}
```
## Alternative to Global State
Context is safer than global state for server-side rendering, as it's not shared between requests.
```js
/// file: state.svelte.js
export const myGlobalState = $state({
user: {
// ...
}
// ...
});
```
Using global state during SSR can leak data between users:
```svelte
```
## docs/svelte/06-runtime/03-lifecycle-hooks.md
# Svelte 5 Lifecycle Hooks
## Component Lifecycle
In Svelte 5, components have only two lifecycle phases:
- Creation (mounting)
- Destruction (unmounting)
State updates trigger only the specific effects that depend on that state.
## `onMount`
Runs after component is mounted to DOM. Not executed during SSR.
```svelte
```
> [!NOTE] Cleanup only works when function synchronously returns a value (not with async functions).
## `onDestroy`
Runs before component unmounts. Only lifecycle hook that runs during SSR.
```svelte
```
## `tick`
Returns promise that resolves after pending state changes are applied.
```svelte
```
## Deprecated: `beforeUpdate` / `afterUpdate`
Shimmed for backward compatibility but not available in components using runes.
- Use `$effect.pre` instead of `beforeUpdate`
- Use `$effect` instead of `afterUpdate`
### Chat Window Example
```svelte
{#each messages as message}
{message}
{/each}
```
## docs/svelte/06-runtime/04-imperative-component-api.md
# Imperative Component API
## `mount`
Creates and mounts a component to a target element:
```js
import { mount } from 'svelte';
import App from './App.svelte';
const app = mount(App, {
target: document.querySelector('#app'),
props: { some: 'property' }
});
```
**Note**: Effects (including `onMount` callbacks and action functions) don't run during `mount`. Use `flushSync()` to force pending effects to run.
## `unmount`
Removes a previously mounted component:
```js
import { mount, unmount } from 'svelte';
import App from './App.svelte';
const app = mount(App, { target: document.body });
// later
unmount(app, { outro: true });
```
Returns a `Promise` that resolves after transitions complete (if `outro: true`) or immediately otherwise.
## `render`
Server-side only. Returns HTML for server rendering:
```js
import { render } from 'svelte/server';
import App from './App.svelte';
const result = render(App, {
props: { some: 'property' }
});
result.body; // HTML for
result.head; // HTML for
```
## `hydrate`
Reuses SSR-rendered HTML and makes it interactive:
```js
import { hydrate } from 'svelte';
import App from './App.svelte';
const app = hydrate(App, {
target: document.querySelector('#app'),
props: { some: 'property' }
});
```
Like `mount`, effects don't run during `hydrate` - use `flushSync()` afterward if needed.
## docs/svelte/07-misc/02-testing.md
# Svelte Testing Guide
## Unit and Integration Testing with Vitest
### Setup
```bash
npm install -D vitest
```
Configure Vite:
```js
// vite.config.js
import { defineConfig } from'vitest/config';
export default defineConfig({
// Tell Vitest to use browser entry points
resolve: process.env.VITEST
? { conditions: ['browser'] }
: undefined
});
```
### Testing JavaScript Functions
```js
// multiplier.svelte.test.js
import { flushSync } from 'svelte';
import { expect, test } from 'vitest';
import { multiplier } from './multiplier.svelte.js';
test('Multiplier', () => {
let double = multiplier(0, 2);
expect(double.value).toEqual(0);
double.set(5);
expect(double.value).toEqual(10);
});
```
### Using Runes in Tests
Filename must include `.svelte`:
```js
// multiplier.svelte.test.js
import { flushSync } from 'svelte';
import { expect, test } from 'vitest';
import { multiplier } from './multiplier.svelte.js';
test('Multiplier', () => {
let count = $state(0);
let double = multiplier(() => count, 2);
expect(double.value).toEqual(0);
count = 5;
expect(double.value).toEqual(10);
});
```
### Testing Effects
Wrap in `$effect.root` and use `flushSync()`:
```js
// logger.svelte.test.js
import { flushSync } from 'svelte';
import { expect, test } from 'vitest';
import { logger } from './logger.svelte.js';
test('Effect', () => {
const cleanup = $effect.root(() => {
let count = $state(0);
let log = logger(() => count);
flushSync();
expect(log.value).toEqual([0]);
count = 1;
flushSync();
expect(log.value).toEqual([0, 1]);
});
cleanup();
});
```
## Component Testing
### Setup
```bash
npm install -D jsdom
```
Update Vite config:
```js
// vite.config.js
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
environment: 'jsdom'
},
resolve: process.env.VITEST
? { conditions: ['browser'] }
: undefined
});
```
### Basic Component Test
```js
// component.test.js
import { flushSync, mount, unmount } from 'svelte';
import { expect, test } from 'vitest';
import Component from './Component.svelte';
test('Component', () => {
const component = mount(Component, {
target: document.body,
props: { initial: 0 }
});
expect(document.body.innerHTML).toBe('');
document.body.querySelector('button').click();
flushSync();
expect(document.body.innerHTML).toBe('');
unmount(component);
});
```
### Using Testing Library
```js
// component.test.js
import { render, screen } from '@testing-library/svelte';
import userEvent from '@testing-library/user-event';
import { expect, test } from 'vitest';
import Component from './Component.svelte';
test('Component', async () => {
const user = userEvent.setup();
render(Component);
const button = screen.getByRole('button');
expect(button).toHaveTextContent(0);
await user.click(button);
expect(button).toHaveTextContent(1);
});
```
## E2E Testing with Playwright
### Setup
Install via VS Code extension or:
```bash
npm init playwright
```
Configure Playwright:
```js
// playwright.config.js
const config = {
webServer: {
command: 'npm run build && npm run preview',
port: 4173
},
testDir: 'tests',
testMatch: /(.+\.)?(test|spec)\.[jt]s/
};
export default config;
```
### Writing Tests
```js
// tests/hello-world.spec.js
import { expect, test } from '@playwright/test';
test('home page has expected h1', async ({ page }) => {
await page.goto('/');
await expect(page.locator('h1')).toBeVisible();
});
```
## docs/svelte/07-misc/03-typescript.md
# Svelte 5 TypeScript Guide
## Basic Usage
Add `lang="ts"` to script tags:
```svelte
```
Only type-only features are supported without preprocessors. Unsupported features:
- enums
- access modifiers with initializers
- non-ECMAScript standard features
## Setup
### SvelteKit/Vite (Recommended)
```ts
// svelte.config.js
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
const config = {
preprocess: vitePreprocess()
};
export default config;
```
For non-type-only features:
```ts
// svelte.config.js
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
const config = {
preprocess: vitePreprocess({ script: true })
};
export default config;
```
### tsconfig.json Requirements
- `target`: at least `ES2022` or `ES2015` with `useDefineForClassFields`
- `verbatimModuleSyntax`: `true`
- `isolatedModules`: `true`
## Typing Components
### $props
```svelte
```
### Generic Components
```svelte
```
### Wrapper Components
```svelte
```
For elements without dedicated types:
```svelte
```
## Typing Runes
### $state
```ts
let count: number = $state(0);
```
For undefined initial values:
```ts
class Counter {
count = $state() as number;
constructor(initial: number) {
this.count = initial;
}
}
```
## Component Types
### Component Type
```svelte
```
### ComponentProps
```ts
import type { Component, ComponentProps } from 'svelte';
import MyComponent from './MyComponent.svelte';
function withProps>(
component: TComponent,
props: ComponentProps
) {}
withProps(MyComponent, { foo: 'bar' });
```
### Component Instance
```svelte
```
## Extending DOM Types
For custom elements or attributes:
```ts
// additional-svelte-typings.d.ts
declare namespace svelteHTML {
interface IntrinsicElements {
'my-custom-element': { someattribute: string; 'on:event': (e: CustomEvent) => void };
}
interface HTMLAttributes {
onbeforeinstallprompt?: (event: any) => any;
mycustomattribute?: any;
}
}
```
Or by augmenting modules:
```ts
// additional-svelte-typings.d.ts
import { HTMLButtonAttributes } from 'svelte/elements';
declare module 'svelte/elements' {
export interface SvelteHTMLElements {
'custom-button': HTMLButtonAttributes;
}
export interface HTMLButtonAttributes {
veryexperimentalattribute?: string;
}
}
export {};
```
Instructions for LLMs: Always use Svelte 5 runes and Svelte 5 syntax. Runes do not need to be imported, they are globals. $state() runes are always declared using `let`, never with `const`. When passing a function to $derived, you must always use $derived.by(() => ...). Error boundaries can only catch errors during component rendering and at the top level of an $effect inside the error boundary. Error boundaries do not catch errors in onclick or other event handlers.