----
url: https://svelte.dev/docs/svelte/legacy-$$slots
----

[Skip to main content](#main)

In runes mode, we know which [snippets](snippet) were provided to a component, as they’re just normal props.

In legacy mode, the way to know if content was provided for a given slot is with the `$$slots` object, whose keys are the names of the slots passed into the component by the parent.

Card

```
<div>
	<slot name="title" />
	{#if $$slots.description}
		<!-- This <hr> and slot will render only if `slot="description"` is provided. -->
		<hr />
		<slot name="description" />
	{/if}
</div>
```

App

```
<Card>
	<h1 slot="title">Blog Post Title</h1>
	<!-- No slot named "description" was provided so the optional slot will not be rendered. -->
</Card>
```

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/99-legacy/21-legacy-$$slots.md) [llms.txt](/docs/svelte/legacy-$$slots/llms.txt)

previous next

[\<slot>](/docs/svelte/legacy-slots) [\<svelte:fragment>](/docs/svelte/legacy-svelte-fragment)

----
url: https://svelte.dev/docs/svelte/svelte-legacy
----

[Skip to main content](#main)

This module provides various functions for use during the migration, since some features can’t be replaced one to one with new features. All imports are marked as deprecated and should be migrated away from over time.

```
import {
	asClassComponent(alias) function asClassComponent<Props extends Record<string, any>, Exports extends Record<string, any>, Events extends Record<string, any>, Slots extends Record<string, any>>(component: SvelteComponent<Props, Events, Slots> | Component<Props>): ComponentType<SvelteComponent<Props, Events, Slots> & Exports>
import asClassComponent

Takes the component function and returns a Svelte 4 compatible component constructor.




Use this only as a temporary solution to migrate your imperative component code to Svelte 5.


reference,
	createBubbler(alias) function createBubbler(): (type: string) => (event: Event) => boolean
import createBubbler

Function to create a bubble function that mimic the behavior of on:click without handler available in svelte 4.




Use this only as a temporary solution to migrate your automatically delegated events in Svelte 5.


reference,
	createClassComponent(alias) function createClassComponent<Props extends Record<string, any>, Exports extends Record<string, any>, Events extends Record<string, any>, Slots extends Record<string, any>>(options: ComponentConstructorOptions<Props> & {
    component: ComponentType<SvelteComponent<Props, Events, Slots>> | Component<Props>;
}): SvelteComponent<Props, Events, Slots> & Exports
import createClassComponent

Takes the same options as a Svelte 4 component and the component function and returns a Svelte 4 compatible component.




Use this only as a temporary solution to migrate your imperative component code to Svelte 5.


reference,
	handlers(alias) function handlers(...handlers: EventListener[]): EventListener
import handlers

Function to mimic the multiple listeners available in svelte 4


reference,
	nonpassive(alias) function nonpassive(node: HTMLElement, [event, handler]: [event: string, handler: () => EventListener]): void
import nonpassive

Substitute for the nonpassive event modifier, implemented as an action


reference,
	once(alias) function once(fn: (event: Event, ...args: Array<unknown>) => void): (event: Event, ...args: unknown[]) => void
import once

Substitute for the once event modifier


reference,
	passive(alias) function passive(node: HTMLElement, [event, handler]: [event: string, handler: () => EventListener]): void
import passive

Substitute for the passive event modifier, implemented as an action


reference,
	preventDefault(alias) function preventDefault(fn: (event: Event, ...args: Array<unknown>) => void): (event: Event, ...args: unknown[]) => void
import preventDefault

Substitute for the preventDefault event modifier


reference,
	run(alias) function run(fn: () => void | (() => void)): void
import run

Runs the given function once immediately on the server, and works like $effect.pre on the client.




Use this only as a temporary solution to migrate your component code to Svelte 5.


reference,
	self(alias) function self(fn: (event: Event, ...args: Array<unknown>) => void): (event: Event, ...args: unknown[]) => void
import self

Substitute for the self event modifier


reference,
	stopImmediatePropagation(alias) function stopImmediatePropagation(fn: (event: Event, ...args: Array<unknown>) => void): (event: Event, ...args: unknown[]) => void
import stopImmediatePropagation

Substitute for the stopImmediatePropagation event modifier


reference,
	stopPropagation(alias) function stopPropagation(fn: (event: Event, ...args: Array<unknown>) => void): (event: Event, ...args: unknown[]) => void
import stopPropagation

Substitute for the stopPropagation event modifier


reference,
	trusted(alias) function trusted(fn: (event: Event, ...args: Array<unknown>) => void): (event: Event, ...args: unknown[]) => void
import trusted

Substitute for the trusted event modifier


reference
} from 'svelte/legacy';
```

## asClassComponent[](#asClassComponent)

> Use this only as a temporary solution to migrate your imperative component code to Svelte 5.

Takes the component function and returns a Svelte 4 compatible component constructor.

```
function asClassComponent<
	Props extends Record<string, any>,
	Exports extends Record<string, any>,
	Events extends Record<string, any>,
	Slots extends Record<string, any>
>(
	component:
		| SvelteComponent<Props, Events, Slots>
		| Component<Props>
): ComponentType<
	SvelteComponent<Props, Events, Slots> & Exports
>;
```

## createBubbler[](#createBubbler)

> Use this only as a temporary solution to migrate your automatically delegated events in Svelte 5.

Function to create a `bubble` function that mimic the behavior of `on:click` without handler available in svelte 4.

```
function createBubbler(): (
	type: string
) => (event: Event) => boolean;
```

## createClassComponent[](#createClassComponent)

> Use this only as a temporary solution to migrate your imperative component code to Svelte 5.

Takes the same options as a Svelte 4 component and the component function and returns a Svelte 4 compatible component.

```
function createClassComponent<
	Props extends Record<string, any>,
	Exports extends Record<string, any>,
	Events extends Record<string, any>,
	Slots extends Record<string, any>
>(
	options: ComponentConstructorOptions<Props> & {
		component:
			| ComponentType<SvelteComponent<Props, Events, Slots>>
			| Component<Props>;
	}
): SvelteComponent<Props, Events, Slots> & Exports;
```

## handlers[](#handlers)

Function to mimic the multiple listeners available in svelte 4

```
function handlers(
	...handlers: EventListener[]
): EventListener;
```

## nonpassive[](#nonpassive)

Substitute for the `nonpassive` event modifier, implemented as an action

```
function nonpassive(
	node: HTMLElement,
	[event, handler]: [
		event: string,
		handler: () => EventListener
	]
): void;
```

## once[](#once)

Substitute for the `once` event modifier

```
function once(
	fn: (event: Event, ...args: Array<unknown>) => void
): (event: Event, ...args: unknown[]) => void;
```

## passive[](#passive)

Substitute for the `passive` event modifier, implemented as an action

```
function passive(
	node: HTMLElement,
	[event, handler]: [
		event: string,
		handler: () => EventListener
	]
): void;
```

## preventDefault[](#preventDefault)

Substitute for the `preventDefault` event modifier

```
function preventDefault(
	fn: (event: Event, ...args: Array<unknown>) => void
): (event: Event, ...args: unknown[]) => void;
```

## run[](#run)

> Use this only as a temporary solution to migrate your component code to Svelte 5.

Runs the given function once immediately on the server, and works like `$effect.pre` on the client.

```
function run(fn: () => void | (() => void)): void;
```

## self[](#self)

Substitute for the `self` event modifier

```
function self(
	fn: (event: Event, ...args: Array<unknown>) => void
): (event: Event, ...args: unknown[]) => void;
```

## stopImmediatePropagation[](#stopImmediatePropagation)

Substitute for the `stopImmediatePropagation` event modifier

```
function stopImmediatePropagation(
	fn: (event: Event, ...args: Array<unknown>) => void
): (event: Event, ...args: unknown[]) => void;
```

## stopPropagation[](#stopPropagation)

Substitute for the `stopPropagation` event modifier

```
function stopPropagation(
	fn: (event: Event, ...args: Array<unknown>) => void
): (event: Event, ...args: unknown[]) => void;
```

## trusted[](#trusted)

Substitute for the `trusted` event modifier

```
function trusted(
	fn: (event: Event, ...args: Array<unknown>) => void
): (event: Event, ...args: unknown[]) => void;
```

## LegacyComponentType[](#LegacyComponentType)

Support using the component as both a class and function during the transition period

```
type LegacyComponentType = {
	new (o: ComponentConstructorOptions): SvelteComponent;
	(
		...args: Parameters<Component<Record<string, any>>>
	): ReturnType<
		Component<Record<string, any>, Record<string, any>>
	>;
};
```

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/98-reference/21-svelte-legacy.md) [llms.txt](/docs/svelte/svelte-legacy/llms.txt)

previous next

[svelte/events](/docs/svelte/svelte-events) [svelte/motion](/docs/svelte/svelte-motion)

----
url: https://svelte.dev/docs/svelte/basic-markup
----

[Skip to main content](#main)

Markup inside a Svelte component can be thought of as HTML++.

## Tags[](#Tags)

A lowercase tag, like `<div>`, denotes a regular HTML element. A capitalised tag or a tag that uses dot notation, such as `<Widget>` or `<my.stuff>`, indicates a *component*.

```
<script>
	import Widget from './Widget.svelte';
</script>

<div>
	<Widget />
</div>
```

## Element attributes[](#Element-attributes)

By default, attributes work exactly like their HTML counterparts.

```
<div class="foo">
	<button disabled>can't touch this</button>
</div>
```

As in HTML, values may be unquoted.

```
<input type=checkbox />
```

Attribute values can contain JavaScript expressions.

```
<a href="page/{p}">page {p}</a>
```

Or they can *be* JavaScript expressions.

```
<button disabled={!clickable}>...</button>
```

Boolean attributes are included on the element if their value is [truthy](https://developer.mozilla.org/en-US/docs/Glossary/Truthy) and excluded if it’s [falsy](https://developer.mozilla.org/en-US/docs/Glossary/Falsy).

All other attributes are included unless their value is [nullish](https://developer.mozilla.org/en-US/docs/Glossary/Nullish) (`null` or `undefined`).

```
<input required={false} placeholder="This input field is not required" />
<div title={null}>This div has no title attribute</div>
```

> Quoting a singular expression does not affect how the value is parsed, but in Svelte 6 it will cause the value to be coerced to a string:
>
> ```
> <button disabled="{number !== 42}">...</button>
> ```

When the attribute name and value match (`name={name}`), they can be replaced with `{name}`.

```
<button {disabled}>...</button>
<!-- equivalent to
<button disabled={disabled}>...</button>
-->
```

## Component props[](#Component-props)

By convention, values passed to components are referred to as *properties* or *props* rather than *attributes*, which are a feature of the DOM.

As with elements, `name={name}` can be replaced with the `{name}` shorthand.

```
<Widget foo={bar} answer={42} text="hello" />
```

## Spread attributes[](#Spread-attributes)

*Spread attributes* allow many attributes or properties to be passed to an element or component at once.

An element or component can have multiple spread attributes, interspersed with regular ones. Order matters — if `things.a` exists it will take precedence over `a="b"`, while `c="d"` would take precedence over `things.c`:

```
<Widget a="b" {...things} c="d" />
```

## Events[](#Events)

Listening to DOM events is possible by adding attributes to the element that start with `on`. For example, to listen to the `click` event, add the `onclick` attribute to a button:

```
<button onclick={() => console.log('clicked')}>click me</button>
```

Event attributes are case sensitive. `onclick` listens to the `click` event, `onClick` listens to the `Click` event, which is different. This ensures you can listen to custom events that have uppercase characters in them.

Because events are just attributes, the same rules as for attributes apply:

* you can use the shorthand form: `<button {onclick}>click me</button>`
* you can spread them: `<button {...thisSpreadContainsEventAttributes}>click me</button>`

Timing-wise, event attributes always fire after events from bindings (e.g. `oninput` always fires after an update to `bind:value`). Under the hood, some event handlers are attached directly with `addEventListener`, while others are *delegated*.

When using `ontouchstart` and `ontouchmove` event attributes, the handlers are [passive](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#using_passive_listeners) for better performance. This greatly improves responsiveness by allowing the browser to scroll the document immediately, rather than waiting to see if the event handler calls `event.preventDefault()`.

In the very rare cases that you need to prevent these event defaults, you should use [`on`](svelte-events#on) instead (for example inside an action).

### Event delegation[](#Events-Event-delegation)

To reduce memory footprint and increase performance, Svelte uses a technique called event delegation. This means that for certain events — see the list below — a single event listener at the application root takes responsibility for running any handlers on the event’s path.

There are a few gotchas to be aware of:

* when you manually dispatch an event with a delegated listener, make sure to set the `{ bubbles: true }` option or it won’t reach the application root
* when using `addEventListener` directly, avoid calling `stopPropagation` or the event won’t reach the application root and handlers won’t be invoked. Similarly, handlers added manually inside the application root will run *before* handlers added declaratively deeper in the DOM (with e.g. `onclick={...}`), in both capturing and bubbling phases. For these reasons it’s better to use the `on` function imported from `svelte/events` rather than `addEventListener`, as it will ensure that order is preserved and `stopPropagation` is handled correctly.

The following event handlers are delegated:

* `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[](#Text-expressions)

A JavaScript expression can be included as text by surrounding it with curly braces.

```
{expression}
```

Expressions that are `null` or `undefined` will be omitted; all others are [coerced to strings](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String#string_coercion).

Curly braces can be included in a Svelte template by using their [HTML entity](https://developer.mozilla.org/docs/Glossary/Entity) strings: `&lbrace;`, `&lcub;`, or `&#123;` for `{` and `&rbrace;`, `&rcub;`, or `&#125;` for `}`.

If you’re using a regular expression (`RegExp`) [literal notation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#literal_notation_and_constructor), you’ll need to wrap it in parentheses.

```
<h1>Hello {name}!</h1>
<p>{a} + {b} = {a + b}.</p>

<div>{(/^[A-Za-z ]+$/).test(value) ? x : y}</div>
```

The expression will be stringified and escaped to prevent code injections. If you want to render HTML, use the `{@html}` tag instead.

```
{@html potentiallyUnsafeHtmlString}
```

> Make sure that you either escape the passed string or only populate it with values that are under your control in order to prevent [XSS attacks](https://owasp.org/www-community/attacks/xss/)

## Comments[](#Comments)

You can use HTML comments inside components.

```
<!-- this is a comment! --><h1>Hello world</h1>
```

Comments beginning with `svelte-ignore` disable warnings for the next block of markup. Usually, these are accessibility warnings; make sure that you’re disabling them for a good reason.

```
<!-- svelte-ignore a11y_autofocus -->
<input bind:value={name} autofocus />
```

You can add a special comment starting with `@component` that will show up when hovering over the component name in other files.

````
<!--
@component
- You can use markdown here.
- You can also use code blocks here.
- Usage:
  ```html
  <Main name="Aretha">
  ```
-->
<script>
	let { name } = $props();
</script>

<main>
	<h1>
		Hello, {name}
	</h1>
</main>
````

You can also put JavaScript-style comments within tags between attributes:

```
<div
  // this is a comment!
  data-foo="bar"
>
  foo bar
</div>
```

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/03-template-syntax/01-basic-markup.md) [llms.txt](/docs/svelte/basic-markup/llms.txt)

previous next

[$host](/docs/svelte/$host) [{#if ...}](/docs/svelte/if)

----
url: https://svelte.dev/docs/svelte/@debug
----

[Skip to main content](#main)

The `{@debug ...}` tag offers an alternative to `console.log(...)`. It logs the values of specific variables whenever they change, and pauses code execution if you have devtools open.

```
<script>
	let user = {
		firstname: 'Ada',
		lastname: 'Lovelace'
	};
</script>

{@debug user}

<h1>Hello {user.firstname}!</h1>
```

`{@debug ...}` accepts a comma-separated list of variable names (not arbitrary expressions).

```
<!-- Compiles -->
{@debug user}
{@debug user1, user2, user3}

<!-- WON'T compile -->
{@debug user.firstname}
{@debug myArray[0]}
{@debug !isReady}
{@debug typeof user === 'object'}
```

The `{@debug}` tag without any arguments will insert a `debugger` statement that gets triggered when *any* state changes, as opposed to the specified variables.

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/03-template-syntax/11-@debug.md) [llms.txt](/docs/svelte/@debug/llms.txt)

previous next

[{@const ...}](/docs/svelte/@const) [{let/const ...}](/docs/svelte/declaration-tags)

----
url: https://svelte.dev/docs/svelte/bind/llms.txt
----

````
Data ordinarily flows down, from parent to child. The `bind:` directive allows data to flow the other way, from child to parent.

The general syntax is `bind:property={expression}`, where `expression` is an [_lvalue_](https://press.rebus.community/programmingfundamentals/chapter/lvalue-and-rvalue/) (i.e. a variable or an object property). When the expression is an identifier with the same name as the property, we can omit the expression — in other words these are equivalent:

<!-- prettier-ignore -->
```svelte
<input bind:value={value} />
<input bind:value />
```


Svelte creates an event listener that updates the bound value. If an element already has a listener for the same event, that listener will be fired before the bound value is updated.

Most bindings are _two-way_, meaning that changes to the value will affect the element and vice versa. A few bindings are _readonly_, meaning that changing their value will have no effect on the element.

## Function bindings

You can also use `bind:property={get, set}`, where `get` and `set` are functions, allowing you to perform validation and transformation:

```svelte
<input bind:value={
	() => value,
	(v) => value = v.toLowerCase()}
/>
```

In the case of readonly bindings like [dimension bindings](#Dimensions), the `get` value should be `null`:

```svelte
<div
	bind:clientWidth={null, redraw}
	bind:clientHeight={null, redraw}
>...</div>
```

> [!NOTE]
> Function bindings are available in Svelte 5.9.0 and newer.

## `<input bind:value>`

A `bind:value` directive on an `<input>` element binds the input's `value` property:

<!-- prettier-ignore -->
```svelte
<script>
	let message = $state('hello');
</script>

<input bind:value={message} />
<p>{message}</p>
```

In the case of a numeric input (`type="number"` or `type="range"`), the value will be coerced to a number:

<!-- codeblock:start {"title":"Numeric bindings"} -->
```svelte
<!--- file: App.svelte --->
<script>
	let a = $state(1);
	let b = $state(2);
</script>

<label>
	<input type="number" bind:value={a} min="0" max="10" />
	<input type="range" bind:value={a} min="0" max="10" />
</label>

<label>
	<input type="number" bind:value={b} min="0" max="10" />
	<input type="range" bind:value={b} min="0" max="10" />
</label>

<p>{a} + {b} = {a + b}</p>
```
<!-- codeblock:end -->

If the input is empty or invalid (in the case of `type="number"`), the value is `undefined`.

Since 5.6.0, if an `<input>` has a `defaultValue` and is part of a form, it will revert to that value instead of the empty string when the form is reset. Note that for the initial render the value of the binding takes precedence unless it is `null` or `undefined`.

```svelte
<script>
	let value = $state('');
</script>

<form>
	<input bind:value defaultValue="not the empty string">
	<input type="reset" value="Reset">
</form>
```

> [!NOTE]
> Use reset buttons sparingly, and ensure that users won't accidentally click them while trying to submit the form.

## `<input bind:checked>`

Checkbox inputs can be bound with `bind:checked`:

```svelte
<label>
	<input type="checkbox" bind:checked={accepted} />
	Accept terms and conditions
</label>
```

Since 5.6.0, if an `<input>` has a `defaultChecked` attribute and is part of a form, it will revert to that value instead of `false` when the form is reset. Note that for the initial render the value of the binding takes precedence unless it is `null` or `undefined`.

```svelte
<script>
	let checked = $state(true);
</script>

<form>
	<input type="checkbox" bind:checked defaultChecked={true}>
	<input type="reset" value="Reset">
</form>
```

> [!NOTE] Use `bind:group` for radio inputs instead of `bind:checked`.

## `<input bind:indeterminate>`

Checkboxes can be in an [indeterminate](https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/indeterminate) state, independently of whether they are checked or unchecked:

```svelte
<script>
	let checked = $state(false);
	let indeterminate = $state(true);
</script>

<form>
	<input type="checkbox" bind:checked bind:indeterminate>

	{#if indeterminate}
		waiting...
	{:else if checked}
		checked
	{:else}
		unchecked
	{/if}
</form>
```

## `<input bind:group>`

Inputs that work together can use `bind:group`:

<!-- codeblock:start {"title":"bind:group"} -->
```svelte
<!--- file: App.svelte --->
<script>
	let tortilla = $state('Plain');

	/** @type {string[]} */
	let fillings = $state([]);
</script>

<h1>Customize your burrito</h1>

<!-- grouped radio inputs are mutually exclusive -->
<label><input type="radio" bind:group={tortilla} value="Plain" /> Plain</label>
<label><input type="radio" bind:group={tortilla} value="Whole wheat" /> Whole wheat</label>
<label><input type="radio" bind:group={tortilla} value="Spinach" /> Spinach</label>

<!-- grouped checkbox inputs populate an array -->
<label><input type="checkbox" bind:group={fillings} value="Rice" /> Rice</label>
<label><input type="checkbox" bind:group={fillings} value="Beans" /> Beans</label>
<label><input type="checkbox" bind:group={fillings} value="Cheese" /> Cheese</label>
<label><input type="checkbox" bind:group={fillings} value="Guac (extra)" /> Guac (extra)</label>

<p>Tortilla: {tortilla}</p>
<p>Fillings: {fillings.join(', ') || 'None'}</p>

<style>
	label {
		display: block;
	}
</style>
```
<!-- codeblock:end -->

> [!NOTE] `bind:group` only works if the inputs are in the same Svelte component.

## `<input bind:files>`

On `<input>` elements with `type="file"`, you can use `bind:files` to get the [`FileList` of selected files](https://developer.mozilla.org/en-US/docs/Web/API/FileList). When you want to update the files programmatically, you always need to use a `FileList` object. Currently `FileList` objects cannot be constructed directly, so you need to create a new [`DataTransfer`](https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer) object and get `files` from there.

```svelte
<script>
	let files = $state();

	function clear() {
		files = new DataTransfer().files; // null or undefined does not work
	}
</script>

<label for="avatar">Upload a picture:</label>
<input accept="image/png, image/jpeg" bind:files id="avatar" name="avatar" type="file" />
<button onclick={clear}>clear</button>
```

`FileList` objects also cannot be modified, so if you want to e.g. delete a single file from the list, you need to create a new `DataTransfer` object and add the files you want to keep.

> [!NOTE] `DataTransfer` may not be available in server-side JS runtimes. Leaving the state that is bound to `files` uninitialized prevents potential errors if components are server-side rendered.

## `<select bind:value>`

A `<select>` value binding corresponds to the `value` property on the selected `<option>`, which can be any value (not just strings, as is normally the case in the DOM).

```svelte
<select bind:value={selected}>
	<option value={a}>a</option>
	<option value={b}>b</option>
	<option value={c}>c</option>
</select>
```

A `<select multiple>` element behaves similarly to a checkbox group. The bound variable is an array with an entry corresponding to the `value` property of each selected `<option>`.

```svelte
<select multiple bind:value={fillings}>
	<option value="Rice">Rice</option>
	<option value="Beans">Beans</option>
	<option value="Cheese">Cheese</option>
	<option value="Guac (extra)">Guac (extra)</option>
</select>
```

When the value of an `<option>` matches its text content, the attribute can be omitted.

```svelte
<select multiple bind:value={fillings}>
	<option>Rice</option>
	<option>Beans</option>
	<option>Cheese</option>
	<option>Guac (extra)</option>
</select>
```

You can give the `<select>` a default value by adding a `selected` attribute to the `<option>` (or options, in the case of `<select multiple>`) that should be initially selected. If the `<select>` is part of a form, it will revert to that selection when the form is reset. Note that for the initial render the value of the binding takes precedence if it's not `undefined`.

```svelte
<select bind:value={selected}>
	<option value={a}>a</option>
	<option value={b} selected>b</option>
	<option value={c}>c</option>
</select>
```

Since 5.57.0, if a `<select>` has a `defaultValue` and is part of a form, it will revert to that value instead of the empty string when the form is reset. Note that for the initial render the value of the binding takes precedence unless it is `null` or `undefined`.

```svelte
<form>
	<select bind:value defaultValue="b">
		<option>a</option>
		<option>b</option>
		<option>c</option>
	</select>
	<input type="reset" value="Reset">
</form>
```

## `<audio>`

`<audio>` elements have their own set of bindings — five two-way ones...

- [`currentTime`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/currentTime)
- [`playbackRate`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/playbackRate)
- [`paused`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/paused)
- [`volume`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/volume)
- [`muted`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/muted)

...and six readonly ones:

- [`duration`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/duration)
- [`buffered`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/buffered)
- [`seekable`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/seekable)
- [`seeking`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/seeking_event)
- [`ended`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/ended)
- [`readyState`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/readyState)
- [`played`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/played)

```svelte
<audio src={clip} bind:duration bind:currentTime bind:paused></audio>
```

## `<video>`

`<video>` elements have all the same bindings as [`<audio>`](#audio) elements, plus readonly [`videoWidth`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLVideoElement/videoWidth) and [`videoHeight`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLVideoElement/videoHeight) bindings.

## `<img>`

`<img>` elements have two readonly bindings:

- [`naturalWidth`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/naturalWidth)
- [`naturalHeight`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/naturalHeight)

## `<details bind:open>`

`<details>` elements support binding to the `open` property.

```svelte
<details bind:open={isOpen}>
	<summary>How do you comfort a JavaScript bug?</summary>
	<p>You console it.</p>
</details>
```

## `window` and `document`

To bind to properties of `window` and `document`, see [`<svelte:window>`](svelte-window) and [`<svelte:document>`](svelte-document).

## Contenteditable bindings

Elements with the `contenteditable` attribute support the following bindings:

- [`innerHTML`](https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML)
- [`innerText`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/innerText)
- [`textContent`](https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent)

> [!NOTE] There are [subtle differences between `innerText` and `textContent`](https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent#differences_from_innertext).

<!-- for some reason puts the comment and html on same line -->
<!-- prettier-ignore -->
```svelte
<div contenteditable="true" bind:innerHTML={html}></div>
```

## Dimensions

All visible elements have the following readonly bindings, measured with a `ResizeObserver`:

- [`clientWidth`](https://developer.mozilla.org/en-US/docs/Web/API/Element/clientWidth)
- [`clientHeight`](https://developer.mozilla.org/en-US/docs/Web/API/Element/clientHeight)
- [`offsetWidth`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetWidth)
- [`offsetHeight`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetHeight)
- [`contentRect`](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserverEntry/contentRect)
- [`contentBoxSize`](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserverEntry/contentBoxSize)
- [`borderBoxSize`](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserverEntry/borderBoxSize)
- [`devicePixelContentBoxSize`](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserverEntry/devicePixelContentBoxSize)

```svelte
<div bind:offsetWidth={width} bind:offsetHeight={height}>
	<Chart {width} {height} />
</div>
```

> [!NOTE] `display: inline` elements do not have a width or height (except for elements with 'intrinsic' dimensions, like `<img>` and `<canvas>`), and cannot be observed with a `ResizeObserver`. You will need to change the `display` style of these elements to something else, such as `inline-block`. Note that CSS transformations do not trigger `ResizeObserver` callbacks.

## bind:this

```svelte
<!--- copy: false --->
bind:this={dom_node}
```

To get a reference to a DOM node, use `bind:this`. The value will be `undefined` until the component is mounted — in other words, you should read it inside an effect or an event handler, but not during component initialisation:

```svelte
<script>
	/** @type {HTMLCanvasElement} */
	let canvas;

	$effect(() => {
		const ctx = canvas.getContext('2d');
		drawStuff(ctx);
	});
</script>

<canvas bind:this={canvas}></canvas>
```

Components also support `bind:this`, allowing you to interact with component instances programmatically.

```svelte
<!--- file: App.svelte --->
<ShoppingCart bind:this={cart} />

<button onclick={() => cart.empty()}> Empty shopping cart </button>
```

```svelte
<!--- file: ShoppingCart.svelte --->
<script>
	// All instance exports are available on the instance object
	export function empty() {
		// ...
	}
</script>
```

> [!NOTE] In case of using [the function bindings](#Function-bindings), the getter is required to ensure that the correct value is nullified on component or element destruction.

## bind:_property_ for components

```svelte
bind:property={variable}
```

You can bind to component props using the same syntax as for elements.

```svelte
<Keypad bind:value={pin} />
```

While Svelte props are reactive without binding, that reactivity only flows downward into the component by default. Using `bind:property` allows changes to the property from within the component to flow back up out of the component.

To mark a property as bindable, use the [`$bindable`]($bindable) rune:

```svelte
<script>
	let { readonlyProperty, bindableProperty = $bindable() } = $props();
</script>
```

Declaring a property as bindable means it _can_ be used using `bind:`, not that it _must_ be used using `bind:`.

Bindable properties can have a fallback value:

```svelte
<script>
	let { bindableProperty = $bindable('fallback value') } = $props();
</script>
```

This fallback value _only_ applies when the property is _not_ bound. When the property is bound and a fallback value is present, the parent is expected to provide a value other than `undefined`, else a runtime error is thrown. This prevents hard-to-reason-about situations where it's unclear which value should apply.
````

----
url: https://svelte.dev/docs/svelte/animate/llms.txt
----

````
An animation is triggered when the contents of a [keyed each block](each#Keyed-each-blocks) are re-ordered. Animations do not run when an element is added or removed, only when the index of an existing data item within the each block changes. Animate directives must be on an element that is an _immediate_ child of a keyed each block.

Animations can be used with Svelte's [built-in animation functions](svelte-animate) or [custom animation functions](#Custom-animation-functions).

```svelte
<!-- When `list` is reordered the animation will run -->
{#each list as item, index (item)}
	<li animate:flip>{item}</li>
{/each}
```

## Animation Parameters

As with actions and transitions, animations can have parameters.

(The double `{{curlies}}` aren't a special syntax; this is an object literal inside an expression tag.)

```svelte
{#each list as item, index (item)}
	<li animate:flip={{ delay: 500 }}>{item}</li>
{/each}
```

## Custom animation functions

```js
/// copy: false
// @noErrors
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
}
```

Animations can use custom functions that provide the `node`, an `animation` object and any `parameters` as arguments. The `animation` parameter is an object containing `from` and `to` properties each containing a [DOMRect](https://developer.mozilla.org/en-US/docs/Web/API/DOMRect#Properties) describing the geometry of the element in its `start` and `end` positions. The `from` property is the DOMRect of the element in its starting position, and the `to` property is the DOMRect of the element in its final position after the list has been reordered and the DOM updated.

If the returned object has a `css` method, Svelte will create a [web animation](https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API) that plays on the element.

The `t` argument passed to `css` is a value that goes from `0` and `1` after the `easing` function has been applied. The `u` argument is equal to `1 - t`.

The function is called repeatedly _before_ the animation begins, with different `t` and `u` arguments.

<!-- TODO: Types -->

```svelte
<!--- file: App.svelte --->
<script>
	import { cubicOut } from 'svelte/easing';

	/**
	 * @param {HTMLElement} node
	 * @param {{ from: DOMRect; to: DOMRect }} states
	 * @param {any} params
	 */
	function whizz(node, { from, to }, params) {
		const dx = from.left - to.left;
		const dy = from.top - to.top;

		const d = Math.sqrt(dx * dx + dy * dy);

		return {
			delay: 0,
			duration: Math.sqrt(d) * 120,
			easing: cubicOut,
			css: (t, u) => `transform: translate(${u * dx}px, ${u * dy}px) rotate(${t * 360}deg);`
		};
	}
</script>

{#each list as item, index (item)}
	<div animate:whizz>{item}</div>
{/each}
```

A custom animation function can also return a `tick` function, which is called _during_ the animation with the same `t` and `u` arguments.

> [!NOTE] If it's possible to use `css` instead of `tick`, do so — web animations can run off the main thread, preventing jank on slower devices.

```svelte
<!--- file: App.svelte --->
<script>
	import { cubicOut } from 'svelte/easing';

	/**
	 * @param {HTMLElement} node
	 * @param {{ from: DOMRect; to: DOMRect }} states
	 * @param {any} params
	 */
	function whizz(node, { from, to }, params) {
		const dx = from.left - to.left;
		const dy = from.top - to.top;

		const d = Math.sqrt(dx * dx + dy * dy);

		return {
			delay: 0,
			duration: Math.sqrt(d) * 120,
			easing: cubicOut,
			tick: (t, u) => Object.assign(node.style, { color: t > 0.5 ? 'Pink' : 'Blue' })
		};
	}
</script>

{#each list as item, index (item)}
	<div animate:whizz>{item}</div>
{/each}
```
````

----
url: https://svelte.dev/docs/svelte/if/llms.txt
----

````
```svelte
<!--- copy: false  --->
{#if expression}...{/if}
```

```svelte
<!--- copy: false  --->
{#if expression}...{:else if expression}...{/if}
```

```svelte
<!--- copy: false  --->
{#if expression}...{:else}...{/if}
```

Content that is conditionally rendered can be wrapped in an if block.

```svelte
{#if answer === 42}
	<p>what was the question?</p>
{/if}
```

Additional conditions can be added with `{:else if expression}`, optionally ending in an `{:else}` clause.

```svelte
{#if porridge.temperature > 100}
	<p>too hot!</p>
{:else if 80 > porridge.temperature}
	<p>too cold!</p>
{:else}
	<p>just right!</p>
{/if}
```

(Blocks don't have to wrap elements, they can also wrap text within elements.)
````

----
url: https://svelte.dev/docs/svelte/stores/llms.txt
----

````
<!-- - how to use
- how to write
- TODO should the details for the store methods belong to the reference section? -->

A _store_ is an object that allows reactive access to a value via a simple _store contract_. The [`svelte/store` module](../svelte-store) contains minimal store implementations which fulfil this contract.

Any time you have a reference to a store, you can access its value inside a component by prefixing it with the `$` character. This causes Svelte to declare the prefixed variable, subscribe to the store at component initialisation and unsubscribe when appropriate.

Assignments to `$`-prefixed variables require that the variable be a writable store, and will result in a call to the store's `.set` method.

Note that the store must be declared at the top level of the component — not inside an `if` block or a function, for example.

Local variables (that do not represent store values) must _not_ have a `$` prefix.

```svelte
<script>
	import { writable } from 'svelte/store';

	const count = writable(0);
	console.log($count); // logs 0

	count.set(1);
	console.log($count); // logs 1

	$count = 2;
	console.log($count); // logs 2
</script>
```

## When to use stores

Prior to Svelte 5, stores were the go-to solution for creating cross-component reactive states or extracting logic. With runes, these use cases have greatly diminished.

- when extracting logic, it's better to take advantage of runes' universal reactivity: You can use runes outside the top level of components and even place them into JavaScript or TypeScript files (using a `.svelte.js` or `.svelte.ts` file ending)
- when creating shared state, you can create a `$state` object containing the values you need and then manipulate said state

```ts
/// file: state.svelte.js
export const userState = $state({
	name: 'name',
	/* ... */
});
```

```svelte
<!--- file: App.svelte --->
<script>
	import { userState } from './state.svelte.js';
</script>

<p>User name: {userState.name}</p>
<button onclick={() => {
	userState.name = 'new name';
}}>
	change name
</button>
```

Stores are still a good solution when you have complex asynchronous data streams or it's important to have more manual control over updating values or listening to changes. If you're familiar with RxJs and want to reuse that knowledge, the `$` also comes in handy for you.

## svelte/store

The `svelte/store` module contains a minimal store implementation which fulfil the store contract. It provides methods for creating stores that you can update from the outside, stores you can only update from the inside, and for combining and deriving stores.

### `writable`

Function that creates a store which has values that can be set from 'outside' components. It gets created as an object with additional `set` and `update` methods.

`set` is a method that takes one argument which is the value to be set. The store value gets set to the value of the argument if the store value is not already equal to it.

`update` is a method that takes one argument which is a callback. The callback takes the existing store value as its argument and returns the new value to be set to the store.

```js
/// file: store.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'
```

If a function is passed as the second argument, it will be called when the number of subscribers goes from zero to one (but not from one to two, etc). That function will be passed a `set` function which changes the value of the store, and an `update` function which works like the `update` method on the store, taking a callback to calculate the store's new value from its old value. It must return a `stop` function that is called when the subscriber count goes from one to zero.

```js
/// file: store.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'
```

Note that the value of a `writable` is lost when it is destroyed, for example when the page is refreshed. However, you can write your own logic to sync the value to for example the `localStorage`.

### `readable`

Creates a store whose value cannot be set from 'outside', the first argument is the store's initial value, and the second argument to `readable` is the same as the second argument to `writable`.

```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. The callback runs initially when the first subscriber subscribes and then whenever the store dependencies change.

In the simplest version, `derived` takes a single store, and the callback returns a derived value.

```ts
// @filename: ambient.d.ts
import { type Writable } from 'svelte/store';

declare global {
	const a: Writable<number>;
}

export {};

// @filename: index.ts
// ---cut---
import { derived } from 'svelte/store';

const doubled = derived(a, ($a) => $a * 2);
```

The callback can set a value asynchronously by accepting a second argument, `set`, and an optional third argument, `update`, calling either or both of them when appropriate.

In this case, you can also pass a third argument to `derived` — the initial value of the derived store before `set` or `update` is first called. If no initial value is specified, the store's initial value will be `undefined`.

```ts
// @filename: ambient.d.ts
import { type Writable } from 'svelte/store';

declare global {
	const a: Writable<number>;
}

export {};

// @filename: index.ts
// @errors: 18046 2769 7006
// ---cut---
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);
	// every time $a produces a value, this produces two
	// values, $a immediately and then $a + 1 a second later
});
```

If you return a function from the callback, it will be called when a) the callback runs again, or b) the last subscriber unsubscribes.

```ts
// @filename: ambient.d.ts
import { type Writable } from 'svelte/store';

declare global {
	const frequency: Writable<number>;
}

export {};

// @filename: index.ts
// ---cut---
import { derived } from 'svelte/store';

const tick = derived(
	frequency,
	($frequency, set) => {
		const interval = setInterval(() => {
			set(Date.now());
		}, 1000 / $frequency);

		return () => {
			clearInterval(interval);
		};
	},
	2000
);
```

In both cases, an array of arguments can be passed as the first argument instead of a single store.

```ts
// @filename: ambient.d.ts
import { type Writable } from 'svelte/store';

declare global {
	const a: Writable<number>;
	const b: Writable<number>;
}

export {};

// @filename: index.ts

// ---cut---
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`

This simple helper function makes a store readonly. You can still subscribe to the changes from the original one using this new readable store.

```js
import { readonly, writable } from 'svelte/store';

const writableStore = writable(1);
const readableStore = readonly(writableStore);

readableStore.subscribe(console.log);

writableStore.set(2); // console: 2
// @errors: 2339
readableStore.set(2); // ERROR
```

### `get`

Generally, you should read the value of a store by subscribing to it and using the value as it changes over time. Occasionally, you may need to retrieve the value of a store to which you're not subscribed. `get` allows you to do so.

> [!NOTE] This works by creating a subscription, reading the value, then unsubscribing. It's therefore not recommended in hot code paths.

```ts
// @filename: ambient.d.ts
import { type Writable } from 'svelte/store';

declare global {
	const store: Writable<string>;
}

export {};

// @filename: index.ts
// ---cut---
import { get } from 'svelte/store';

const value = get(store);
```

## Store contract

```ts
// @noErrors
store = { subscribe: (subscription: (value: any) => void) => (() => void), set?: (value: any) => void }
```

You can create your own stores without relying on [`svelte/store`](../svelte-store), by implementing the _store contract_:

1. A store must contain a `.subscribe` method, which must accept as its argument a subscription function. This subscription function must be immediately and synchronously called with the store's current value upon calling `.subscribe`. All of a store's active subscription functions must later be synchronously called whenever the store's value changes.
2. The `.subscribe` method must return an unsubscribe function. Calling an unsubscribe function must stop its subscription, and its corresponding subscription function must not be called again by the store.
3. A store may _optionally_ contain a `.set` method, which must accept as its argument a new value for the store, and which synchronously calls all of the store's active subscription functions. Such a store is called a _writable store_.

For interoperability with RxJS Observables, the `.subscribe` method is also allowed to return an object with an `.unsubscribe` method, rather than return the unsubscription function directly. Note however that unless `.subscribe` synchronously calls the subscription (which is not required by the Observable spec), Svelte will see the value of the store as `undefined` until it does.
````

----
url: https://svelte.dev/docs/svelte/getting-started/llms.txt
----

````
We recommend using [SvelteKit](../kit), which lets you [build almost anything](../kit/project-types). It's the official application framework from the Svelte team and powered by [Vite](https://vite.dev/). Create a new project with:

```sh
npx sv create myapp
cd myapp
npm install
npm run dev
```

Don't worry if you don't know Svelte yet! You can ignore all the nice features SvelteKit brings on top for now and dive into it later.

## Alternatives to SvelteKit

You can also use Svelte directly with Vite via [vite-plugin-svelte](https://github.com/sveltejs/vite-plugin-svelte) by running `npm create vite@latest` and selecting the `svelte` option (or, if working with an existing project, adding the plugin to your `vite.config.js` file). With this, `npm run build` will generate HTML, JS, and CSS files inside the `dist` directory. In most cases, you will probably need to [choose a routing library](/packages#routing) as well.

>[!NOTE] Vite is often used in standalone mode to build [single page apps (SPAs)](../kit/glossary#SPA), which you can also [build with SvelteKit](../kit/single-page-apps).

There are also [plugins for other bundlers](/packages#bundler-plugins), but we recommend Vite.

## Editor tooling

The Svelte team maintains a [VS Code extension](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode), and there are integrations with various other [editors](https://sveltesociety.dev/collection/editor-support-c85c080efc292a34) and tools as well.

You can also check your code from the command line using [`npx sv check`](https://svelte.dev/docs/cli/sv-check).


## Getting help

Don't be shy about asking for help in the [Discord chatroom](/chat)! You can also find answers on [Stack Overflow](https://stackoverflow.com/questions/tagged/svelte).
````

----
url: https://svelte.dev/docs/svelte/svelte-document
----

[Skip to main content](#main)

```
<svelte:document onevent={handler} />
```

```
<svelte:document bind:prop={value} />
```

Similarly to `<svelte:window>`, this element allows you to add listeners to events on `document`, such as `visibilitychange`, which don’t fire on `window`. It also lets you use [attachments](@attach) on `document`.

As with `<svelte:window>`, this element may only appear the top level of your component and must never be inside a block or element.

```
<svelte:document onvisibilitychange={handleVisibilityChange} {@attach someAttachment} />
```

You can also bind to the following properties:

* `activeElement`
* `fullscreenElement`
* `pointerLockElement`
* `visibilityState`

All are readonly.

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/05-special-elements/03-svelte-document.md) [llms.txt](/docs/svelte/svelte-document/llms.txt)

previous next

[\<svelte:window>](/docs/svelte/svelte-window) [\<svelte:body>](/docs/svelte/svelte-body)

----
url: https://svelte.dev/docs/svelte/svelte-element
----

[Skip to main content](#main)

```
<svelte:element this={expression} />
```

The `<svelte:element>` element lets you render an element that is unknown at author time, for example because it comes from a CMS. Any properties and event listeners present will be applied to the element.

The only supported binding is `bind:this`, since Svelte’s built-in bindings do not work with generic elements.

If `this` has a nullish value, the element and its children will not be rendered.

If `this` is the name of a [void element](https://developer.mozilla.org/en-US/docs/Glossary/Void_element) (e.g., `br`) and `<svelte:element>` has child elements, a runtime error will be thrown in development mode:

```
<script>
	let tag = $state('hr');
</script>

<svelte:element this={tag}>
	This text cannot appear inside an hr element
</svelte:element>
```

Svelte tries its best to infer the correct namespace from the element’s surroundings, but it’s not always possible. You can make it explicit with an `xmlns` attribute:

```
<svelte:element this={tag} xmlns="http://www.w3.org/2000/svg" />
```

`this` needs to be a valid DOM element tag, things like `#text` or `svelte:head` will not work.

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/05-special-elements/06-svelte-element.md) [llms.txt](/docs/svelte/svelte-element/llms.txt)

previous next

[\<svelte:head>](/docs/svelte/svelte-head) [\<svelte:options>](/docs/svelte/svelte-options)

----
url: https://svelte.dev/docs/svelte/legacy-component-api
----

[Skip to main content](#main)

In Svelte 3 and 4, the API for interacting with a component is different than in Svelte 5. Note that this page does *not* apply to legacy mode components in a Svelte 5 application.

## Creating a component[](#Creating-a-component)

```
const componentconst component: any = new Componentany(optionsany);
```

A client-side component — that is, a component compiled with `generate: 'dom'` (or the `generate` option left unspecified) is a JavaScript class.

```
import App(alias) type App = SvelteComponent<Record<string, any>, any, any>
(alias) const App: LegacyComponentType
import App from './App.svelte';

const appconst app: SvelteComponent<Record<string, any>, any, any> = new App(alias) new App(o: ComponentConstructorOptions): SvelteComponent
import App({
	target(property) ComponentConstructorOptions<Record<string, any>>.target: Document | Element | ShadowRoot: documentvar document: Document

window.document returns a reference to the document contained in the window.




MDN Reference


.body(property) Document.body: HTMLElement

The Document.body property represents the  or  node of the current document, or null if no such element exists.




MDN Reference


,
	props(property) ComponentConstructorOptions<Record<string, any>>.props?: Record<string, any> | undefined: {
		// assuming App.svelte contains something like
		// `export let answer`:
		answer(property) answer: number: 42
	}
});
```

The following initialisation options can be provided:

| option    | default     | description                                                                                          |
| --------- | ----------- | ---------------------------------------------------------------------------------------------------- |
| `target`  | **none**    | An `HTMLElement` or `ShadowRoot` to render to. This option is required                               |
| `anchor`  | `null`      | A child of `target` to render the component immediately before                                       |
| `props`   | `{}`        | An object of properties to supply to the component                                                   |
| `context` | `new Map()` | A `Map` of root-level context key-value pairs to supply to the component                             |
| `hydrate` | `false`     | See below                                                                                            |
| `intro`   | `false`     | If `true`, will play transitions on initial render, rather than waiting for subsequent state changes |

Existing children of `target` are left where they are.

The `hydrate` option instructs Svelte to upgrade existing DOM (usually from server-side rendering) rather than creating new elements. It will only work if the component was compiled with the [`hydratable: true` option](/docs/svelte-compiler#compile). Hydration of `<head>` elements only works properly if the server-side rendering code was also compiled with `hydratable: true`, which adds a marker to each element in the `<head>` so that the component knows which elements it’s responsible for removing during hydration.

Whereas children of `target` are normally left alone, `hydrate: true` will cause any children to be removed. For that reason, the `anchor` option cannot be used alongside `hydrate: true`.

The existing DOM doesn’t need to match the component — Svelte will ‘repair’ the DOM as it goes.

index

```
import App(alias) type App = SvelteComponent<Record<string, any>, any, any>
(alias) const App: LegacyComponentType
import App from './App.svelte';

const appconst app: SvelteComponent<Record<string, any>, any, any> = new App(alias) new App(o: ComponentConstructorOptions): SvelteComponent
import App({
	target(property) ComponentConstructorOptions<Record<string, any>>.target: Document | Element | ShadowRoot: documentvar document: Document

window.document returns a reference to the document contained in the window.




MDN Reference


.querySelector(method) ParentNode.querySelector<Element>(selectors: string): Element | null (+4 overloads)

Returns the first element that is a descendant of node that matches selectors.




MDN Reference


('#server-rendered-html'),
	hydrate(property) ComponentConstructorOptions<Record<string, any>>.hydrate?: boolean | undefined: true
});
```

> In Svelte 5+, use [`mount`](svelte#mount) instead

## $set[](#$set)

```
componentany.$setany(propsany);
```

Programmatically sets props on an instance. `component.$set({ x: 1 })` is equivalent to `x = 1` inside the component’s `<script>` block.

Calling this method schedules an update for the next microtask — the DOM is *not* updated synchronously.

```
componentany.$setany({ answer(property) answer: number: 42 });
```

> In Svelte 5+, use `$state` instead to create a component props and update that
>
> ```
> let propsmodule props
> let props: {
>     answer: number;
> } = $statefunction $state<{
>     answer: number;
> }>(initial: {
>     answer: number;
> }): {
>     answer: number;
> } (+1 overload)
> namespace $state
>
> Declares reactive state.
>
>
>
>
> Example:
>
>
>
> let count = $state(0);
>
> {@link https://svelte.dev/docs/svelte/$state Documentation}
>
>
> initial 
>
> The initial value
>
>
> ({ answer(property) answer: number: 42 });
> const componentconst component: any = mountany(Componentany, { props(property) props: {
>     answer: number;
> } });
> // ...
> propsmodule props
> let props: {
>     answer: number;
> }.answer(property) answer: number = 24;
> ```

## $on[](#$on)

```
componentany.$onany(evany, callbackany);
```

Causes the `callback` function to be called whenever the component dispatches an `event`.

A function is returned that will remove the event listener when called.

```
const offconst off: any = componentany.$onany('selected', (event(parameter) event: any) => {
	consolenamespace console
var console: Console

The console module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.




The module exports two specific components:





A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.


A global console instance configured to write to process.stdout and
process.stderr. The global console can be used without importing the node:console module.





Warning: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the note on process I/O for
more information.




Example using the global console:



console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
//   Error: Whoops, something bad happened
//     at [eval]:5:15
//     at Script.runInThisContext (node:vm:132:18)
//     at Object.runInThisContext (node:vm:309:38)
//     at node:internal/process/execution:77:19
//     at [eval]-wrapper:6:22
//     at evalScript (node:internal/process/execution:76:60)
//     at node:internal/main/eval_string:23:3

const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:



const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);

myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err

const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

source


.log(method) Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to printf(3)
(the arguments are all passed to util.format()).



const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.




v0.1.100


(event(parameter) event: any.detailany.selectionany);
});

offconst off: any();
```

> In Svelte 5+, pass callback props instead

## $destroy[](#$destroy)

```
componentany.$destroyany();
```

Removes a component from the DOM and triggers any `onDestroy` handlers.

> In Svelte 5+, use [`unmount`](svelte#unmount) instead

## Component props[](#Component-props)

```
componentany.propany;
```

```
componentmodule component.prop(property) component.prop: any = valueany;
```

If a component is compiled with `accessors: true`, each instance will have getters and setters corresponding to each of the component’s props. Setting a value will cause a *synchronous* update, rather than the default async update caused by `component.$set(...)`.

By default, `accessors` is `false`, unless you’re compiling as a custom element.

```
consolenamespace console
var console: Console

The console module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.




The module exports two specific components:





A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.


A global console instance configured to write to process.stdout and
process.stderr. The global console can be used without importing the node:console module.





Warning: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the note on process I/O for
more information.




Example using the global console:



console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
//   Error: Whoops, something bad happened
//     at [eval]:5:15
//     at Script.runInThisContext (node:vm:132:18)
//     at Object.runInThisContext (node:vm:309:38)
//     at node:internal/process/execution:77:19
//     at [eval]-wrapper:6:22
//     at evalScript (node:internal/process/execution:76:60)
//     at node:internal/main/eval_string:23:3

const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:



const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);

myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err

const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

source


.log(method) Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to printf(3)
(the arguments are all passed to util.format()).



const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.




v0.1.100


(componentany.countany);
componentany.countany += 1;
```

> In Svelte 5+, this concept is obsolete. If you want to make properties accessible from the outside, `export` them

## Server-side component API[](#Server-side-component-API)

```
const resultconst result: any = Componentany.renderany(...)
```

Unlike client-side components, server-side components don’t have a lifespan after you render them — their whole job is to create some HTML and CSS. For that reason, the API is somewhat different.

A server-side component exposes a `render` method that can be called with optional props. It returns an object with `head`, `html`, and `css` properties, where `head` contains the contents of any `<svelte:head>` elements encountered.

You can import a Svelte component directly into Node using `svelte/register`.

```
requirevar require: NodeJS.Require
(id: string) => any (+1 overload)

Used to import modules, JSON, and local files.




v0.1.13


('svelte/register');

const Appnamespace App
const App: any

It's possible to tell SvelteKit how to type objects inside your app by declaring the App namespace. By default, a new project will have a file called src/app.d.ts containing the following:



declare global {
	namespace App {
		// interface Error {}
		// interface Locals {}
		// interface PageData {}
		// interface PageState {}
		// interface Platform {}
	}
}

export {};

The export {} line exists because without it, the file would be treated as an ambient module which prevents you from adding import declarations.
If you need to add ambient declare module declarations, do so in a separate file like src/ambient.d.ts.




By populating these interfaces, you will gain type safety when using event.locals, event.platform, and data from load functions.


 = requirevar require: NodeJS.Require
(id: string) => any (+1 overload)

Used to import modules, JSON, and local files.




v0.1.13


('./App.svelte').defaultany;

const { headconst head: any, htmlconst html: any, cssconst css: any } = Appnamespace App
const App: any

It's possible to tell SvelteKit how to type objects inside your app by declaring the App namespace. By default, a new project will have a file called src/app.d.ts containing the following:



declare global {
	namespace App {
		// interface Error {}
		// interface Locals {}
		// interface PageData {}
		// interface PageState {}
		// interface Platform {}
	}
}

export {};

The export {} line exists because without it, the file would be treated as an ambient module which prevents you from adding import declarations.
If you need to add ambient declare module declarations, do so in a separate file like src/ambient.d.ts.




By populating these interfaces, you will gain type safety when using event.locals, event.platform, and data from load functions.


.renderany({
	answer(property) answer: number: 42
});
```

The `.render()` method accepts the following parameters:

| parameter | default | description                                        |
| --------- | ------- | -------------------------------------------------- |
| `props`   | `{}`    | An object of properties to supply to the component |
| `options` | `{}`    | An object of options                               |

The `options` object takes in the following options:

| option    | default     | description                                                              |
| --------- | ----------- | ------------------------------------------------------------------------ |
| `context` | `new Map()` | A `Map` of root-level context key-value pairs to supply to the component |

```
const { headconst head: any, htmlconst html: any, cssconst css: any } = Appany.renderany(
	// props
	{ answer(property) answer: number: 42 },
	// options
	{
		context(property) context: Map<string, string>: new Mapvar Map: MapConstructor
new <string, string>(iterable?: Iterable<readonly [string, string]> | null | undefined) => Map<string, string> (+3 overloads)([['context-key', 'context-value']])
	}
);
```

> In Svelte 5+, use [`render`](svelte-server#render) instead

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/99-legacy/40-legacy-component-api.md) [llms.txt](/docs/svelte/legacy-component-api/llms.txt)

previous next

[\<svelte:self>](/docs/svelte/legacy-svelte-self)

----
url: https://svelte.dev/docs/svelte/each
----

[Skip to main content](#main)

```
{#each expression as name}...{/each}
```

```
{#each expression as name, index}...{/each}
```

Iterating over values can be done with an each block. The values in question can be arrays, array-like objects (i.e. anything with a `length` property), or iterables like `Map` and `Set`. (Internally, they are converted to arrays with [`Array.from`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from).)

If the value is `null` or `undefined`, it is treated the same as an empty array (which will cause [else blocks](#Else-blocks) to be rendered, where applicable).

```
<h1>Shopping list</h1>
<ul>
	{#each items as item}
		<li>{item.name} x {item.qty}</li>
	{/each}
</ul>
```

An each block can also specify an *index*, equivalent to the second argument in an `array.map(...)` callback:

```
{#each items as item, i}
	<li>{i + 1}: {item.name} x {item.qty}</li>
{/each}
```

## Keyed each blocks[](#Keyed-each-blocks)

```
{#each expression as name (key)}...{/each}
```

```
{#each expression as name, index (key)}...{/each}
```

If a *key* expression is provided — which must uniquely identify each list item — Svelte will use it to intelligently update the list when data changes by inserting, moving and deleting items, rather than adding or removing items at the end and updating the state in the middle.

The key can be any object, but strings and numbers are recommended since they allow identity to persist when the objects themselves change.

```
{#each items as item (item.id)}
	<li>{item.name} x {item.qty}</li>
{/each}

<!-- or with additional index value -->
{#each items as item, i (item.id)}
	<li>{i + 1}: {item.name} x {item.qty}</li>
{/each}
```

You can freely use destructuring and rest patterns in each blocks.

```
{#each items as { id, name, qty }, i (id)}
	<li>{i + 1}: {name} x {qty}</li>
{/each}

{#each objects as { id, ...rest }}
	<li><span>{id}</span><MyComponent {...rest} /></li>
{/each}

{#each items as [id, ...rest]}
	<li><span>{id}</span><MyComponent values={rest} /></li>
{/each}
```

## Each blocks without an item[](#Each-blocks-without-an-item)

```
{#each expression}...{/each}
```

```
{#each expression, index}...{/each}
```

In case you just want to render something `n` times, you can omit the `as` part:

[Open in playground](/playground/untitled#H4sIAAAAAAAAA3WR3WrDMAyFX0VoDFqWtGRXxWsKY4-x7MKx1dbUdYyt_hHy7sNu1m3Q3gmdT8c6co9O7gkFfmwpRmg7GTQWuDaWIorPHlsZaUTevZ_FI1kmLFB1jslxRIFLbY6grIyxblAlnzL7NLhqXMP9E0m1hR4suQ1vBSxgKCBItxuS_AhIK4xAw79PiNZKtav7STKAl4xN4Rleoa5rqIbVcq7NcTU6z5NzdrmVN90tI18sZXT2Z23or8PaRG_lRcAmGP127aWyZNp7K5lK1dnD3kUBgTxJniwKqNZhepcN3ekR2HZBUxBQ-TPEzhoNOeOoyuhJcRkkm05Albq5P8vQz7INt1LtNqE7OC3-zef0Ofc1LhZ47z-ZzoyCw4EK5ItPejotDl8FsjT2ZJxGsZY20vANGEeVODUCAAA)

```
<div class="chess-board">
	{#each { length: 8 }, rank}
		{#each { length: 8 }, file}
			<div class:black={(rank + file) % 2 === 1}></div>
		{/each}
	{/each}
</div>

<style>
	.chess-board {
		display: grid;
		grid-template-columns: repeat(8, 1fr);
		grid-template-rows: repeat(8, 1fr);
		border: 1px solid black;
		aspect-ratio: 1;

		.black {
			background: black;
		}
	}
</style>
```

## Else blocks[](#Else-blocks)

```
{#each expression as name}...{:else}...{/each}
```

An each block can also have an `{:else}` clause, which is rendered if the list is empty.

```
{#each todos as todo}
	<p>{todo.text}</p>
{:else}
	<p>No tasks today!</p>
{/each}
```

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/03-template-syntax/03-each.md) [llms.txt](/docs/svelte/each/llms.txt)

previous next

[{#if ...}](/docs/svelte/if) [{#key ...}](/docs/svelte/key)

----
url: https://svelte.dev/docs/svelte/testing/llms.txt
----

````
Testing helps you write and maintain your code and guard against regressions. Testing frameworks help you with that, allowing you to describe assertions or expectations about how your code should behave. Svelte is unopinionated about which testing framework you use — you can write unit tests, integration tests, and end-to-end tests using solutions like [Vitest](https://vitest.dev/), [Jasmine](https://jasmine.github.io/), [Cypress](https://www.cypress.io/) and [Playwright](https://playwright.dev/).

## Unit and component tests with Vitest

Unit tests allow you to test small isolated parts of your code. Integration tests allow you to test parts of your application to see if they work together. If you're using Vite (including via SvelteKit), we recommend using [Vitest](https://vitest.dev/). You can use the Svelte CLI to [setup Vitest](/docs/cli/vitest) either during project creation or later on.

To setup Vitest manually, first install it:

```sh
npm install -D vitest
```

Then adjust your `vite.config.js`:

<!-- prettier-ignore -->
```js
/// file: vite.config.js
import { defineConfig } from +++'vitest/config'+++;

export default defineConfig({
	// ...
	// Tell Vitest to use the `browser` entry points in `package.json` files, even though it's running in Node
	resolve: process.env.VITEST
		? {
				conditions: ['browser']
			}
		: undefined
});
```

> [!NOTE] If loading the browser version of all your packages is undesirable, because (for example) you also test backend libraries, [you may need to resort to an alias configuration](https://github.com/testing-library/svelte-testing-library/issues/222#issuecomment-1909993331)

You can now write unit tests for code inside your `.js/.ts` files:

```js
/// file: multiplier.svelte.test.js
// @filename: multiplier.svelte.ts
export function multiplier(initial: number, k: number) {
	let count = $state(initial);

	return {
		get value() {
			return count * k;
		},
		set: (c: number) => {
			count = c;
		}
	};
}
// @filename: multiplier.svelte.test.js
// ---cut---
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);
});
```

```js
/// file: multiplier.svelte.js
/**
 * @param {number} initial
 * @param {number} k
 */
export function multiplier(initial, k) {
	let count = $state(initial);

	return {
		get value() {
			return count * k;
		},
		/** @param {number} c */
		set: (c) => {
			count = c;
		}
	};
}
```

### Using runes inside your test files

Since Vitest processes your test files the same way as your source files, you can use runes inside your tests as long as the filename includes `.svelte`:

```js
/// file: multiplier.svelte.test.js
// @filename: multiplier.svelte.ts
export function multiplier(getCount: () => number, k: number) {
	return {
		get value() {
			return getCount() * k;
		}
	};
}
// @filename: multiplier.svelte.test.js
// ---cut---
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);
});
```

```js
/// file: multiplier.svelte.js
/**
 * @param {() => number} getCount
 * @param {number} k
 */
export function multiplier(getCount, k) {
	return {
		get value() {
			return getCount() * k;
		}
	};
}
```

If the code being tested uses effects, you need to wrap the test inside `$effect.root`:

```js
/// file: logger.svelte.test.js
// @filename: logger.svelte.ts
export function logger(fn: () => void) {}
// @filename: logger.svelte.test.js
// ---cut---
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);

		// logger uses an $effect to log updates of its input
		let log = logger(() => count);

		// effects normally run after a microtask,
		// use flushSync to execute all pending effects synchronously
		flushSync();
		expect(log).toEqual([0]);

		count = 1;
		flushSync();

		expect(log).toEqual([0, 1]);
	});

	cleanup();
});
```

```js
/// file: logger.svelte.js
/**
 * @param {() => any} getValue
 */
export function logger(getValue) {
	/** @type {any[]} */
	let log = [];

	$effect(() => {
		log.push(getValue());
	});

	return log;
}
```

### Component testing

It is possible to test your components in isolation, which allows you to render them in a browser (real or simulated), simulate behavior, and make assertions, without spinning up your whole app.

> [!NOTE] Before writing component tests, think about whether you actually need to test the component, or if it's more about the logic _inside_ the component. If so, consider extracting out that logic to test it in isolation, without the overhead of a component.

To get started, install jsdom (a library that shims DOM APIs):

```sh
npm install -D jsdom
```

Then adjust your `vite.config.js`:

```js
/// file: vite.config.js
import { defineConfig } from 'vitest/config';

export default defineConfig({
	plugins: [
		/* ... */
	],
	test: {
		// If you are testing components client-side, you need to set up a DOM environment.
		// If not all your files should have this environment, you can use a
		// `// @vitest-environment jsdom` comment at the top of the test files instead.
		environment: 'jsdom'
	},
	// Tell Vitest to use the `browser` entry points in `package.json` files, even though it's running in Node
	resolve: process.env.VITEST
		? {
				conditions: ['browser']
			}
		: undefined
});
```

After that, you can create a test file in which you import the component to test, interact with it programmatically and write expectations about the results:

```js
/// file: component.test.js
import { flushSync, mount, unmount } from 'svelte';
import { expect, test } from 'vitest';
import Component from './Component.svelte';

test('Component', () => {
	// Instantiate the component using Svelte's `mount` API
	const component = mount(Component, {
		target: document.body, // `document` exists because of jsdom
		props: { initial: 0 }
	});

	expect(document.body.innerHTML).toBe('<button>0</button>');

	// Click the button, then flush the changes so you can synchronously write expectations
	document.body.querySelector('button')?.click();
	flushSync();

	expect(document.body.innerHTML).toBe('<button>1</button>');

	// Remove the component from the DOM
	unmount(component);
});
```

While the process is very straightforward, it is also low level and somewhat brittle, as the precise structure of your component may change frequently. Tools like [@testing-library/svelte](https://testing-library.com/docs/svelte-testing-library/intro/) can help streamline your tests. The above test could be rewritten like this:

```js
// @errors: 2339
/// file: 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);
});
```

When writing component tests that involve two-way bindings, context or snippet props, it's best to create a wrapper component for your specific test and interact with that. `@testing-library/svelte` contains some [examples](https://testing-library.com/docs/svelte-testing-library/example).

## Component tests with Storybook

[Storybook](https://storybook.js.org) is a tool for developing and documenting UI components, and it can also be used to test your components. They're run with Vitest's browser mode, which renders your components in a real browser for the most realistic testing environment.

To get started, first install Storybook ([using Svelte's CLI](/docs/cli/storybook)) in your project via `npx sv add storybook` and choose the recommended configuration that includes testing features. If you're already using Storybook, and for more information on Storybook's testing capabilities, follow the [Storybook testing docs](https://storybook.js.org/docs/writing-tests?renderer=svelte) to get started.

You can create stories for component variations and test interactions with the [play function](https://storybook.js.org/docs/writing-tests/interaction-testing?renderer=svelte#writing-interaction-tests), which allows you to simulate behavior and make assertions using the Testing Library and Vitest APIs. Here's an example of two stories that can be tested, one that renders an empty LoginForm component and one that simulates a user filling out the form:

```svelte
/// file: LoginForm.stories.svelte
<script module>
	import { defineMeta } from '@storybook/addon-svelte-csf';
	import { expect, fn } from 'storybook/test';

	import LoginForm from './LoginForm.svelte';

	const { Story } = defineMeta({
		component: LoginForm,
		args: {
			// Pass a mock function to the `onSubmit` prop
			onSubmit: fn(),
		}
	});
</script>

<Story name="Empty Form" />

<Story
	name="Filled Form"
	play={async ({ args, canvas, userEvent }) => {
		// Simulate a user filling out the form
		await userEvent.type(canvas.getByTestId('email'), 'email@provider.com');
		await userEvent.type(canvas.getByTestId('password'), 'a-random-password');
		await userEvent.click(canvas.getByRole('button'));

		// Run assertions
		await expect(args.onSubmit).toHaveBeenCalledTimes(1);
		await expect(canvas.getByText('You’re in!')).toBeInTheDocument();
	}}
/>
```

## End-to-end tests with Playwright

E2E (short for 'end to end') tests allow you to test your full application through the eyes of the user. This section uses [Playwright](https://playwright.dev/) as an example, but you can also use other solutions like [Cypress](https://www.cypress.io/) or [NightwatchJS](https://nightwatchjs.org/).

You can use the Svelte CLI to [setup Playwright](/docs/cli/playwright) either during project creation or later on. You can also [set it up with `npm init playwright`](https://playwright.dev/docs/intro). Additionally, you may also want to install an IDE plugin such as [the VS Code extension](https://playwright.dev/docs/getting-started-vscode) to be able to execute tests from inside your IDE.

If you've run `npm init playwright` or are not using Vite, you may need to adjust the Playwright config to tell Playwright what to do before running the tests — mainly starting your application at a certain port. For example:

```js
/// file: 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;
```

You can now start writing tests. These are totally unaware of Svelte as a framework, so you mainly interact with the DOM and write assertions.

```js
// @errors: 2307 7031
/// file: 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();
});
```
````

----
url: https://svelte.dev/docs/svelte/context
----

[Skip to main content](#main)

Context allows components to access values owned by parent components without passing them down as props (potentially through many layers of intermediate components, known as ‘prop-drilling’).

By creating a `[get, set, has]` triplet of functions with `createContext`, you can set the context in a parent component and get it in a child component:

[Open in playground](/playground/untitled#H4sIAAAAAAAAA42SwW6DMAyGX8WyJgESAvVKKdrUF9hlp9IDAzMipQEl7toJ8e5TAFFgm8Yx8e8__2enRZVdCCM81orpzuhjKSQZjE4tvmeGxvJL0wTmkyQT-phbrWKDEcYm16LhJFUpi0tTa4bXTJNiKHV9AScIh-PY7OxnwmMlZDHp-tNMFocPaxUPLv0z8dAXJlYz3qOPvwXtiSLWV_KRvxpbt3TY-Qu4RcR_-VowxG-G9Dgy6CaGfLjpKVXKkqw6t3E1KejgAE-NrhvjeqNi6eS2YBNF4NxqLQsHOm89iPZZkypIT66u1z3g1yAb-eej34D_sRE_r5VhuBrScFg1uT_A4mqXVCRlDa3tCGy0zgehjCgI5gnjsNrNFr4KvxF5jBqwWQJPkLmmjGnNOPvFSigmXWY5gQWD1iIP6zOshfrYp6qzOrr3lsM0Tss5-Ku_dIbD8uXYFhPX2z-AF9H_xD37yJmQN6EKjMpMGuq-AU_UQgfsAwAA)

```
<script>
	import Parent from './Parent.svelte';
	import Child from './Child.svelte';
</script>

<Parent>
	<Child />
</Parent>
```

```
<script lang="ts">
	import Parent from './Parent.svelte';
	import Child from './Child.svelte';
</script>

<Parent>
	<Child />
</Parent>
```

```
<script>
	import { setUserContext } from './context';

	let { children } = $props();

	setUserContext({ name: 'world' });
</script>

{@render children()}
```

```
<script lang="ts">
	import { setUserContext } from './context';

	let { children } = $props();

	setUserContext({ name: 'world' });
</script>

{@render children()}
```

```
<script>
	import { getUserContext } from './context';

	const user = getUserContext();
</script>

<h1>hello {user.name}, inside Child.svelte</h1>
```

```
<script lang="ts">
	import { getUserContext } from './context';

	const user = getUserContext();
</script>

<h1>hello {user.name}, inside Child.svelte</h1>
```

```
import { createContext(alias) function createContext<T>(): [() => T, (context: T) => T, () => boolean]
import createContext

Returns a [get, set, has] triplet of functions for working with context in a type-safe way.




get will throw an error if set has not yet been called in the current component or any of
its ancestors.




5.40.0


reference } from 'svelte';

interface Userinterface User {
	name(property) User.name: string: string;
}

export const [getUserContextconst getUserContext: () => User, setUserContextconst setUserContext: (context: User) => User] = createContext(alias) createContext<User>(): [() => User, (context: User) => User, () => boolean]
import createContext

Returns a [get, set, has] triplet of functions for working with context in a type-safe way.




get will throw an error if set has not yet been called in the current component or any of
its ancestors.




5.40.0


reference<Userinterface User>();
```

> `createContext` was added in version 5.40. If you are using an earlier version of Svelte, you must use `setContext` and `getContext` instead.

This is particularly useful when `Parent.svelte` is not directly aware of `Child.svelte`, but instead renders it as part of a `children` [snippet](snippet) as shown above.

## setContext and getContext[](#setContext-and-getContext)

As an alternative to `createContext`, you can use `setContext` and `getContext` directly. The parent component sets context with `setContext(key, value)`...

Parent

```
<script>
	import { setContext } from 'svelte';

	setContext('my-context', 'hello from Parent.svelte');
</script>
```

```
<script lang="ts">
	import { setContext } from 'svelte';

	setContext('my-context', 'hello from Parent.svelte');
</script>
```

...and the child retrieves it with `getContext`:

Child

```
<script>
	import { getContext } from 'svelte';

	const message = getContext('my-context');
</script>

<h1>{message}, inside Child.svelte</h1>
```

```
<script lang="ts">
	import { getContext } from 'svelte';

	const message = getContext('my-context');
</script>

<h1>{message}, inside Child.svelte</h1>
```

The key (`'my-context'`, in the example above) and the context itself can be any JavaScript value.

> `createContext` is preferred since it provides better type safety and makes it unnecessary to use keys.

In addition to [`setContext`](svelte#setContext) and [`getContext`](svelte#getContext), Svelte exposes [`hasContext`](svelte#hasContext) and [`getAllContexts`](svelte#getAllContexts) functions.

## Using context with state[](#Using-context-with-state)

You can store reactive state in context...

[Open in playground](/playground/untitled#H4sIAAAAAAAAA42S226DMAyGX8WKJpVqCLpbCkhTH6P0gqZmjQYBJWbthHj3KQkU2FaJKw4-_P9nu2Myr5BF7FBLwjvBTdAVNOWEzGeFKFGz6Nixc65xyHxvmkB_YWkzuCmTpFnEYs2VaCjNZEaiampF0IFGOtStJFTQQ6HqCjZByJ1WQHqzn2UfrqK8PJLs1yBk02RGJRLwoV0CL9am15lIRvZ_BDvz1W-HgkneG-pMJA4nqzI-t0S1hFryUvDPpPO2kKSjTGCf8JrAW-_IJFdYoSTTxpW6Ns59mD57XamUwM4JKdQ4F2E--28BZpAsItWiz-i7MXGzNdb7i6XNp7libR8r1ibNzKWeb2Qq8_7OuUm7BWofh82M6pfDlVyTpyXVg4QrzAnH6x5h5mcljKUi5wgjcufY7D3Jtjqj2meyN7l4t20d93HC9WeHfoJkqRoPgdTb7ifehfOntCefUS7Km5AXFhV5qbH_AYUaIeGzAwAA)

```
<script>
	import { setCounter } from './context.ts';
	import Child from './Child.svelte';

	let counter = $state({
		count: 0
	});

	setCounter(counter);
</script>

<button onclick={() => counter.count += 1}>
	increment
</button>

<Child />
<Child />
<Child />

<button onclick={() => counter.count = 0}>
	reset
</button>
```

```
<script lang="ts">
	import { setCounter } from './context.ts';
	import Child from './Child.svelte';

	let counter = $state({
		count: 0
	});

	setCounter(counter);
</script>

<button onclick={() => counter.count += 1}>
	increment
</button>

<Child />
<Child />
<Child />

<button onclick={() => counter.count = 0}>
	reset
</button>
```

```
<script>
	import { getCounter } from './context.ts';

	const counter = getCounter();
</script>

<p>{counter.count}</p>
```

```
<script lang="ts">
	import { getCounter } from './context.ts';

	const counter = getCounter();
</script>

<p>{counter.count}</p>
```

```
import { createContext(alias) function createContext<T>(): [() => T, (context: T) => T, () => boolean]
import createContext

Returns a [get, set, has] triplet of functions for working with context in a type-safe way.




get will throw an error if set has not yet been called in the current component or any of
its ancestors.




5.40.0


reference } from 'svelte';

interface Counterinterface Counter {
	count(property) Counter.count: number: number;
}

export const [getCounterconst getCounter: () => Counter, setCounterconst setCounter: (context: Counter) => Counter] = createContext(alias) createContext<Counter>(): [() => Counter, (context: Counter) => Counter, () => boolean]
import createContext

Returns a [get, set, has] triplet of functions for working with context in a type-safe way.




get will throw an error if set has not yet been called in the current component or any of
its ancestors.




5.40.0


reference<Counterinterface Counter>();
```

...though note that if you *reassign* `counter` instead of updating it, you will ‘break the link’ — in other words instead of this...

```
<button onclick={() => counter = { count: 0 } }>
	reset
</button>
```

...you must do this:

```
<button onclick={() => counter.count = 0}>
	reset
</button>
```

Svelte will warn you if you get it wrong.

Similarly, to pass primitive values through context, use functions as described in [Passing state into functions]($state#Passing-state-into-functions).

## Mounting components with context[](#Mounting-components-with-context)

To mount a component with specific context, create a wrapper component that sets the context before rendering the component. This is useful for [component tests](testing#Unit-and-component-tests-with-Vitest-Component-testing), or any other scenario that needs to provide context through `mount`. As of version 5.49, you can do this sort of thing:

```
import { mount(alias) function mount<Props extends Record<string, any>, Exports extends Record<string, any>>(component: ComponentType<SvelteComponent<Props>> | Component<Props, Exports, any>, options: MountOptions<Props>): Exports
import mount

Mounts a component to the given target and returns the exports and potentially the props (if compiled with accessors: true) of the component.
Transitions will play during the initial render unless the intro option is set to false.


reference, unmount(alias) function unmount(component: Record<string, any>, options?: {
    outro?: boolean;
} | undefined): Promise<void>
import unmount

Unmounts a component that was previously mounted using mount or hydrate.




Since 5.13.0, if options.outro is true, transitions will play before the component is removed from the DOM.




Returns a Promise that resolves after transitions have completed if options.outro is true, or immediately otherwise (prior to 5.13.0, returns void).



import { mount, unmount } from 'svelte';
import App from './App.svelte';

const app = mount(App, { target: document.body });

// later...
unmount(app, { outro: true });
reference } from 'svelte';
import { expect(alias) const expect: ExpectStatic
import expect, test(alias) const test: TestAPI
import test

Defines a test case with a given name and test function. The test function can optionally be configured with test options.


name 


The name of the test or a function that will be used as a test name.



optionsOrFn 


Optional. The test options or the test function if no explicit name is provided.



optionsOrTest 


Optional. The test function or options, depending on the previous parameters.





{Error} If called inside another test function.



// Define a simple test
test('should add two numbers', () => {
  expect(add(1, 2)).toBe(3);
});
// Define a test with options
test('should subtract two numbers', { retry: 3 }, () => {
  expect(subtract(5, 2)).toBe(3);
});
 } from 'vitest';
import { setUserContextimport setUserContext } from './context';
import MyComponent(alias) type MyComponent = SvelteComponent<Record<string, any>, any, any>
(alias) const MyComponent: LegacyComponentType
import MyComponent from './MyComponent.svelte';

test(alias) test<object>(name: string | Function, fn?: TestFunction<object> | undefined, options?: number): void (+1 overload)
import test

Defines a test case with a given name and test function. The test function can optionally be configured with test options.


name 


The name of the test or a function that will be used as a test name.



optionsOrFn 


Optional. The test options or the test function if no explicit name is provided.



optionsOrTest 


Optional. The test function or options, depending on the previous parameters.





{Error} If called inside another test function.



// Define a simple test
test('should add two numbers', () => {
  expect(add(1, 2)).toBe(3);
});
// Define a test with options
test('should subtract two numbers', { retry: 3 }, () => {
  expect(subtract(5, 2)).toBe(3);
});
('MyComponent', () => {
	function Wrapper(local function) Wrapper(...args: any[]): {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<string, any>(...args(parameter) args: any[]) {
		setUserContextimport setUserContext({ name(property) name: string: 'Bob' });
		return MyComponent(alias) MyComponent(internals: Brand<"ComponentInternals">, props: Record<string, any>): ReturnType<Component<Record<string, any>, Record<string, any>>>
import MyComponent(...args(parameter) args: any[]);
	}

	const componentconst component: {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<string, any> = mount(alias) mount<Record<string, any>, {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<string, any>>(component: ComponentType<SvelteComponent<Record<string, any>, any, any>> | Component<Record<string, any>, {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<string, any>, any>, options: MountOptions<...>): {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<...>
import mount

Mounts a component to the given target and returns the exports and potentially the props (if compiled with accessors: true) of the component.
Transitions will play during the initial render unless the intro option is set to false.


reference(Wrapper(local function) Wrapper(...args: any[]): {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<string, any>, {
		target(property) target: Document | Element | ShadowRoot

Target element where the component will be mounted.


: documentvar document: Document

window.document returns a reference to the document contained in the window.




MDN Reference


.body(property) Document.body: HTMLElement

The Document.body property represents the  or  node of the current document, or null if no such element exists.




MDN Reference



	});

	expect(alias) expect<string>(actual: string, message?: string): Assertion<string> (+1 overload)
import expect(documentvar document: Document

window.document returns a reference to the document contained in the window.




MDN Reference


.body(property) Document.body: HTMLElement

The Document.body property represents the  or  node of the current document, or null if no such element exists.




MDN Reference


.innerHTML(property) Element.innerHTML: string

The innerHTML property of the Element interface gets or sets the HTML or XML markup contained within the element, omitting any shadow roots in both cases.




MDN Reference


).toBe(property) JestAssertion<string>.toBe: <string>(expected: string) => void

Checks that a value is what you expect. It calls Object.is to compare values.
Don't use toBe with floating-point numbers.




expect(result).toBe(42);
expect(status).toBe(true);


('<h1>Hello Bob!</h1>');

	unmount(alias) unmount(component: Record<string, any>, options?: {
    outro?: boolean;
} | undefined): Promise<void>
import unmount

Unmounts a component that was previously mounted using mount or hydrate.




Since 5.13.0, if options.outro is true, transitions will play before the component is removed from the DOM.




Returns a Promise that resolves after transitions have completed if options.outro is true, or immediately otherwise (prior to 5.13.0, returns void).



import { mount, unmount } from 'svelte';
import App from './App.svelte';

const app = mount(App, { target: document.body });

// later...
unmount(app, { outro: true });
reference(componentconst component: {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<string, any>);
});
```

This approach also works with [`hydrate`](imperative-component-api#hydrate) and [`render`](imperative-component-api#render).

The context set by the wrapper only applies to that mounted component tree. Each call to `mount`, `hydrate` or `render` creates a separate wrapper instance, so the context does not leak into other mounted components.

## Replacing global state[](#Replacing-global-state)

When you have state shared by many different components, you might be tempted to put it in its own module and just import it wherever it’s needed:

state.svelte

```
export const myGlobalStateconst myGlobalState: {
    user: {};
} = $statefunction $state<{
    user: {};
}>(initial: {
    user: {};
}): {
    user: {};
} (+1 overload)
namespace $state

Declares reactive state.




Example:



let count = $state(0);

{@link https://svelte.dev/docs/svelte/$state Documentation}


initial 

The initial value


({
	user(property) user: {}: {
		// ...
	}
	// ...
});
```

In many cases this is perfectly fine, but there is a risk: if you mutate the state during server-side rendering (which is discouraged, but entirely possible!)...

App

```
<script>
	import { myGlobalState } from './state.svelte.js';

	let { data } = $props();

	if (data.user) {
		myGlobalState.user = data.user;
	}
</script>
```

```
<script lang="ts">
	import { myGlobalState } from './state.svelte.js';

	let { data } = $props();

	if (data.user) {
		myGlobalState.user = data.user;
	}
</script>
```

...then the data may be accessible by the *next* user. Context solves this problem because it is not shared between requests.

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/06-runtime/02-context.md) [llms.txt](/docs/svelte/context/llms.txt)

previous next

[Stores](/docs/svelte/stores) [Lifecycle hooks](/docs/svelte/lifecycle-hooks)

----
url: https://svelte.dev/docs/svelte/faq/llms.txt
----

`````
## I'm new to Svelte. Where should I start?

We think the best way to get started is playing through the interactive [tutorial](/tutorial). Each step there is mainly focused on one specific aspect and is easy to follow. You'll be editing and running real Svelte components right in your browser.

Five to ten minutes should be enough to get you up and running. An hour and a half should get you through the entire tutorial.

## Where can I get support?

If your question is about certain syntax, the [reference docs](/docs/svelte) are a good place to start.

Stack Overflow is a popular forum to ask code-level questions or if you’re stuck with a specific error. Read through the existing questions tagged with [Svelte](https://stackoverflow.com/questions/tagged/svelte+or+svelte-3) or [ask your own](https://stackoverflow.com/questions/ask?tags=svelte)!

There are online forums and chats which are a great place for discussion about best practices, application architecture or just to get to know fellow Svelte users. [Our Discord](/chat) or [the Reddit channel](https://www.reddit.com/r/sveltejs/) are examples of that. If you have an answerable code-level question, Stack Overflow is usually a better fit.

## Are there any third-party resources?

Svelte Society maintains a [list of books and videos](https://sveltesociety.dev/collection/a-list-of-books-and-courses-ac01dd10363184fa).

## How can I get VS Code to syntax-highlight my .svelte files?

There is an [official VS Code extension for Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode).

## Is there a tool to automatically format my .svelte files?

You can use prettier with the [prettier-plugin-svelte](https://www.npmjs.com/package/prettier-plugin-svelte) plugin.

## How do I document my components?

In editors which use the Svelte Language Server you can document Components, functions and exports using specially formatted comments.

````svelte
<script>
	/** What should we call the user? */
	export let name = 'world';
</script>

<!--
@component
Here's some documentation for this component.
It will show up on hover.

- You can use markdown here.
- You can also use code blocks here.
- Usage:
  ```svelte
  <main name="Arethra">
  ```
-->
<main>
	<h1>
		Hello, {name}
	</h1>
</main>
````

Note: The `@component` is necessary in the HTML comment which describes your component.

## Does Svelte scale?

There will be a blog post about this eventually, but in the meantime, check out [this issue](https://github.com/sveltejs/svelte/issues/2546).

## Is there a UI component library?

There are several [UI component libraries](/packages#component-libraries) as well as standalone components listed on [the packages page](/packages).

## How do I test Svelte apps?

How your application is structured and where logic is defined will determine the best way to ensure it is properly tested. It is important to note that not all logic belongs within a component — this includes concerns such as data transformation, cross-component state management, and logging, among others. Remember that the Svelte library has its own test suite, so you do not need to write tests to validate implementation details provided by Svelte.

A Svelte application will typically have three different types of tests: Unit, Component, and End-to-End (E2E).

_Unit Tests_: Focus on testing business logic in isolation. Often this is validating individual functions and edge cases. By minimizing the surface area of these tests they can be kept lean and fast, and by extracting as much logic as possible from your Svelte components more of your application can be covered using them. When creating a new SvelteKit project, you will be asked whether you would like to setup [Vitest](https://vitest.dev/) for unit testing. There are a number of other test runners that could be used as well.

_Component Tests_: Validating that a Svelte component mounts and interacts as expected throughout its lifecycle requires a tool that provides a Document Object Model (DOM). Components can be compiled (since Svelte is a compiler and not a normal library) and mounted to allow asserting against element structure, listeners, state, and all the other capabilities provided by a Svelte component. Tools for component testing range from an in-memory implementation like jsdom paired with a test runner like [Vitest](https://vitest.dev/) to solutions that leverage an actual browser to provide a visual testing capability such as [Playwright](https://playwright.dev/docs/test-components) or [Cypress](https://www.cypress.io/).

_End-to-End Tests_: To ensure your users are able to interact with your application it is necessary to test it as a whole in a manner as close to production as possible. This is done by writing end-to-end (E2E) tests which load and interact with a deployed version of your application in order to simulate how the user will interact with your application. When creating a new SvelteKit project, you will be asked whether you would like to setup [Playwright](https://playwright.dev/) for end-to-end testing. There are many other E2E test libraries available for use as well.

Some resources for getting started with testing:

- [Svelte docs on testing](/docs/svelte/testing)
- [Setup Vitest using the Svelte CLI](/docs/cli/vitest)
- [Svelte Testing Library](https://testing-library.com/docs/svelte-testing-library/example/)
- [Svelte Component Testing in Cypress](https://docs.cypress.io/guides/component-testing/svelte/overview)
- [Example using uvu test runner with JSDOM](https://github.com/lukeed/uvu/tree/master/examples/svelte)
- [Test Svelte components using Vitest & Playwright](https://davipon.hashnode.dev/test-svelte-component-using-vitest-playwright)
- [Component testing with WebdriverIO](https://webdriver.io/docs/component-testing/svelte)

## Is there a router?

The official routing library is [SvelteKit](/docs/kit). SvelteKit provides a filesystem router, server-side rendering (SSR), and hot module reloading (HMR) in one easy-to-use package. It shares similarities with Next.js for React and Nuxt.js for Vue. SvelteKit also supports hash-based routing for client-side applications.

However, you can use any router library. A sampling of available routers are highlighted [on the packages page](/packages#routing).

## How do I write a mobile app with Svelte?

While most mobile apps are written without using JavaScript, if you'd like to leverage your existing Svelte components and knowledge of Svelte when building mobile apps, you can turn a [SvelteKit SPA](https://kit.svelte.dev/docs/single-page-apps) into a mobile app with [Tauri](https://v2.tauri.app/start/frontend/sveltekit/) or [Capacitor](https://capacitorjs.com/solution/svelte). Mobile features like the camera, geolocation, and push notifications are available via plugins for both platforms.

You can also write apps in Svelte that compiles to native components by using [Symbiote Native](https://docs.symbiote-native.dev/), which leverages the infrastructure provided by React Native.

Work has been completed towards [custom renderer support in Svelte 5](https://github.com/sveltejs/svelte/issues/15470), but this feature is not yet merged. The custom rendering API will allow support in additional mobile frameworks like Lynx JS and Svelte Native. Symbiote Native will also adopt this API. Svelte Native was an option available for Svelte 4, but Svelte 5 does not currently support it. Svelte Native lets you write NativeScript apps using Svelte components that contain [NativeScript UI components](https://docs.nativescript.org/ui/) rather than DOM elements.

## Can I tell Svelte not to remove my unused styles?

No. Svelte removes the styles from the component and warns you about them in order to prevent issues that would otherwise arise.

Svelte's component style scoping works by generating a class unique to the given component, adding it to the relevant elements in the component that are under Svelte's control, and then adding it to each of the selectors in that component's styles. When the compiler can't see what elements a style selector applies to, there would be two bad options for keeping it:

- If it keeps the selector and adds the scoping class to it, the selector will likely not match the expected elements in the component, and they definitely won't if they were created by a child component or `{@html ...}`.
- If it keeps the selector without adding the scoping class to it, the given style will become a global style, affecting your entire page.

If you need to style something that Svelte can't identify at compile time, you will need to explicitly opt into global styles by using `:global(...)`. But also keep in mind that you can wrap `:global(...)` around only part of a selector. `.foo :global(.bar) { ... }` will style any `.bar` elements that appear within the component's `.foo` elements. As long as there's some parent element in the current component to start from, partially global selectors like this will almost always be able to get you what you want.

## Is Svelte v2 still available?

New features aren't being added to it, and bugs will probably only be fixed if they are extremely nasty or present some sort of security vulnerability.

The documentation is still available [here](https://v2.svelte.dev/guide).

## How do I do hot module reloading?

We recommend using [SvelteKit](/docs/kit), which supports HMR out of the box and is built on top of [Vite](https://vitejs.dev/) and [svelte-hmr](https://github.com/sveltejs/svelte-hmr). There are also community plugins for [rollup](https://github.com/rixo/rollup-plugin-svelte-hot) and [webpack](https://github.com/sveltejs/svelte-loader).
`````

----
url: https://svelte.dev/docs/svelte/typescript/llms.txt
----

````
<!-- - [basically what we have today](https://svelte.dev/docs/typescript)
- built-in support, but only for type-only features
- generics
- using `Component` and the other helper types
- using `svelte-check` -->

You can use TypeScript within Svelte components. IDE extensions like the [Svelte VS Code extension](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode) will help you catch errors right in your editor, and [`svelte-check`](https://www.npmjs.com/package/svelte-check) does the same on the command line, which you can integrate into your CI.

## `<script lang="ts">`

To use TypeScript inside your Svelte components, add `lang="ts"` to your `script` tags:

```svelte
<script lang="ts">
	let name: string = 'world';

	function greet(name: string) {
		alert(`Hello, ${name}!`);
	}
</script>

<button onclick={(e: Event) => greet(e.target.innerText)}>
	{name as string}
</button>
```

Doing so allows you to use TypeScript's _type-only_ features. That is, all features that just disappear when transpiling to JavaScript, such as type annotations or interface declarations. Features that require the TypeScript compiler to output actual code are not supported. This includes:

- using enums
- using `private`, `protected` or `public` modifiers in constructor functions together with initializers
- using features that are not yet part of the ECMAScript standard (i.e. not level 4 in the TC39 process) and therefore not implemented yet within Acorn, the parser we use for parsing JavaScript

If you want to use one of these features, you need to setup up a `script` preprocessor.

## Preprocessor setup

To use non-type-only TypeScript features within Svelte components, you need to add a preprocessor that will turn TypeScript into JavaScript.

### Using Vite

If you're using SvelteKit, or Vite _without_ SvelteKit, you can use `vitePreprocess` from `@sveltejs/vite-plugin-svelte` in your config file:

```ts
/// file: svelte.config.js
// @noErrors
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';

const config = {
	// Note the additional `{ script: true }`
	preprocess: vitePreprocess({ script: true })
};

export default config;
```

### Using other build tools

If you're using tools like Rollup (via [rollup-plugin-svelte](https://github.com/sveltejs/rollup-plugin-svelte)) or Webpack (via [svelte-loader](https://github.com/sveltejs/svelte-loader)) instead, install `typescript` and `svelte-preprocess` and add the preprocessor to the plugin config. See the respective plugin READMEs for more info.

> [!NOTE] If you're starting a new project, we recommend using SvelteKit or Vite instead

## tsconfig.json settings

When using TypeScript, make sure your `tsconfig.json` is setup correctly.

- Use a [`target`](https://www.typescriptlang.org/tsconfig/#target) of at least `ES2015` so classes are not compiled to functions
- Set [`verbatimModuleSyntax`](https://www.typescriptlang.org/tsconfig/#verbatimModuleSyntax) to `true` so that imports are left as-is
- Set [`isolatedModules`](https://www.typescriptlang.org/tsconfig/#isolatedModules) to `true` so that each file is looked at in isolation. TypeScript has a few features which require cross-file analysis and compilation, which the Svelte compiler and tooling like Vite don't do.

## Typing `$props`

Type `$props` just like a regular object with certain properties.

```svelte
<script lang="ts">
	import type { Snippet } from 'svelte';

	interface Props {
		requiredProperty: number;
		optionalProperty?: boolean;
		snippetWithStringArgument: Snippet<[string]>;
		eventHandler: (arg: string) => void;
		[key: string]: unknown;
	}

	let {
		requiredProperty,
		optionalProperty,
		snippetWithStringArgument,
		eventHandler,
		...everythingElse
	}: Props = $props();
</script>

<button onclick={() => eventHandler('clicked button')}>
	{@render snippetWithStringArgument('hello')}
</button>
```

## Generic `$props`

Components can declare a generic relationship between their properties. One example is a generic list component that receives a list of items and a callback property that receives an item from the list. To declare that the `items` property and the `select` callback operate on the same types, add the `generics` attribute to the `script` tag:

```svelte
<script lang="ts" generics="Item extends { text: string }">
	interface Props {
		items: Item[];
		select(item: Item): void;
	}

	let { items, select }: Props = $props();
</script>

{#each items as item}
	<button onclick={() => select(item)}>
		{item.text}
	</button>
{/each}
```

The content of `generics` is what you would put between the `<...>` tags of a generic function. In other words, you can use multiple generics, `extends` and fallback types.

## Typing wrapper components

In case you're writing a component that wraps a native element, you may want to expose all the attributes of the underlying element to the user. In that case, use (or extend from) one of the interfaces provided by `svelte/elements`. Here's an example for a `Button` component:

```svelte
<script lang="ts">
	import type { HTMLButtonAttributes } from 'svelte/elements';

	let { children, ...rest }: HTMLButtonAttributes = $props();
</script>

<button {...rest}>
	{@render children?.()}
</button>
```

Not all elements have a dedicated type definition. For those without one, use `SvelteHTMLElements`:

```svelte
<script lang="ts">
	import type { SvelteHTMLElements } from 'svelte/elements';

	let { children, ...rest }: SvelteHTMLElements['div'] = $props();
</script>

<div {...rest}>
	{@render children?.()}
</div>
```

## Typing `$state`

You can type `$state` like any other variable.

```ts
let count: number = $state(0);
```

If you don't give `$state` an initial value, part of its types will be `undefined`.

```ts
// @noErrors
// Error: Type 'number | undefined' is not assignable to type 'number'
let count: number = $state();
```

You can pass the type directly as a generic parameter to safely handle this. TypeScript will infer the variable as `number | undefined`.

```ts
let count = $state<number>();
```

If you know that the variable _will_ be defined before you first use it, use an `as` casting. This is especially useful in the context of classes:

```ts
class Counter {
	count = $state() as number;
	constructor(initial: number) {
		this.count = initial;
	}
}
```

## The `Component` type

Svelte components are of type `Component`. You can use it and its related types to express a variety of constraints.

Using it together with dynamic components to restrict what kinds of component can be passed to it:

```svelte
<script lang="ts">
	import type { Component } from 'svelte';

	interface Props {
		// only components that have at most the "prop"
		// property required can be passed
		DynamicComponent: Component<{ prop: string }>;
	}

	let { DynamicComponent }: Props = $props();
</script>

<DynamicComponent prop="foo" />
```

> [!LEGACY] In Svelte 4, components were of type `SvelteComponent`

To extract the properties from a component, use `ComponentProps`.

```ts
import type { Component, ComponentProps } from 'svelte';
import MyComponent from './MyComponent.svelte';

function withProps<TComponent extends Component<any>>(
	component: TComponent,
	props: ComponentProps<TComponent>
) {}

// Errors if the second argument is not the correct props expected
// by the component in the first argument.
withProps(MyComponent, { foo: 'bar' });
```

To declare that a variable expects the constructor or instance type of a component:

```svelte
<script lang="ts">
	import MyComponent from './MyComponent.svelte';

	let componentConstructor: typeof MyComponent = MyComponent;
	let componentInstance: MyComponent;
</script>

<MyComponent bind:this={componentInstance} />
```

## Enhancing built-in DOM types

Svelte provides a best effort of all the HTML DOM types that exist. Sometimes you may want to use experimental attributes or custom events coming from an action. In these cases, TypeScript will throw a type error, saying that it does not know these types. If it's a non-experimental standard attribute/event, this may very well be a missing typing from our [HTML typings](https://github.com/sveltejs/svelte/blob/main/packages/svelte/elements.d.ts). In that case, you are welcome to open an issue and/or a PR fixing it.

In case this is a custom or experimental attribute/event, you can enhance the typings by augmenting the `svelte/elements` module like this:

```ts
/// file: additional-svelte-typings.d.ts
import { HTMLButtonAttributes } from 'svelte/elements';

declare module 'svelte/elements' {
	// add a new element
	export interface SvelteHTMLElements {
		'custom-button': HTMLButtonAttributes;
	}

	// add a new global attribute that is available on all html elements
	export interface HTMLAttributes<T> {
		globalattribute?: string;
	}

	// add a new attribute for button elements
	export interface HTMLButtonAttributes {
		veryexperimentalattribute?: string;
	}
}

export {}; // ensure this is not an ambient module, else types will be overridden instead of augmented
```

Then make sure that the `d.ts` file is referenced in your `tsconfig.json`. If it reads something like `"include": ["src/**/*"]` and your `d.ts` file is inside `src`, it should work. You may need to reload for the changes to take effect.
````

----
url: https://svelte.dev/docs/svelte/legacy-$$props-and-$$restProps/llms.txt
----

````
In runes mode, getting an object containing all the props that were passed in is easy, using the [`$props`]($props) rune.

In legacy mode, we use `$$props` and `$$restProps`:

- `$$props` contains all the props that were passed in, including ones that are not individually declared with the `export` keyword
- `$$restProps` contains all the props that were passed in _except_ the ones that were individually declared

For example, a `<Button>` component might need to pass along all its props to its own `<button>` element, except the `variant` prop:

```svelte
<script>
	export let variant;
</script>

<button {...$$restProps} class="variant-{variant} {$$props.class ?? ''}">
	click me
</button>

<style>
	.variant-danger {
		background: red;
	}
</style>
```

In Svelte 3/4 using `$$props` and `$$restProps` creates a modest performance penalty, so they should only be used when needed.
````

----
url: https://svelte.dev/docs/svelte/global-styles
----

[Skip to main content](#main)

## :global(...)[](#:global\(\))

To apply styles to a single selector globally, use the `:global(...)` modifier:

```
<style>
	:global(body) {
		/* applies to <body> */
		margin: 0;
	}

	div :global(strong) {
		/* applies to all <strong> elements, in any component,
		   that are inside <div> elements belonging
		   to this component */
		color: goldenrod;
	}

	p:global(.big.red) {
		/* applies to all <p> elements belonging to this component
		   with `class="big red"`, even if it is applied
		   programmatically (for example by a library) */
	}
</style>
```

If you want to make @keyframes that are accessible globally, you need to prepend your keyframe names with `-global-`.

The `-global-` part will be removed when compiled, and the keyframe will then be referenced using just `my-animation-name` elsewhere in your code.

```
<style>
	@keyframes -global-my-animation-name {
		/* code goes here */
	}
</style>
```

## :global[](#:global)

To apply styles to a group of selectors globally, create a `:global {...}` block:

```
<style>
	:global {
		/* applies to every <div> in your application */
		div { ... }

		/* applies to every <p> in your application */
		p { ... }
	}

	.a :global {
		/* applies to every `.b .c .d` element, in any component,
		   that is inside an `.a` element in this component */
		.b .c .d {...}
	}
</style>
```

> The second example above could also be written as an equivalent `.a :global .b .c .d` selector, where everything after the `:global` is unscoped, though the nested form is preferred.

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/04-styling/02-global-styles.md) [llms.txt](/docs/svelte/global-styles/llms.txt)

previous next

[Scoped styles](/docs/svelte/scoped-styles) [Custom properties](/docs/svelte/custom-properties)

----
url: https://svelte.dev/docs/svelte/$host
----

[Skip to main content](#main)

When compiling a component as a [custom element](custom-elements), the `$host` rune provides access to the host element, allowing you to (for example) dispatch custom events ([demo](/playground/untitled#H4sIAAAAAAAAE41Ry2rDMBD8FSECtqkTt1fHFpSSL-ix7sFRNkTEXglrnTYY_3uRlDgxTaEHIfYxs7szA9-rBizPPwZOZwM89wmecqxbF70as7InaMjltrWFR3mpkQDJ8pwXVnbKkKiwItUa3RGLVtk7gTHQXRDR2lXda4CY1D0SK9nCUk0QPyfrCovsRoNFe17aQOAwGncgO2gBqRzihJXiQrEs2csYOhQ-7HgKHaLIbpRhhBG-I2eD_8ciM4KnnOCbeE5dD2P6h0Dz0-Yi_arNhPLJXBtSGi2TvSXdbpqwdsXvjuYsC1veabvvUTog2ylrapKH2G2XsMFLS4uDthQnq2t1cwKkGOGLvYU5PvaQxLsxOkPmsm97Io1Mo2yUPF6VnOZFkw1RMoopKLKAE_9gmGxyDFMwMcwN-Bx_ABXQWmOtAgAA)):

Stepper

```
<svelte:options customElement="my-stepper" />

<script>
	function dispatch(type) {
		$host().dispatchEvent(new CustomEvent(type));
	}
</script>

<button onclick={() => dispatch('decrement')}>decrement</button>
<button onclick={() => dispatch('increment')}>increment</button>
```

```
<svelte:options customElement="my-stepper" />

<script lang="ts">
	function dispatch(type) {
		$host().dispatchEvent(new CustomEvent(type));
	}
</script>

<button onclick={() => dispatch('decrement')}>decrement</button>
<button onclick={() => dispatch('increment')}>increment</button>
```

App

```
<script>
	import './Stepper.svelte';

	let count = $state(0);
</script>

<my-stepper
	ondecrement={() => count -= 1}
	onincrement={() => count += 1}
></my-stepper>

<p>count: {count}</p>
```

```
<script lang="ts">
	import './Stepper.svelte';

	let count = $state(0);
</script>

<my-stepper
	ondecrement={() => count -= 1}
	onincrement={() => count += 1}
></my-stepper>

<p>count: {count}</p>
```

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/02-runes/08-$host.md) [llms.txt](/docs/svelte/$host/llms.txt)

previous next

[$inspect](/docs/svelte/$inspect) [Basic markup](/docs/svelte/basic-markup)

----
url: https://svelte.dev/docs/svelte/legacy-on
----

[Skip to main content](#main)

In runes mode, event handlers are just like any other attribute or prop.

In legacy mode, we use the `on:` directive:

App

```
<script>
	let count = 0;

	/** @param {MouseEvent} event */
	function handleClick(event) {
		count += 1;
	}
</script>

<button on:click={handleClick}>
	count: {count}
</button>
```

```
<script lang="ts">
	let count = 0;

	function handleClick(event: MouseEvent) {
		count += 1;
	}
</script>

<button on:click={handleClick}>
	count: {count}
</button>
```

Handlers can be declared inline with no performance penalty:

```
<button on:click={() => (count += 1)}>
	count: {count}
</button>
```

Add *modifiers* to element event handlers with the `|` character.

```
<form on:submit|preventDefault={handleSubmit}>
	<!-- the `submit` event's default is prevented,
	     so the page won't reload -->
</form>
```

The following modifiers are available:

* `preventDefault` — calls `event.preventDefault()` before running the handler
* `stopPropagation` — calls `event.stopPropagation()`, preventing the event reaching the next element
* `stopImmediatePropagation` — calls `event.stopImmediatePropagation()`, preventing other listeners of the same event from being fired.
* `passive` — improves scrolling performance on touch/wheel events (Svelte will add it automatically where it’s safe to do so)
* `nonpassive` — explicitly set `passive: false`
* `capture` — fires the handler during the *capture* phase instead of the *bubbling* phase
* `once` — remove the handler after the first time it runs
* `self` — only trigger handler if `event.target` is the element itself
* `trusted` — only trigger handler if `event.isTrusted` is `true`. I.e. if the event is triggered by a user action.

Modifiers can be chained together, e.g. `on:click|once|capture={...}`.

If the `on:` directive is used without a value, the component will *forward* the event, meaning that a consumer of the component can listen for it.

```
<button on:click>
	The component itself will emit the click event
</button>
```

It’s possible to have multiple event listeners for the same event:

App

```
<script>
	let count = 0;

	function increment() {
		count += 1;
	}

	/** @param {MouseEvent} event */
	function log(event) {
		console.log(event);
	}
</script>

<button on:click={increment} on:click={log}>
	clicks: {count}
</button>
```

```
<script lang="ts">
	let count = 0;

	function increment() {
		count += 1;
	}

	function log(event: MouseEvent) {
		console.log(event);
	}
</script>

<button on:click={increment} on:click={log}>
	clicks: {count}
</button>
```

## Component events[](#Component-events)

Components can dispatch events by creating a *dispatcher* when they are initialised:

Stepper

```
<script>
	import { createEventDispatcher } from 'svelte';
	const dispatch = createEventDispatcher();
</script>

<button on:click={() => dispatch('decrement')}>decrement</button>
<button on:click={() => dispatch('increment')}>increment</button>
```

```
<script lang="ts">
	import { createEventDispatcher } from 'svelte';
	const dispatch = createEventDispatcher();
</script>

<button on:click={() => dispatch('decrement')}>decrement</button>
<button on:click={() => dispatch('increment')}>increment</button>
```

`dispatch` creates a [`CustomEvent`](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent). If a second argument is provided, it becomes the `detail` property of the event object.

A consumer of this component can listen for the dispatched events:

```
<script>
	import Stepper from './Stepper.svelte';

	let n = 0;
</script>

<Stepper
	on:decrement={() => n -= 1}
	on:increment={() => n += 1}
/>

<p>n: {n}</p>
```

Component events do not bubble — a parent component can only listen for events on its immediate children.

Other than `once`, modifiers are not valid on component event handlers.

> If you’re planning an eventual migration to Svelte 5, use callback props instead. This will make upgrading easier as `createEventDispatcher` is deprecated:
>
> Stepper
>
> ```
> <script>
> 	export let decrement;
> 	export let increment;
> </script>
>
> <button on:click={decrement}>decrement</button>
> <button on:click={increment}>increment</button>
> ```
>
> ```
> <script lang="ts">
> 	export let decrement;
> 	export let increment;
> </script>
>
> <button on:click={decrement}>decrement</button>
> <button on:click={increment}>increment</button>
> ```

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/99-legacy/10-legacy-on.md) [llms.txt](/docs/svelte/legacy-on/llms.txt)

previous next

[$$props and $$restProps](/docs/svelte/legacy-$$props-and-$$restProps) [\<slot>](/docs/svelte/legacy-slots)

----
url: https://svelte.dev/docs/svelte/svelte-animate
----

[Skip to main content](#main)

```
import { flip(alias) function flip(node: Element, { from, to }: {
    from: DOMRect;
    to: DOMRect;
}, params?: FlipParams): AnimationConfig
import flip

The flip function calculates the start and end position of an element and animates between them, translating the x and y values.
flip stands for First, Last, Invert, Play.


reference } from 'svelte/animate';
```

## flip[](#flip)

The flip function calculates the start and end position of an element and animates between them, translating the x and y values. `flip` stands for [First, Last, Invert, Play](https://aerotwist.com/blog/flip-your-animations/).

```
function flip(
	node: Element,
	{
		from,
		to
	}: {
		from: DOMRect;
		to: DOMRect;
	},
	params?: FlipParams
): AnimationConfig;
```

## AnimationConfig[](#AnimationConfig)

```
interface AnimationConfig {/*…*/}
```

```
delay?: number;
```

```
duration?: number;
```

```
easing?: (t: number) => number;
```

```
css?: (t: number, u: number) => string;
```

```
tick?: (t: number, u: number) => void;
```

## FlipParams[](#FlipParams)

```
interface FlipParams {/*…*/}
```

```
delay?: number;
```

```
duration?: number | ((len: number) => number);
```

```
easing?: (t: number) => number;
```

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/98-reference/21-svelte-animate.md) [llms.txt](/docs/svelte/svelte-animate/llms.txt)

previous next

[svelte/action](/docs/svelte/svelte-action) [svelte/attachments](/docs/svelte/svelte-attachments)

----
url: https://svelte.dev/docs/svelte/imperative-component-api/llms.txt
----

````
<!-- better title needed?

- mount
- unmount
- render
- hydrate
- how they interact with each other -->

Every Svelte application starts by imperatively creating a root component. On the client this component is mounted to a specific element. On the server, you want to get back a string of HTML instead which you can render. The following functions help you achieve those tasks.

## `mount`

Instantiates a component and mounts it to the given target:

```js
// @errors: 2322
import { mount } from 'svelte';
import App from './App.svelte';

const app = mount(App, {
	target: document.querySelector('#app'),
	props: { some: 'property' }
});
```

You can mount multiple components per page, and you can also mount from within your application, for example when creating a tooltip component and attaching it to the hovered element.

Note that unlike calling `new App(...)` in Svelte 4, things like effects (including `onMount` callbacks, and action functions) will not run during `mount`. If you need to force pending effects to run (in the context of a test, for example) you can do so with `flushSync()`.

## `unmount`

Unmounts a component that was previously created with [`mount`](#mount) or [`hydrate`](#hydrate).

If `options.outro` is `true`, [transitions](transition) will play before the component is removed from the DOM:

```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 have completed if `options.outro` is true, or immediately otherwise.

## `render`

Only available on the server and when compiling with the `server` option. Takes a component and returns an object with `body` and `head` properties on it, which you can use to populate the HTML when server-rendering your app:

```js
// @errors: 2724 2305 2307
import { render } from 'svelte/server';
import App from './App.svelte';

const result = render(App, {
	props: { some: 'property' }
});
result.body; // HTML for somewhere in this <body> tag
result.head; // HTML for somewhere in this <head> tag
```

## `hydrate`

Like `mount`, but will reuse up any HTML rendered by Svelte's SSR output (from the [`render`](#render) function) inside the target and make it interactive:

```js
// @errors: 2322
import { hydrate } from 'svelte';
import App from './App.svelte';

const app = hydrate(App, {
	target: document.querySelector('#app'),
	props: { some: 'property' }
});
```

As with `mount`, effects will not run during `hydrate` — use `flushSync()` immediately afterwards if you need them to.
````

----
url: https://svelte.dev/docs/svelte/$bindable/llms.txt
----

````
Ordinarily, props go one way, from parent to child. This makes it easy to understand how data flows around your app.

In Svelte, component props can be _bound_, which means that data can also flow _up_ from child to parent. This isn't something you should do often — overuse can make your data flow unpredictable and your components harder to maintain — but it can simplify your code if used sparingly and carefully.

It also means that a state proxy can be _mutated_ in the child.

> [!NOTE] Mutation is also possible with normal props, but is strongly discouraged — Svelte will warn you if it detects that a component is mutating state it does not 'own'.

To mark a prop as bindable, we use the `$bindable` rune:

<!-- prettier-ignore -->
```svelte
/// file: FancyInput.svelte
<script>
	let { value = $bindable(), ...props } = $props();
</script>

<input bind:value={value} {...props} />

<style>
	input {
		font-family: 'Comic Sans MS';
		color: deeppink;
	}
</style>
```

Now, a component that uses `<FancyInput>` can add the [`bind:`](bind) directive (demo:

<!-- prettier-ignore -->
```svelte
/// file: App.svelte
<script>
	import FancyInput from './FancyInput.svelte';

	let message = $state('hello');
</script>

<FancyInput bind:value={message} />
<p>{message}</p>
```

The parent component doesn't _have_ to use `bind:` — it can just pass a normal prop. Some parents don't want to listen to what their children have to say.

In this case, you can specify a fallback value for when no prop is passed at all:

```js
/// file: FancyInput.svelte
let { value = $bindable('fallback'), ...props } = $props();
```

When a bindable prop has a fallback value, the parent must pass a value other than `undefined` if it uses `bind:`. This avoids ambiguity about which value should apply, since the parent and child should share the same value for a binding.
````

----
url: https://svelte.dev/docs/svelte/if
----

[Skip to main content](#main)

```
{#if expression}...{/if}
```

```
{#if expression}...{:else if expression}...{/if}
```

```
{#if expression}...{:else}...{/if}
```

Content that is conditionally rendered can be wrapped in an if block.

```
{#if answer === 42}
	<p>what was the question?</p>
{/if}
```

Additional conditions can be added with `{:else if expression}`, optionally ending in an `{:else}` clause.

```
{#if porridge.temperature > 100}
	<p>too hot!</p>
{:else if 80 > porridge.temperature}
	<p>too cold!</p>
{:else}
	<p>just right!</p>
{/if}
```

(Blocks don’t have to wrap elements, they can also wrap text within elements.)

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/03-template-syntax/02-if.md) [llms.txt](/docs/svelte/if/llms.txt)

previous next

[Basic markup](/docs/svelte/basic-markup) [{#each ...}](/docs/svelte/each)

----
url: https://svelte.dev/docs/svelte/transition/llms.txt
----

````
A _transition_ is triggered by an element entering or leaving the DOM as a result of a state change.

When a block (such as an `{#if ...}` block) is transitioning out, all elements inside it, including those that do not have their own transitions, are kept in the DOM until every transition in the block has been completed.

The `transition:` directive indicates a _bidirectional_ transition, which means it can be smoothly reversed while the transition is in progress.

```svelte
<script>
	+++import { fade } from 'svelte/transition';+++

	let visible = $state(false);
</script>

<button onclick={() => visible = !visible}>toggle</button>

{#if visible}
	<div +++transition:fade+++>fades in and out</div>
{/if}
```

## Local vs global

Transitions are local by default. Local transitions only play when the block they belong to is created or destroyed, _not_ when parent blocks are created or destroyed.

```svelte
{#if x}
	{#if y}
		<p transition:fade>fades in and out only when y changes</p>

		<p transition:fade|global>fades in and out when x or y change</p>
	{/if}
{/if}
```

## Built-in transitions

A selection of built-in transitions can be imported from the [`svelte/transition`](svelte-transition) module.

## Transition parameters

Transitions can have parameters.

(The double `{{curlies}}` aren't a special syntax; this is an object literal inside an expression tag.)

```svelte
{#if visible}
	<div transition:fade={{ duration: 2000 }}>fades in and out over two seconds</div>
{/if}
```

## Accessibility

Transitions are driven by the [Web Animations API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API) rather than by CSS. A global `@media (prefers-reduced-motion: reduce)` rule that zeroes `transition-duration` and `animation-duration` therefore has no effect on them.

Use [`prefersReducedMotion`](svelte-motion#prefersReducedMotion) to adjust (or completely disable) the transition accordingly for devices who request reduced motion.

## Custom transition functions

```js
/// copy: false
// @noErrors
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
}
```

Transitions can use custom functions. If the returned object has a `css` function, Svelte will generate keyframes for a [web animation](https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API).

The `t` argument passed to `css` is a value between `0` and `1` after the `easing` function has been applied. _In_ transitions run from `0` to `1`, _out_ transitions run from `1` to `0` — in other words, `1` is the element's natural state, as though no transition had been applied. The `u` argument is equal to `1 - t`.

The function is called repeatedly _before_ the transition begins, with different `t` and `u` arguments.

```svelte
<!--- file: App.svelte --->
<script>
	import { elasticOut } from 'svelte/easing';

	/** @type {boolean} */
	export let visible;

	/**
	 * @param {HTMLElement} node
	 * @param {{ delay?: number, duration?: number, easing?: (t: number) => number }} params
	 */
	function whoosh(node, params) {
		const existingTransform = getComputedStyle(node).transform.replace('none', '');

		return {
			delay: params.delay || 0,
			duration: params.duration || 400,
			easing: params.easing || elasticOut,
			css: (t, u) => `transform: ${existingTransform} scale(${t})`
		};
	}
</script>

{#if visible}
	<div in:whoosh>whooshes in</div>
{/if}
```

A custom transition function can also return a `tick` function, which is called _during_ the transition with the same `t` and `u` arguments.

> [!NOTE] If it's possible to use `css` instead of `tick`, do so — web animations can run off the main thread, preventing jank on slower devices.

```svelte
<!--- file: App.svelte --->
<script>
	export let visible = false;

	/**
	 * @param {HTMLElement} node
	 * @param {{ speed?: number }} params
	 */
	function typewriter(node, { speed = 1 }) {
		const valid = node.childNodes.length === 1 && node.childNodes[0].nodeType === Node.TEXT_NODE;

		if (!valid) {
			throw new Error(`This transition only works on elements with a single text node child`);
		}

		const text = node.textContent;
		const duration = text.length / (speed * 0.01);

		return {
			duration,
			tick: (t) => {
				const i = ~~(text.length * t);
				node.textContent = text.slice(0, i);
			}
		};
	}
</script>

{#if visible}
	<p in:typewriter={{ speed: 1 }}>The quick brown fox jumps over the lazy dog</p>
{/if}
```

If a transition returns a function instead of a transition object, the function will be called in the next microtask. This allows multiple transitions to coordinate, making [crossfade effects](/tutorial/deferred-transitions) possible.

Transition functions also receive a third argument, `options`, which contains information about the transition.

Available values in the `options` object are:

- `direction` - one of `in`, `out`, or `both` depending on the type of transition

## Transition events

An element with transitions will dispatch the following events in addition to any standard DOM events:

- `introstart`
- `introend`
- `outrostart`
- `outroend`

```svelte
{#if visible}
	<p
		transition:fly={{ y: 200, duration: 2000 }}
		onintrostart={() => (status = 'intro started')}
		onoutrostart={() => (status = 'outro started')}
		onintroend={() => (status = 'intro ended')}
		onoutroend={() => (status = 'outro ended')}
	>
		Flies in and out
	</p>
{/if}
```
````

----
url: https://svelte.dev/docs/svelte/legacy-$$props-and-$$restProps
----

[Skip to main content](#main)

In runes mode, getting an object containing all the props that were passed in is easy, using the [`$props`]($props) rune.

In legacy mode, we use `$$props` and `$$restProps`:

* `$$props` contains all the props that were passed in, including ones that are not individually declared with the `export` keyword
* `$$restProps` contains all the props that were passed in *except* the ones that were individually declared

For example, a `<Button>` component might need to pass along all its props to its own `<button>` element, except the `variant` prop:

```
<script>
	export let variant;
</script>

<button {...$$restProps} class="variant-{variant} {$$props.class ?? ''}">
	click me
</button>

<style>
	.variant-danger {
		background: red;
	}
</style>
```

In Svelte 3/4 using `$$props` and `$$restProps` creates a modest performance penalty, so they should only be used when needed.

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/99-legacy/04-legacy-$$props-and-$$restProps.md) [llms.txt](/docs/svelte/legacy-$$props-and-$$restProps/llms.txt)

previous next

[export let](/docs/svelte/legacy-export-let) [on:](/docs/svelte/legacy-on)

----
url: https://svelte.dev/docs/svelte/lifecycle-hooks
----

[Skip to main content](#main)

In Svelte 5, the component lifecycle consists of only two parts: Its creation and its destruction. Everything in-between — when certain state is updated — is not related to the component as a whole; only the parts that need to react to the state change are notified. This is because under the hood the smallest unit of change is actually not a component, it’s the (render) effects that the component sets up upon component initialization. Consequently, there’s no such thing as a “before update”/”after update” hook.

## onMount[](#onMount)

The `onMount` function schedules a callback to run as soon as the component has been mounted to the DOM. It must be called during the component’s initialisation (but doesn’t need to live *inside* the component; it can be called from an external module).

`onMount` does not run inside a component that is rendered on the server.

```
<script>
	import { onMount } from 'svelte';

	onMount(() => {
		console.log('the component has mounted');
	});
</script>
```

If a function is returned from `onMount`, it will be called when the component is unmounted.

```
<script>
	import { onMount } from 'svelte';

	onMount(() => {
		const interval = setInterval(() => {
			console.log('beep');
		}, 1000);

		return () => clearInterval(interval);
	});
</script>
```

> This behaviour will only work when the function passed to `onMount` is *synchronous*. `async` functions always return a `Promise`.

## onDestroy[](#onDestroy)

Schedules a callback to run immediately before the component is unmounted.

Out of `onMount`, `beforeUpdate`, `afterUpdate` and `onDestroy`, this is the only one that runs inside a server-side component.

```
<script>
	import { onDestroy } from 'svelte';

	onDestroy(() => {
		console.log('the component is being destroyed');
	});
</script>
```

## tick[](#tick)

While there’s no “after update” hook, you can use `tick` to ensure that the UI is updated before continuing. `tick` returns a promise that resolves once any pending state changes have been applied, or in the next microtask if there are none.

```
<script>
	import { tick } from 'svelte';

	$effect.pre(() => {
		console.log('the component is about to update');
		tick().then(() => {
				console.log('the component just updated');
		});
	});
</script>
```

## Deprecated: beforeUpdate / afterUpdate[](#Deprecated:-beforeUpdate-afterUpdate)

Svelte 4 contained hooks that ran before and after the component as a whole was updated. For backwards compatibility, these hooks were shimmed in Svelte 5 but not available inside components that use runes.

```
<script>
	import { beforeUpdate, afterUpdate } from 'svelte';

	beforeUpdate(() => {
		console.log('the component is about to update');
	});

	afterUpdate(() => {
		console.log('the component just updated');
	});
</script>
```

Instead of `beforeUpdate` use `$effect.pre` and instead of `afterUpdate` use `$effect` instead — these runes offer more granular control and only react to the changes you’re actually interested in.

### Chat window example[](#Deprecated:-beforeUpdate-afterUpdate-Chat-window-example)

To implement a chat window that autoscrolls to the bottom when new messages appear (but only if you were *already* scrolled to the bottom), we need to measure the DOM before we update it.

In Svelte 4, we do this with `beforeUpdate`, but this is a flawed approach — it fires before *every* update, whether it’s relevant or not. In the example below, we need to introduce checks like `updatingMessages` to make sure we don’t mess with the scroll position when someone toggles dark mode.

With runes, we can use `$effect.pre`, which behaves the same as `$effect` but runs before DOM updates scheduled after it (see [$effect.pre]($effect#$effect.pre) for the exact ordering). As long as we explicitly reference `messages` inside the effect body, it will run whenever `messages` changes, but *not* when `theme` changes.

`beforeUpdate`, and its equally troublesome counterpart `afterUpdate`, are therefore deprecated in Svelte 5.

* [Before](/playground/untitled#H4sIAAAAAAAAE31WXa_bNgz9K6yL1QmWOLlrC-w6H8MeBgwY9tY9NfdBtmlbiywZkpyPBfnvo2zLcZK28AWuRPGI5OGhkEuQc4EmiL9eAskqDOLg97oOZoE9125jDigs0t6oRqfOsjap5rXd7uTO8qpW2sIFEsyVxn_qjFmcAcstar-xPN3DFXKtKgi768IVgQku0ELj3Lgs_kZjWIEGNpAzYXDlHWyJFZI1zJjeh4O5uvl_DY8oUkVeVoFuJKYls-_CGYS25Aboj0EtWNqel0wWoBoLTGZgmdgDS9zW4Uz4NsrswPHoyutN4xInkylstnBxdmIhh8m7xzqmoNE2Wq46n1RJQzEbq4g-JQSl7e-HDx-GdaTy3KD9E3lRWvj5Zu9QX1QN20dj7zyHz8s-1S6lW7Cpz3RnXTcm04hIlfdFuO8p2mQ5-3a06cqjrn559bF_2NHOnRZ5I1PLlXQNyQT-hedMHeUEDyjtdMxsa4n2eIbNhlTwhyRthaOKOmYtniwF6pwt0wXa6MBEg0OibZec27gz_dk3UrZ6hB2LLYoiv521Yd8Gt-foTrfhiCDP0lC9VUUhcDLU49Xe_9943cNvEArHfAjxeBTovvXiNpFynfEDpIIZs9kFbg52QbeNHWZzebz32s7xHco3nJAJl1nshmhz8dYOQJDyZetnbb2gTWe-vEeWlrfpZMavr56ldb29eNt6UXvgwgFbp_WC0tl2RK25rGk6lYz3nUI2lzvBXGHhPZPGWmKUXFNBKqdaW259wl_aHbiqoVIZdpE60Nax6IOujT0LbFFxIVTCxCRR2XloUcYNvSbnGHKBp763jHoj59xiZWJI0Wm0P_m3MSS985xkasn-cFq20xTDy3J5KFcjgUTD69BHdcHIjz431z28IqlxGcPSfdFnrGDZn6gD6lyo45zyHAD-btczf-98nhQxHEvKfeUtOVkSejD3q-9X7JbzjGtsdUxlKdFU8qGsT78uaw848syWMXz85Waq2Gnem4mAn3prweq4q6Y3JEpnqMmnPoFRgmd3ySW0LLRqSKlwYHriCvJvUs2yjMaaoA-XzTXLeGMe45zmhv_XAno3Mj0xF7USuqNvnE9H343QHlq-eAgxpbTPNR9yzUkgLjwSR0NK4wKoxy-jDg-9vy8sUSToakzW-9fX13Em9Q8T6Z26uZhBN36XUYo5q7ggLXBZoub2Ofv7g6GCZfTxe034NCjiudXj7Omla0eTfo7QBPOcYxbE7qG-vl3_B1G-_i_JCAAA)
* [After](/playground/untitled#H4sIAAAAAAAAE31WXa-jNhD9K7PsdknUQJLurtRLPqo-VKrU1327uQ8GBnBjbGSb5KZR_nvHgMlXtyIS9njO-MyZGZRzUHCBJkhez4FkNQZJ8HvTBLPAnhq3MQcUFmlvVKszZ1mbTPPGbndyZ3ndKG3hDJZne7hAoVUNYY8JV-RBPgIt2AprhA18MpZZnIQ50_twuvLHNRrDSjRXj9fwiCJTBLIKdCsxq5j9EM4gtBU3QD8GjWBZd14xWYJqLTCZg2ViDyx1W4cz4dv0hsiB49FRHkyfsCgws3GjcTKZwmYLZ2feWc9o1W8zJQ2Fb62i5JUQRNRHgs-fx3WsisKg_RN5WVn4-WrvUd9VA9tH4-AcwbfFQIpkLWByvWzqSe2sk3kyjUlOec_XPU-3TRaz_75tuvKoi19e3OvipSpamVmupJM2F_gXnnJ1lBM8oLQjHceys8R7PMFms4HwD2lRhzeEe-EsvluSrHe2TJdo4wMTLY48XKwPzm0KGm2r5ajFtRYU4TWOY7-ddWHfxhDP0QkQhnf5PWRnVVkKnIx8fZsOb5dR16nwG4TCCRdCMphWQ7z1_DoOcp3zA2SCGbPZBa5jd0G_TRxmc36Me-mG6A7l60XIlMs8ce2-OXtrDyBItdz6qVjPadObzx-RZdV1nJjx64tXad1sz962njceOHfAzmk9JzrbXqg1lw3NkZL7vgE257t-uMDcO6attSSokpmgFqVMO2U93e_dDlzOUKsc-3t6zNZp6K9cG3sS2KGSUqiUiUmq8tNYoJwbmvpTAoXA96GyjCojI26xNglk6DpwOPm7NdRYp4ia0JL94bTqRiGB5WJxqFY37RGPoz3c6i4jP3rcUA7wmhqNywQW7om_YQ2L4UQdUBdCHSPiOQJ8bFcxHzeK0jKBY0XcV95SkCWlD9t-9eOM3TLKucauiyktJdpaPqT19ddF4wFHntsqgS-_XE01e48GMwnw02AtWZP02QyGVOkcNfk072CU4PkduZSWpVYt9SkcmJ64hPwHpWF5ziVls3wIFmmW89Y83vMeGf5PBxjcyPSkXNy10J18t3x6-a6CDtBq6SGklNKeazFyLahB3PVIGo2UbhOgGi9vKjzW_j6xVFFD17difXx5ebll0vwvkcGpn4sZ9MN3vqFYsJoL6gUuK9TcPrO_PxgzWMRfflSEr2NHPJf6lj1957rRpH8CNMG84JgHidUtXt4u_wK21LXERAgAAA==)

```
<script>
	import { beforeUpdate, afterUpdate, tick } from 'svelte';

	let updatingMessages = false;
	let theme = $state('dark');
	let messages = $state([]);

	let viewport;

	beforeUpdate(() => {
	$effect.pre(() => {
		if (!updatingMessages) return;
		messages;
		const autoscroll = viewport && viewport.offsetHeight + viewport.scrollTop > viewport.scrollHeight - 50;

		if (autoscroll) {
			tick().then(() => {
				viewport.scrollTo(0, viewport.scrollHeight);
			});
		}

		updatingMessages = false;
	});

	function handleKeydown(event) {
		if (event.key === 'Enter') {
			const text = event.target.value;
			if (!text) return;

			updatingMessages = true;
			messages = [...messages, text];
			event.target.value = '';
		}
	}

	function toggle() {
		theme = theme === 'dark' ? 'light' : 'dark';
	}
</script>

<div class:dark={theme === 'dark'}>
	<div bind:this={viewport}>
		{#each messages as message}
			<p>{message}</p>
		{/each}
	</div>

	<input onkeydown={handleKeydown} />

	<button onclick={toggle}> Toggle dark mode </button>
</div>
```

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/06-runtime/03-lifecycle-hooks.md) [llms.txt](/docs/svelte/lifecycle-hooks/llms.txt)

previous next

[Context](/docs/svelte/context) [Imperative component API](/docs/svelte/imperative-component-api)

----
url: https://svelte.dev/docs/svelte/scoped-styles/llms.txt
----

````
Svelte components can include a `<style>` element containing CSS that belongs to the component. This CSS is _scoped_ by default, meaning that styles will not apply to any elements on the page outside the component in question.

This works by adding a class to affected elements, which is based on a hash of the component styles (e.g. `svelte-123xyz`).

```svelte
<style>
	p {
		/* this will only affect <p> elements in this component */
		color: burlywood;
	}
</style>
```

## Specificity

Each scoped selector receives a [specificity](https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity) increase of 0-1-0, as a result of the scoping class (e.g. `.svelte-123xyz`) being added to the selector. This means that (for example) a `p` selector defined in a component will take precedence over a `p` selector defined in a global stylesheet, even if the global stylesheet is loaded later.

In some cases, the scoping class must be added to a selector multiple times, but after the first occurrence it is added with `:where(.svelte-xyz123)` in order to not increase specificity further.

## Scoped keyframes

If a component defines `@keyframes`, the name is scoped to the component using the same hashing approach. Any `animation` rules in the component will be similarly adjusted:

```svelte
<style>
	.bouncy {
		animation: bounce 10s;
	}

	/* these keyframes are only accessible inside this component */
	@keyframes bounce {
		/* ... */
	}
</style>
```
````

----
url: https://svelte.dev/docs/svelte/svelte-body
----

[Skip to main content](#main)

```
<svelte:body onevent={handler} />
```

Similarly to `<svelte:window>`, this element allows you to add listeners to events on `document.body`, such as `mouseenter` and `mouseleave`, which don’t fire on `window`. It also lets you use [actions](use) on the `<body>` element.

As with `<svelte:window>` and `<svelte:document>`, this element may only appear at the top level of your component and must never be inside a block or element.

```
<svelte:body onmouseenter={handleMouseenter} onmouseleave={handleMouseleave} use:someAction />
```

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/05-special-elements/04-svelte-body.md) [llms.txt](/docs/svelte/svelte-body/llms.txt)

previous next

[\<svelte:document>](/docs/svelte/svelte-document) [\<svelte:head>](/docs/svelte/svelte-head)

----
url: https://svelte.dev/docs/svelte/legacy-on/llms.txt
----

````
In runes mode, event handlers are just like any other attribute or prop.

In legacy mode, we use the `on:` directive:

```svelte
<!--- file: App.svelte --->
<script>
	let count = 0;

	/** @param {MouseEvent} event */
	function handleClick(event) {
		count += 1;
	}
</script>

<button on:click={handleClick}>
	count: {count}
</button>
```

Handlers can be declared inline with no performance penalty:

```svelte
<button on:click={() => (count += 1)}>
	count: {count}
</button>
```

Add _modifiers_ to element event handlers with the `|` character.

```svelte
<form on:submit|preventDefault={handleSubmit}>
	<!-- the `submit` event's default is prevented,
	     so the page won't reload -->
</form>
```

The following modifiers are available:

- `preventDefault` — calls `event.preventDefault()` before running the handler
- `stopPropagation` — calls `event.stopPropagation()`, preventing the event reaching the next element
- `stopImmediatePropagation` — calls `event.stopImmediatePropagation()`, preventing other listeners of the same event from being fired.
- `passive` — improves scrolling performance on touch/wheel events (Svelte will add it automatically where it's safe to do so)
- `nonpassive` — explicitly set `passive: false`
- `capture` — fires the handler during the _capture_ phase instead of the _bubbling_ phase
- `once` — remove the handler after the first time it runs
- `self` — only trigger handler if `event.target` is the element itself
- `trusted` — only trigger handler if `event.isTrusted` is `true`. I.e. if the event is triggered by a user action.

Modifiers can be chained together, e.g. `on:click|once|capture={...}`.

If the `on:` directive is used without a value, the component will _forward_ the event, meaning that a consumer of the component can listen for it.

```svelte
<button on:click>
	The component itself will emit the click event
</button>
```

It's possible to have multiple event listeners for the same event:

```svelte
<!--- file: App.svelte --->
<script>
	let count = 0;

	function increment() {
		count += 1;
	}

	/** @param {MouseEvent} event */
	function log(event) {
		console.log(event);
	}
</script>

<button on:click={increment} on:click={log}>
	clicks: {count}
</button>
```

## Component events

Components can dispatch events by creating a _dispatcher_ when they are initialised:

```svelte
<!--- file: Stepper.svelte -->
<script>
	import { createEventDispatcher } from 'svelte';
	const dispatch = createEventDispatcher();
</script>

<button on:click={() => dispatch('decrement')}>decrement</button>
<button on:click={() => dispatch('increment')}>increment</button>
```

`dispatch` creates a [`CustomEvent`](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent). If a second argument is provided, it becomes the `detail` property of the event object.

A consumer of this component can listen for the dispatched events:

```svelte
<script>
	import Stepper from './Stepper.svelte';

	let n = 0;
</script>

<Stepper
	on:decrement={() => n -= 1}
	on:increment={() => n += 1}
/>

<p>n: {n}</p>
```

Component events do not bubble — a parent component can only listen for events on its immediate children.

Other than `once`, modifiers are not valid on component event handlers.

> [!NOTE]
> If you're planning an eventual migration to Svelte 5, use callback props instead. This will make upgrading easier as `createEventDispatcher` is deprecated:
>
> ```svelte
> <!--- file: Stepper.svelte --->
> <script>
> 	export let decrement;
> 	export let increment;
> </script>
>
> <button on:click={decrement}>decrement</button>
> <button on:click={increment}>increment</button>
> ```
````

----
url: https://svelte.dev/docs/svelte/what-are-runes
----

[Skip to main content](#main)

> **rune** /ruːn/ *noun*
>
> A letter or mark used as a mystical or magic symbol.

Runes are symbols that you use in `.svelte` and `.svelte.js` / `.svelte.ts` files to control the Svelte compiler. If you think of Svelte as a language, runes are part of the syntax — they are *keywords*.

Runes have a `$` prefix and look like functions:

```
let messagelet message: string = $statefunction $state<"hello">(initial: "hello"): "hello" (+1 overload)
namespace $state

Declares reactive state.




Example:



let count = $state(0);

{@link https://svelte.dev/docs/svelte/$state Documentation}


initial 

The initial value


('hello');
```

They differ from normal JavaScript functions in important ways, however:

* You don’t need to import them — they are part of the language
* They’re not values — you can’t assign them to a variable or pass them as arguments to a function
* Just like JavaScript keywords, they are only valid in certain positions (the compiler will help you if you put them in the wrong place)

> Legacy mode
>
> Runes didn’t exist prior to Svelte 5.

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/02-runes/01-what-are-runes.md) [llms.txt](/docs/svelte/what-are-runes/llms.txt)

previous next

[.svelte.js and .svelte.ts files](/docs/svelte/svelte-js-files) [$state](/docs/svelte/$state)

----
url: https://svelte.dev/docs/svelte/what-are-runes/llms.txt
----

````
> [!NOTE] **rune** /ruːn/ _noun_
>
> A letter or mark used as a mystical or magic symbol.

Runes are symbols that you use in `.svelte` and `.svelte.js`/`.svelte.ts` files to control the Svelte compiler. If you think of Svelte as a language, runes are part of the syntax — they are _keywords_.

Runes have a `$` prefix and look like functions:

```js
let message = $state('hello');
```

They differ from normal JavaScript functions in important ways, however:

- You don't need to import them — they are part of the language
- They're not values — you can't assign them to a variable or pass them as arguments to a function
- Just like JavaScript keywords, they are only valid in certain positions (the compiler will help you if you put them in the wrong place)

> [!LEGACY]
> Runes didn't exist prior to Svelte 5.
````

----
url: https://svelte.dev/docs/svelte/legacy-let
----

[Skip to main content](#main)

In runes mode, reactive state is explicitly declared with the [`$state` rune]($state).

In legacy mode, variables declared at the top level of a component are automatically considered *reactive*. Reassigning or mutating these variables (`count += 1` or `object.x = y`) will cause the UI to update.

```
<script>
	let count = 0;
</script>

<button on:click={() => count += 1}>
	clicks: {count}
</button>
```

Because Svelte’s legacy mode reactivity is based on *assignments*, using array methods like `.push()` and `.splice()` won’t automatically trigger updates. A subsequent assignment is required to ‘tell’ the compiler to update the UI:

```
<script>
	let numbers = [1, 2, 3, 4];

	function addNumber() {
		// this method call does not trigger an update
		numbers.push(numbers.length + 1);

		// this assignment will update anything
		// that depends on `numbers`
		numbers = numbers;
	}
</script>
```

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/99-legacy/01-legacy-let.md) [llms.txt](/docs/svelte/legacy-let/llms.txt)

previous next

[Overview](/docs/svelte/legacy-overview) [Reactive $: statements](/docs/svelte/legacy-reactive-assignments)

----
url: https://svelte.dev/docs/svelte/custom-elements/llms.txt
----

````
<!-- - [basically what we have today](https://svelte.dev/docs/custom-elements-api) -->

Svelte components can also be compiled to custom elements (aka web components) using the `customElement: true` compiler option. You should specify a tag name for the component using the `<svelte:options>` [element](svelte-options). Within the custom element you can access the host element via the [`$host`](https://svelte.dev/docs/svelte/$host) rune.

```svelte
<svelte:options customElement="my-element" />

<script>
	let { name = 'world' } = $props();
</script>

<h1>Hello {name}!</h1>
<slot />
```

You can leave out the tag name for any of your inner components which you don't want to expose and use them like regular Svelte components. Consumers of the component can still name it afterwards if needed, using the static `element` property which contains the custom element constructor and which is available when the `customElement` compiler option is `true`.

```js
// @noErrors
import MyElement from './MyElement.svelte';

customElements.define('my-element', MyElement.element);
```

Once a custom element has been defined, it can be used as a regular DOM element:

```js
document.body.innerHTML = `
	<my-element>
		<p>This is some slotted content</p>
	</my-element>
`;
```

Any [props](basic-markup#Component-props) are exposed as properties of the DOM element (as well as being readable/writable as attributes, where possible).

```js
// @noErrors
const el = document.querySelector('my-element');

// get the current value of the 'name' prop
console.log(el.name);

// set a new value, updating the shadow DOM
el.name = 'everybody';
```

Note that you need to list out all properties explicitly, i.e. doing `let props = $props()` without declaring `props` in the [component options](#Component-options) means that Svelte can't know which props to expose as properties on the DOM element.

## Component lifecycle

Custom elements are created from Svelte components using a wrapper approach. This means the inner Svelte component has no knowledge that it is a custom element. The custom element wrapper takes care of handling its lifecycle appropriately.

When a custom element is created, the Svelte component it wraps is _not_ created right away. It is only created in the next tick after the `connectedCallback` is invoked. Properties assigned to the custom element before it is inserted into the DOM are temporarily saved and then set on component creation, so their values are not lost. The same does not work for invoking exported functions on the custom element though, they are only available after the element has mounted. If you need to invoke functions before component creation, you can work around it by using the [`extend` option](#Component-options).

When a custom element written with Svelte is created or updated, the shadow DOM will reflect the value in the next tick, not immediately. This way updates can be batched, and DOM moves which temporarily (but synchronously) detach the element from the DOM don't lead to unmounting the inner component.

The inner Svelte component is destroyed in the next tick after the `disconnectedCallback` is invoked.

## Component options

When constructing a custom element, you can tailor several aspects by defining `customElement` as an object within `<svelte:options>` since Svelte 4. This object may contain the following properties:

- `tag: string`: an optional `tag` property for the custom element's name. If set, a custom element with this tag name will be defined with the document's `customElements` registry upon importing this component.
- `shadow`: an optional property to modify shadow root properties. It accepts the following values:
  - `"none"`: No shadow root is created. Note that styles are then no longer encapsulated, and you can't use slots.
  - `"open"`: Shadow root is created with the `mode: "open"` option.
  - [`ShadowRootInit`](https://developer.mozilla.org/en-US/docs/Web/API/Element/attachShadow#options): You can pass a settings object that will be passed to `attachShadow()` when shadow root is created.
- `props`: an optional property to modify certain details and behaviors of your component's properties. It offers the following settings:
  - `attribute: string`: To update a custom element's prop, you have two alternatives: either set the property on the custom element's reference as illustrated above or use an HTML attribute. For the latter, the default attribute name is the lowercase property name. Modify this by assigning `attribute: "<desired name>"`.
  - `reflect: boolean`: By default, updated prop values do not reflect back to the DOM. To enable this behavior, set `reflect: true`.
  - `type: 'String' | 'Boolean' | 'Number' | 'Array' | 'Object'`: While converting an attribute value to a prop value and reflecting it back, the prop value is assumed to be a `String` by default. This may not always be accurate. For instance, for a number type, define it using `type: "Number"`
    You don't need to list all properties, those not listed will use the default settings.
- `extend`: an optional property which expects a function as its argument. It is passed the custom element class generated by Svelte and expects you to return a custom element class. This comes in handy if you have very specific requirements to the life cycle of the custom element or want to enhance the class to for example use [ElementInternals](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals#examples) for better HTML form integration.

```svelte
<svelte:options
	customElement={{
		tag: 'custom-element',
		shadow: {
			mode: import.meta.env.DEV ? 'open' : 'closed',
			clonable: true,
			// ...
		},
		props: {
			name: { reflect: true, type: 'Number', attribute: 'element-index' }
		},
		extend: (customElementConstructor) => {
			// Extend the class so we can let it participate in HTML forms
			return class extends customElementConstructor {
				static formAssociated = true;

				constructor() {
					super();
					this.attachedInternals = this.attachInternals();
				}

				// Add the function here, not below in the component so that
				// it's always available, not just when the inner Svelte component
				// is mounted
				randomIndex() {
					this.elementIndex = Math.random();
				}
			};
		}
	}}
/>

<script>
	let { elementIndex, attachedInternals } = $props();
	// ...
	function check() {
		attachedInternals.checkValidity();
	}
</script>

...
```

> [!NOTE] While Typescript is supported in the `extend` function, it is subject to limitations: you need to set `lang="ts"` on one of the scripts AND you can only use [erasable syntax](https://www.typescriptlang.org/tsconfig/#erasableSyntaxOnly) in it. They are not processed by script preprocessors.

## Caveats and limitations

Custom elements can be a useful way to package components for consumption in a non-Svelte app, as they will work with vanilla HTML and JavaScript as well as [most frameworks](https://custom-elements-everywhere.com/). There are, however, some important differences to be aware of:

- Styles are _encapsulated_, rather than merely _scoped_ (unless you set `shadow: "none"`). This means that any non-component styles (such as you might have in a `global.css` file) will not apply to the custom element, including styles with the `:global(...)` modifier
- Instead of being extracted out as a separate .css file, styles are inlined into the component as a JavaScript string
- Custom elements are not generally suitable for server-side rendering, as the shadow DOM is invisible until JavaScript loads
- In Svelte, slotted content renders _lazily_. In the DOM, it renders _eagerly_. In other words, it will always be created even if the component's `<slot>` element is inside an `{#if ...}` block. Similarly, including a `<slot>` in an `{#each ...}` block will not cause the slotted content to be rendered multiple times
- The deprecated `let:` directive has no effect, because custom elements do not have a way to pass data to the parent component that fills the slot
- Polyfills are required to support older browsers
- You can use Svelte's context feature between regular Svelte components within a custom element, but you can't use them across custom elements. In other words, you can't use `setContext` on a parent custom element and read that with `getContext` in a child custom element.
- Don't declare properties or attributes starting with `on`, as their usage will be interpreted as an event listener. In other words, Svelte treats `<custom-element oneworld={true}></custom-element>` as `customElement.addEventListener('eworld', true)` (and not as `customElement.oneworld = true`)
````

----
url: https://svelte.dev/docs/svelte/browser-support/llms.txt
----

```
The table below shows the minimum browser versions Svelte is expected to work in, derived from the browser APIs used by Svelte's internal code.

<!-- generated in ../../../../../packages/svelte/scripts/generate-browser-support.ts. do not edit -->

| Browser | Minimum version |
| - | - |
| Chrome/Edge | 87 |
| Firefox | 83 |
| Safari | 14 |
| Opera | 73 |
| Opera (Android) | 62 |
| Samsung Internet | 14.0 |
| Android WebView | 87 |
| Internet Explorer | not supported |


> [!NOTE] This equates to a <a href="https://web-platform-dx.github.io/baseline/">Baseline</a> target of 2020.

This table only covers Svelte itself. It does not include [SvelteKit](/docs/kit), other Svelte libraries, or your own code.

## Exceptions

A few Svelte features require a higher minimum browser version. You'll only need to take the following table into consideration if you use these specific features.

<!-- generated in ../../../../../packages/svelte/scripts/generate-browser-support.ts. do not edit -->

| Feature | Chrome/Edge | Firefox | Safari |
| - | - | - | - |
| [`$state.snapshot`](/docs/svelte/$state#$state.snapshot) | 98 | 94 | 15.4 |
| [`bind:devicePixelContentBoxSize`](/docs/svelte/bind#Dimensions) | <span style="color: var(--sk-fg-4)">—</span> | 93 | not supported |
| [`flip` from `svelte/animate`](/docs/svelte/svelte-animate#flip) | <span style="color: var(--sk-fg-4)">—</span> | 126 | <span style="color: var(--sk-fg-4)">—</span> |
```

----
url: https://svelte.dev/docs/svelte/legacy-svelte-self/llms.txt
----

````
The `<svelte:self>` element allows a component to include itself, recursively.

It cannot appear at the top level of your markup; it must be inside an if or each block or passed to a component's slot to prevent an infinite loop.

```svelte
<script>
	export let count;
</script>

{#if count > 0}
	<p>counting down... {count}</p>
	<svelte:self count={count - 1} />
{:else}
	<p>lift-off!</p>
{/if}
```

> [!NOTE]
> This concept is obsolete, as components can import themselves:
> ```svelte
> <!--- file: App.svelte --->
> <script>
> 	import Self from './App.svelte'
> 	export let count;
> </script>
>
> {#if count > 0}
> 	<p>counting down... {count}</p>
> 	<Self count={count - 1} />
> {:else}
> 	<p>lift-off!</p>
> {/if}
> ```
````

----
url: https://svelte.dev/docs/svelte/svelte-element/llms.txt
----

````
```svelte
<svelte:element this={expression} />
```

The `<svelte:element>` element lets you render an element that is unknown at author time, for example because it comes from a CMS. Any properties and event listeners present will be applied to the element.

The only supported binding is `bind:this`, since Svelte's built-in bindings do not work with generic elements.

If `this` has a nullish value, the element and its children will not be rendered.

If `this` is the name of a [void element](https://developer.mozilla.org/en-US/docs/Glossary/Void_element) (e.g., `br`) and `<svelte:element>` has child elements, a runtime error will be thrown in development mode:

```svelte
<script>
	let tag = $state('hr');
</script>

<svelte:element this={tag}>
	This text cannot appear inside an hr element
</svelte:element>
```

Svelte tries its best to infer the correct namespace from the element's surroundings, but it's not always possible. You can make it explicit with an `xmlns` attribute:

```svelte
<svelte:element this={tag} xmlns="http://www.w3.org/2000/svg" />
```

`this` needs to be a valid DOM element tag, things like `#text` or `svelte:head` will not work.
````

----
url: https://svelte.dev/docs/svelte/svelte-reactivity-window/llms.txt
----

````
This module exports reactive versions of various `window` values, each of which has a reactive `current` property that you can reference in reactive contexts (templates, [deriveds]($derived) and [effects]($effect)) without using [`<svelte:window>`](svelte-window) bindings or manually creating your own event listeners.

```svelte
<script>
	import { innerWidth, innerHeight } from 'svelte/reactivity/window';
</script>

<p>{innerWidth.current}x{innerHeight.current}</p>
```



```js
// @noErrors
import {
	devicePixelRatio,
	innerHeight,
	innerWidth,
	online,
	outerHeight,
	outerWidth,
	screenLeft,
	screenTop,
	scrollX,
	scrollY
} from 'svelte/reactivity/window';
```

## devicePixelRatio

<blockquote class="since note">

Available since 5.11.0

</blockquote>

`devicePixelRatio.current` is a reactive view of `window.devicePixelRatio`. On the server it is `undefined`.
Note that behaviour differs between browsers — on Chrome it will respond to the current zoom level,
on Firefox and Safari it won't.

<div class="ts-block">

```dts
const devicePixelRatio: {
	get current(): number | undefined;
};
```

</div>



## innerHeight

<blockquote class="since note">

Available since 5.11.0

</blockquote>

`innerHeight.current` is a reactive view of `window.innerHeight`. On the server it is `undefined`.

<div class="ts-block">

```dts
const innerHeight: ReactiveValue<number | undefined>;
```

</div>



## innerWidth

<blockquote class="since note">

Available since 5.11.0

</blockquote>

`innerWidth.current` is a reactive view of `window.innerWidth`. On the server it is `undefined`.

<div class="ts-block">

```dts
const innerWidth: ReactiveValue<number | undefined>;
```

</div>



## online

<blockquote class="since note">

Available since 5.11.0

</blockquote>

`online.current` is a reactive view of `navigator.onLine`. On the server it is `undefined`.

<div class="ts-block">

```dts
const online: ReactiveValue<boolean | undefined>;
```

</div>



## outerHeight

<blockquote class="since note">

Available since 5.11.0

</blockquote>

`outerHeight.current` is a reactive view of `window.outerHeight`. On the server it is `undefined`.

<div class="ts-block">

```dts
const outerHeight: ReactiveValue<number | undefined>;
```

</div>



## outerWidth

<blockquote class="since note">

Available since 5.11.0

</blockquote>

`outerWidth.current` is a reactive view of `window.outerWidth`. On the server it is `undefined`.

<div class="ts-block">

```dts
const outerWidth: ReactiveValue<number | undefined>;
```

</div>



## screenLeft

<blockquote class="since note">

Available since 5.11.0

</blockquote>

`screenLeft.current` is a reactive view of `window.screenLeft`. It is updated inside a `requestAnimationFrame` callback. On the server it is `undefined`.

<div class="ts-block">

```dts
const screenLeft: ReactiveValue<number | undefined>;
```

</div>



## screenTop

<blockquote class="since note">

Available since 5.11.0

</blockquote>

`screenTop.current` is a reactive view of `window.screenTop`. It is updated inside a `requestAnimationFrame` callback. On the server it is `undefined`.

<div class="ts-block">

```dts
const screenTop: ReactiveValue<number | undefined>;
```

</div>



## scrollX

<blockquote class="since note">

Available since 5.11.0

</blockquote>

`scrollX.current` is a reactive view of `window.scrollX`. On the server it is `undefined`.

<div class="ts-block">

```dts
const scrollX: ReactiveValue<number | undefined>;
```

</div>



## scrollY

<blockquote class="since note">

Available since 5.11.0

</blockquote>

`scrollY.current` is a reactive view of `window.scrollY`. On the server it is `undefined`.

<div class="ts-block">

```dts
const scrollY: ReactiveValue<number | undefined>;
```

</div>
````

----
url: https://svelte.dev/docs/svelte/context/llms.txt
----

````
Context allows components to access values owned by parent components without passing them down as props (potentially through many layers of intermediate components, known as 'prop-drilling').

By creating a `[get, set, has]` triplet of functions with `createContext`, you can set the context in a parent component and get it in a child component:

<!-- codeblock:start {"title":"Context","selected":"context.ts"} -->
```svelte
<!--- file: App.svelte --->
<script>
	import Parent from './Parent.svelte';
	import Child from './Child.svelte';
</script>

<Parent>
	<Child />
</Parent>
```

```svelte
<!--- file: Parent.svelte --->
<script>
	import { setUserContext } from './context';

	let { children } = $props();

	setUserContext({ name: 'world' });
</script>

{@render children()}
```

```svelte
<!--- file: Child.svelte --->
<script>
	import { getUserContext } from './context';

	const user = getUserContext();
</script>

<h1>hello {user.name}, inside Child.svelte</h1>
```

```ts
/// file: context.ts
import { createContext } from 'svelte';

interface User {
	name: string;
}

export const [getUserContext, setUserContext] = createContext<User>();
```
<!-- codeblock:end -->

> [!NOTE] `createContext` was added in version 5.40. If you are using an earlier version of Svelte, you must use `setContext` and `getContext` instead.

This is particularly useful when `Parent.svelte` is not directly aware of `Child.svelte`, but instead renders it as part of a `children` [snippet](snippet) as shown above.

## `setContext` and `getContext`

As an alternative to `createContext`, you can use `setContext` and `getContext` directly. The parent component sets context with `setContext(key, value)`...

```svelte
<!--- file: Parent.svelte --->
<script>
	import { setContext } from 'svelte';

	setContext('my-context', 'hello from Parent.svelte');
</script>
```

...and the child retrieves it with `getContext`:

```svelte
<!--- file: Child.svelte --->
<script>
	import { getContext } from 'svelte';

	const message = getContext('my-context');
</script>

<h1>{message}, inside Child.svelte</h1>
```

The key (`'my-context'`, in the example above) and the context itself can be any JavaScript value.

> [!NOTE] `createContext` is preferred since it provides better type safety and makes it unnecessary to use keys.

In addition to [`setContext`](svelte#setContext) and [`getContext`](svelte#getContext), Svelte exposes [`hasContext`](svelte#hasContext) and [`getAllContexts`](svelte#getAllContexts) functions.

## Using context with state

You can store reactive state in context...

<!-- codeblock:start {"title":"Context with state"} -->
```svelte
<!--- file: App.svelte --->
<script>
	import { setCounter } from './context.ts';
	import Child from './Child.svelte';

	let counter = $state({
		count: 0
	});

	setCounter(counter);
</script>

<button onclick={() => counter.count += 1}>
	increment
</button>

<Child />
<Child />
<Child />

<button onclick={() => counter.count = 0}>
	reset
</button>
```

```svelte
<!--- file: Child.svelte --->
<script>
	import { getCounter } from './context.ts';

	const counter = getCounter();
</script>

<p>{counter.count}</p>
```

```ts
/// file: context.ts
import { createContext } from 'svelte';

interface Counter {
	count: number;
}

export const [getCounter, setCounter] = createContext<Counter>();
```
<!-- codeblock:end -->

...though note that if you _reassign_ `counter` instead of updating it, you will 'break the link' — in other words instead of this...

```svelte
<button onclick={() => counter = { count: 0 } }>
	reset
</button>
```

...you must do this:

```svelte
<button onclick={() => +++counter.count = 0+++}>
	reset
</button>
```

Svelte will warn you if you get it wrong.

Similarly, to pass primitive values through context, use functions as described in [Passing state into functions]($state#Passing-state-into-functions).

## Mounting components with context

To mount a component with specific context, create a wrapper component that sets the context before rendering the component. This is useful for [component tests](testing#Unit-and-component-tests-with-Vitest-Component-testing), or any other scenario that needs to provide context through `mount`. As of version 5.49, you can do this sort of thing:

```js
import { mount, unmount } from 'svelte';
import { expect, test } from 'vitest';
import { setUserContext } from './context';
import MyComponent from './MyComponent.svelte';

test('MyComponent', () => {
	function Wrapper(...args) {
		setUserContext({ name: 'Bob' });
		return MyComponent(...args);
	}

	const component = mount(Wrapper, {
		target: document.body
	});

	expect(document.body.innerHTML).toBe('<h1>Hello Bob!</h1>');

	unmount(component);
});
```

This approach also works with [`hydrate`](imperative-component-api#hydrate) and [`render`](imperative-component-api#render).

The context set by the wrapper only applies to that mounted component tree. Each call to `mount`, `hydrate` or `render` creates a separate wrapper instance, so the context does not leak into other mounted components.

## Replacing global state

When you have state shared by many different components, you might be tempted to put it in its own module and just import it wherever it's needed:

```js
/// file: state.svelte.js
export const myGlobalState = $state({
	user: {
		// ...
	}
	// ...
});
```

In many cases this is perfectly fine, but there is a risk: if you mutate the state during server-side rendering (which is discouraged, but entirely possible!)...

```svelte
<!--- file: App.svelte --->
<script>
	import { myGlobalState } from './state.svelte.js';

	let { data } = $props();

	if (data.user) {
		myGlobalState.user = data.user;
	}
</script>
```

...then the data may be accessible by the _next_ user. Context solves this problem because it is not shared between requests.
````

----
url: https://svelte.dev/docs/svelte/runtime-errors
----

[Skip to main content](#main)

## Client errors[](#Client-errors)

### async\_derived\_orphan[](#Client-errors-async_derived_orphan)

```
Cannot create a `$derived(...)` with an `await` expression outside of an effect tree
```

In Svelte there are two types of reaction — [`$derived`](/docs/svelte/$derived) and [`$effect`](/docs/svelte/$effect). Deriveds can be created anywhere, because they run *lazily* and can be [garbage collected](https://developer.mozilla.org/en-US/docs/Glossary/Garbage_collection) if nothing references them. Effects, by contrast, keep running eagerly whenever their dependencies change, until they are destroyed.

Because of this, effects can only be created inside other effects (or [effect roots](/docs/svelte/$effect#$effect.root), such as the one that is created when you first mount a component) so that Svelte knows when to destroy them.

Some sleight of hand occurs when a derived contains an `await` expression: Since waiting until we read `{await getPromise()}` to call `getPromise` would be too late, we use an effect to instead call it proactively, notifying Svelte when the value is available. But since we’re using an effect, we can only create asynchronous deriveds inside another effect.

### bind\_invalid\_checkbox\_value[](#Client-errors-bind_invalid_checkbox_value)

```
Using `bind:value` together with a checkbox input is not allowed. Use `bind:checked` instead
```

### bind\_invalid\_export[](#Client-errors-bind_invalid_export)

```
Component %component% has an export named `%key%` that a consumer component is trying to access using `bind:%key%`, which is disallowed. Instead, use `bind:this` (e.g. `<%name% bind:this={component} />`) and then access the property on the bound component instance (e.g. `component.%key%`)
```

### bind\_not\_bindable[](#Client-errors-bind_not_bindable)

```
A component is attempting to bind to a non-bindable property `%key%` belonging to %component% (i.e. `<%name% bind:%key%={...}>`). To mark a property as bindable: `let { %key% = $bindable() } = $props()`
```

### component\_api\_changed[](#Client-errors-component_api_changed)

```
Calling `%method%` on a component instance (of %component%) is no longer valid in Svelte 5
```

See the [migration guide](/docs/svelte/v5-migration-guide#Components-are-no-longer-classes) for more information.

### component\_api\_invalid\_new[](#Client-errors-component_api_invalid_new)

```
Attempted to instantiate %component% with `new %name%`, which is no longer valid in Svelte 5. If this component is not under your control, set the `compatibility.componentApi` compiler option to `4` to keep it working.
```

See the [migration guide](/docs/svelte/v5-migration-guide#Components-are-no-longer-classes) for more information.

### derived\_references\_self[](#Client-errors-derived_references_self)

```
A derived value cannot reference itself recursively
```

### each\_key\_duplicate[](#Client-errors-each_key_duplicate)

```
Keyed each block has duplicate key at indexes %a% and %b%
```

```
Keyed each block has duplicate key `%value%` at indexes %a% and %b%
```

### each\_key\_volatile[](#Client-errors-each_key_volatile)

```
Keyed each block has key that is not idempotent — the key for item at index %index% was `%a%` but is now `%b%`. Keys must be the same each time for a given item
```

The key expression in a keyed each block must return the same value when called multiple times for the same item. Using expressions like `[item.a, item.b]` creates a new array each time, which will never be equal to itself. Instead, use a primitive value or create a stable key like `item.a + '-' + item.b`.

### effect\_in\_teardown[](#Client-errors-effect_in_teardown)

```
`%rune%` cannot be used inside an effect cleanup function
```

### effect\_in\_unowned\_derived[](#Client-errors-effect_in_unowned_derived)

```
Effect cannot be created inside a `$derived` value that was not itself created inside an effect
```

### effect\_orphan[](#Client-errors-effect_orphan)

```
`%rune%` can only be used inside an effect (e.g. during component initialisation)
```

Effects can only be created while a parent effect is running. This means that they cannot, for example, be created inside an event handler or after an `await` expression (unless the `await` occurs directly inside a component’s `<script>` tag, and not inside an async function).

In very rare cases, it is appropriate to use [`$effect.root`]($effect#$effect.root) so that you can create effects outside the normal component lifecycle.

### effect\_pending\_outside\_reaction[](#Client-errors-effect_pending_outside_reaction)

```
`$effect.pending()` can only be called inside an effect or derived
```

### effect\_update\_depth\_exceeded[](#Client-errors-effect_update_depth_exceeded)

```
Maximum update depth exceeded. This typically indicates that an effect reads and writes the same piece of state
```

If an effect updates some state that it also depends on, it will re-run, potentially in a loop:

```
let countlet count: number = $statefunction $state<0>(initial: 0): 0 (+1 overload)
namespace $state

Declares reactive state.




Example:



let count = $state(0);

{@link https://svelte.dev/docs/svelte/$state Documentation}


initial 

The initial value


(0);

$effectfunction $effect(fn: () => void | (() => void)): void
namespace $effect

Runs code when a component is mounted to the DOM, and then whenever its dependencies change, i.e. $state or $derived values.
The timing of the execution is after the DOM has been updated.




Example:



$effect(() => console.log('The count is now ' + count));

If you return a function from the effect, it will be called right before the effect is run again, or when the component is unmounted.




Does not run during server-side rendering.




{@link https://svelte.dev/docs/svelte/$effect Documentation}


fn 

The function to execute


(() => {
	// this both reads and writes `count`,
	// so will run in an infinite loop
	countlet count: number += 1;
});
```

(Svelte intervenes before this can crash your browser tab.)

The same applies to array mutations, since these both read and write to the array:

```
let arraylet array: string[] = $statefunction $state<string[]>(initial: string[]): string[] (+1 overload)
namespace $state

Declares reactive state.




Example:



let count = $state(0);

{@link https://svelte.dev/docs/svelte/$state Documentation}


initial 

The initial value


(['hello']);

$effectfunction $effect(fn: () => void | (() => void)): void
namespace $effect

Runs code when a component is mounted to the DOM, and then whenever its dependencies change, i.e. $state or $derived values.
The timing of the execution is after the DOM has been updated.




Example:



$effect(() => console.log('The count is now ' + count));

If you return a function from the effect, it will be called right before the effect is run again, or when the component is unmounted.




Does not run during server-side rendering.




{@link https://svelte.dev/docs/svelte/$effect Documentation}


fn 

The function to execute


(() => {
	arraylet array: string[].push(method) Array<string>.push(...items: string[]): number

Appends new elements to the end of an array, and returns the new length of the array.


items 

New elements to add to the array.


('goodbye');
});
```

Note that it’s fine for an effect to re-run itself as long as it ‘settles’:

```
$effectfunction $effect(fn: () => void | (() => void)): void
namespace $effect

Runs code when a component is mounted to the DOM, and then whenever its dependencies change, i.e. $state or $derived values.
The timing of the execution is after the DOM has been updated.




Example:



$effect(() => console.log('The count is now ' + count));

If you return a function from the effect, it will be called right before the effect is run again, or when the component is unmounted.




Does not run during server-side rendering.




{@link https://svelte.dev/docs/svelte/$effect Documentation}


fn 

The function to execute


(() => {
	// this is okay, because sorting an already-sorted array
	// won't result in a mutation
	arraylet array: string[].sort(method) Array<string>.sort(compareFn?: ((a: string, b: string) => number) | undefined): string[]

Sorts an array in place.
This method mutates the array and returns a reference to the same array.


compareFn 

Function used to determine the order of the elements. It is expected to return
a negative value if the first argument is less than the second argument, zero if they're equal, and a positive
value otherwise. If omitted, the elements are sorted in ascending, UTF-16 code unit order.



[11,2,22,1].sort((a, b) => a - b)
();
});
```

Often when encountering this issue, the value in question shouldn’t be state (for example, if you are pushing to a `logs` array in an effect, make `logs` a normal array rather than `$state([])`). In the rare cases where you really *do* need to write to state in an effect — [which you should avoid]($effect#When-not-to-use-$effect) — you can read the state with [untrack](svelte#untrack) to avoid adding it as a dependency.

### flush\_sync\_in\_effect[](#Client-errors-flush_sync_in_effect)

```
Cannot use `flushSync` inside an effect
```

The `flushSync()` function can be used to flush any pending effects synchronously. It cannot be used if effects are currently being flushed — in other words, you can call it after a state change but *not* inside an effect.

This restriction only applies when using the `experimental.async` option, which will be active by default in Svelte 6.

### fork\_discarded[](#Client-errors-fork_discarded)

```
Cannot commit a fork that was already discarded
```

### fork\_timing[](#Client-errors-fork_timing)

```
Cannot create a fork inside an effect or when state changes are pending
```

### get\_abort\_signal\_outside\_reaction[](#Client-errors-get_abort_signal_outside_reaction)

```
`getAbortSignal()` can only be called inside an effect or derived
```

### hydratable\_missing\_but\_required[](#Client-errors-hydratable_missing_but_required)

```
Expected to find a hydratable with key `%key%` during hydration, but did not.
```

This can happen if you render a hydratable on the client that was not rendered on the server, and means that it was forced to fall back to running its function blockingly during hydration. This is bad for performance, as it blocks hydration until the asynchronous work completes.

```
<script>
  import { hydratable } from 'svelte';

	if (BROWSER) {
		// bad! nothing can become interactive until this asynchronous work is done
		await hydratable('foo', get_slow_random_number);
	}
</script>
```

### hydration\_failed[](#Client-errors-hydration_failed)

```
Failed to hydrate the application
```

### invalid\_snippet[](#Client-errors-invalid_snippet)

```
Could not `{@render}` snippet due to the expression being `null` or `undefined`. Consider using optional chaining `{@render snippet?.()}`
```

### lifecycle\_legacy\_only[](#Client-errors-lifecycle_legacy_only)

```
`%name%(...)` cannot be used in runes mode
```

### props\_invalid\_value[](#Client-errors-props_invalid_value)

```
Cannot do `bind:%key%={undefined}` when `%key%` has a fallback value
```

### props\_rest\_readonly[](#Client-errors-props_rest_readonly)

```
Rest element properties of `$props()` such as `%property%` are readonly
```

### rune\_outside\_svelte[](#Client-errors-rune_outside_svelte)

```
The `%rune%` rune is only available inside `.svelte` and `.svelte.js/ts` files
```

### state\_descriptors\_fixed[](#Client-errors-state_descriptors_fixed)

```
Property descriptors defined on `$state` objects must contain `value` and always be `enumerable`, `configurable` and `writable`.
```

### state\_prototype\_fixed[](#Client-errors-state_prototype_fixed)

```
Cannot set prototype of `$state` object
```

### state\_unsafe\_mutation[](#Client-errors-state_unsafe_mutation)

```
Updating state inside `$derived(...)`, `$inspect(...)` or a template expression is forbidden. If the value should not be reactive, declare it without `$state`
```

This error occurs when state is updated while evaluating a `$derived`. You might encounter it while trying to ‘derive’ two pieces of state in one go:

```
<script>
	let count = $state(0);

	let even = $state(true);

	let odd = $derived.by(() => {
		even = count % 2 === 0;
		return !even;
	});
</script>

<button onclick={() => count++}>{count}</button>

<p>{count} is even: {even}</p>
<p>{count} is odd: {odd}</p>
```

This is forbidden because it introduces instability: if `<p>{count} is even: {even}</p>` is updated before `odd` is recalculated, `even` will be stale. In most cases the solution is to make everything derived:

```
let evenlet even: boolean = $derivedfunction $derived<boolean>(expression: boolean): boolean
namespace $derived

Declares derived state, i.e. one that depends on other state variables.
The expression inside $derived(...) should be free of side-effects.




Example:



let double = $derived(count * 2);

{@link https://svelte.dev/docs/svelte/$derived Documentation}


expression 

The derived state expression


(countlet count: number % 2 === 0);
let oddlet odd: boolean = $derivedfunction $derived<boolean>(expression: boolean): boolean
namespace $derived

Declares derived state, i.e. one that depends on other state variables.
The expression inside $derived(...) should be free of side-effects.




Example:



let double = $derived(count * 2);

{@link https://svelte.dev/docs/svelte/$derived Documentation}


expression 

The derived state expression


(!evenlet even: boolean);
```

If side-effects are unavoidable, use [`$effect`]($effect) instead.

### svelte\_boundary\_reset\_onerror[](#Client-errors-svelte_boundary_reset_onerror)

```
A `<svelte:boundary>` `reset` function cannot be called while an error is still being handled
```

If a [`<svelte:boundary>`](/docs/svelte/svelte-boundary) has an `onerror` function, it must not call the provided `reset` function synchronously since the boundary is still in a broken state. Typically, `reset()` is called later, once the error has been resolved.

If it’s possible to resolve the error inside the `onerror` callback, you must at least wait for the boundary to settle before calling `reset()`, for example using [`tick`](/docs/svelte/lifecycle-hooks#tick):

```
<svelte:boundary onerror={async (error, reset) => {
	fixTheError();
	await tick();
	reset();
}}>

</svelte:boundary>
```

## Server errors[](#Server-errors)

### async\_local\_storage\_unavailable[](#Server-errors-async_local_storage_unavailable)

```
The node API `AsyncLocalStorage` is not available, but is required to use async server rendering.
```

Some platforms require configuration flags to enable this API. Consult your platform’s documentation.

### await\_invalid[](#Server-errors-await_invalid)

```
Encountered asynchronous work while rendering synchronously.
```

You (or the framework you’re using) called [`render(...)`](svelte-server#render) with a component containing an `await` expression. Either `await` the result of `render` or wrap the `await` (or the component containing it) in a [`<svelte:boundary>`](svelte-boundary) with a `pending` snippet.

### dynamic\_element\_invalid\_tag[](#Server-errors-dynamic_element_invalid_tag)

```
`<svelte:element this="%tag%">` is not a valid element name — the element will not be rendered
```

The value passed to the `this` prop of `<svelte:element>` must be a valid HTML element, SVG element, MathML element, or custom element name. A value containing invalid characters (such as whitespace or special characters) was provided, which could be a security risk. Ensure only valid tag names are passed.

### html\_deprecated[](#Server-errors-html_deprecated)

```
The `html` property of server render results has been deprecated. Use `body` instead.
```

### hydratable\_clobbering[](#Server-errors-hydratable_clobbering)

```
Attempted to set `hydratable` with key `%key%` twice with different values.

%stack%
```

This error occurs when using `hydratable` multiple times with the same key. To avoid this, you can:

* Ensure all invocations with the same key result in the same value
* Update the keys to make both instances unique

```
<script>
  import { hydratable } from 'svelte';

  // which one should "win" and be serialized in the rendered response?
  const one = hydratable('not-unique', () => 1);
  const two = hydratable('not-unique', () => 2);
</script>
```

### hydratable\_serialization\_failed[](#Server-errors-hydratable_serialization_failed)

```
Failed to serialize `hydratable` data for key `%key%`.

`hydratable` can serialize anything [`uneval` from `devalue`](https://npmjs.com/package/uneval) can, plus Promises.

Cause:
%stack%
```

### invalid\_csp[](#Server-errors-invalid_csp)

```
`csp.nonce` was set while `csp.hash` was `true`. These options cannot be used simultaneously.
```

### invalid\_id\_prefix[](#Server-errors-invalid_id_prefix)

```
The `idPrefix` option cannot include `--`.
```

### lifecycle\_function\_unavailable[](#Server-errors-lifecycle_function_unavailable)

```
`%name%(...)` is not available on the server
```

Certain methods such as `mount` cannot be invoked while running in a server context. Avoid calling them eagerly, i.e. not during render.

### server\_context\_required[](#Server-errors-server_context_required)

```
Could not resolve `render` context.
```

Certain functions such as `hydratable` cannot be invoked outside of a `render(...)` call, such as at the top level of a module.

## Shared errors[](#Shared-errors)

### experimental\_async\_required[](#Shared-errors-experimental_async_required)

```
Cannot use `%name%(...)` unless the `experimental.async` compiler option is `true`
```

### invalid\_default\_snippet[](#Shared-errors-invalid_default_snippet)

```
Cannot use `{@render children(...)}` if the parent component uses `let:` directives. Consider using a named snippet instead
```

This error would be thrown in a setup like this:

Parent

```
<List {items} let:entry>
	<span>{entry}</span>
</List>
```

List

```
<script>
	let { items, children } = $props();
</script>

<ul>
	{#each items as item}
		<li>{@render children(item)}</li>
	{/each}
</ul>
```

```
<script lang="ts">
	let { items, children } = $props();
</script>

<ul>
	{#each items as item}
		<li>{@render children(item)}</li>
	{/each}
</ul>
```

Here, `List.svelte` is using `{@render children(item)` which means it expects `Parent.svelte` to use snippets. Instead, `Parent.svelte` uses the deprecated `let:` directive. This combination of APIs is incompatible, hence the error.

### invalid\_snippet\_arguments[](#Shared-errors-invalid_snippet_arguments)

```
A snippet function was passed invalid arguments. Snippets should only be instantiated via `{@render ...}`
```

### invariant\_violation[](#Shared-errors-invariant_violation)

```
An invariant violation occurred, meaning Svelte's internal assumptions were flawed. This is a bug in Svelte, not your app — please open an issue at https://github.com/sveltejs/svelte, citing the following message: "%message%"
```

### lifecycle\_outside\_component[](#Shared-errors-lifecycle_outside_component)

```
`%name%(...)` can only be used during component initialisation
```

Certain lifecycle methods can only be used during component initialisation. To fix this, make sure you’re invoking the method inside the *top level of the instance script* of your component.

```
<script>
	import { onMount } from 'svelte';

	function handleClick() {
		// This is wrong
		onMount(() => {})
	}

	// This is correct
	onMount(() => {})
</script>

<button onclick={handleClick}>click me</button>
```

### missing\_context[](#Shared-errors-missing_context)

```
Context was not set in the current component or any of its ancestors
```

The [`createContext()`](svelte#createContext) utility returns a `[get, set, has]` triplet of functions. `get` will throw an error if `set` was not used to set the context in the current component or any of its ancestors.

### set\_context\_after\_init[](#Shared-errors-set_context_after_init)

```
`setContext` must be called when a component first initializes, not in a subsequent effect or after an `await` expression
```

This restriction only applies when using the `experimental.async` option, which will be active by default in Svelte 6.

### snippet\_without\_render\_tag[](#Shared-errors-snippet_without_render_tag)

```
Attempted to render a snippet without a `{@render}` block. This would cause the snippet code to be stringified instead of its content being rendered to the DOM. To fix this, change `{snippet}` to `{@render snippet()}`.
```

A component throwing this error will look something like this (`children` is not being rendered):

```
<script>
	let { children } = $props();
</script>

{children}
```

...or like this (a parent component is passing a snippet where a non-snippet value is expected):

Parent

```
<ChildComponent>
  {#snippet label()}
	<span>Hi!</span>
  {/snippet}
</ChildComponent>
```

Child

```
<script>
  let { label } = $props();
</script>

<!-- This component doesn't expect a snippet, but the parent provided one -->
<p>{label}</p>
```

```
<script lang="ts">
  let { label } = $props();
</script>

<!-- This component doesn't expect a snippet, but the parent provided one -->
<p>{label}</p>
```

### store\_invalid\_shape[](#Shared-errors-store_invalid_shape)

```
`%name%` is not a store with a `subscribe` method
```

### svelte\_element\_invalid\_this\_value[](#Shared-errors-svelte_element_invalid_this_value)

```
The `this` prop on `<svelte:element>` must be a string, if defined
```

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/98-reference/30-runtime-errors.md) [llms.txt](/docs/svelte/runtime-errors/llms.txt)

previous next

[Compiler warnings](/docs/svelte/compiler-warnings) [Runtime warnings](/docs/svelte/runtime-warnings)

----
url: https://svelte.dev/docs/svelte/legacy-export-let
----

[Skip to main content](#main)

In runes mode, [component props](basic-markup#Component-props) are declared with the [`$props`]($props) rune, allowing parent components to pass in data.

In legacy mode, props are marked with the `export` keyword, and can have a default value:

```
<script>
	export let foo;
	export let bar = 'default value';

	// Values that are passed in as props
	// are immediately available
	console.log({ foo });
</script>
```

The default value is used if it would otherwise be `undefined` when the component is created.

> Unlike in runes mode, if the parent component changes a prop from a defined value to `undefined`, it does not revert to the initial value.

Props without default values are considered *required*, and Svelte will print a warning during development if no value is provided, which you can squelch by specifying `undefined` as the default value:

```
export let foolet foo: undefined = undefinedvar undefined;
```

## Component exports[](#Component-exports)

An exported `const`, `class` or `function` declaration is *not* considered a prop — instead, it becomes part of the component’s API:

Greeter

```
<script>
	export function greet(name) {
		alert(`hello ${name}!`);
	}
</script>
```

```
<script lang="ts">
	export function greet(name) {
		alert(`hello ${name}!`);
	}
</script>
```

App

```
<script>
	import Greeter from './Greeter.svelte';

	let greeter;
</script>

<Greeter bind:this={greeter} />

<button on:click={() => greeter.greet('world')}>
	greet
</button>
```

```
<script lang="ts">
	import Greeter from './Greeter.svelte';

	let greeter;
</script>

<Greeter bind:this={greeter} />

<button on:click={() => greeter.greet('world')}>
	greet
</button>
```

## Renaming props[](#Renaming-props)

The `export` keyword can appear separately from the declaration. This is useful for renaming props, for example in the case of a reserved word:

App

```
<script>
	/** @type {string} */
	let className;

	// creates a `class` property, even
	// though it is a reserved word
	export { className as class };
</script>
```

```
<script lang="ts">
	let className: string;

	// creates a `class` property, even
	// though it is a reserved word
	export { className as class };
</script>
```

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/99-legacy/03-legacy-export-let.md) [llms.txt](/docs/svelte/legacy-export-let/llms.txt)

previous next

[Reactive $: statements](/docs/svelte/legacy-reactive-assignments) [$$props and $$restProps](/docs/svelte/legacy-$$props-and-$$restProps)

----
url: https://svelte.dev/docs/svelte/svelte-events
----

[Skip to main content](#main)

```
import { on(alias) function on<Type extends keyof WindowEventMap>(window: Window, type: Type, handler: (this: Window, event: WindowEventMap[Type] & {
    currentTarget: Window;
}) => any, options?: AddEventListenerOptions | undefined): () => void (+4 overloads)
import on

Attaches an event handler to the window and returns a function that removes the handler. Using this
rather than addEventListener will preserve the correct order relative to handlers added declaratively
(with attributes like onclick), which use event delegation for performance reasons


reference } from 'svelte/events';
```

## on[](#on)

Attaches an event handler to the window and returns a function that removes the handler. Using this rather than `addEventListener` will preserve the correct order relative to handlers added declaratively (with attributes like `onclick`), which use event delegation for performance reasons

```
function on<Type extends keyof WindowEventMap>(
	window: Window,
	type: Type,
	handler: (
		this: Window,
		event: WindowEventMap[Type] & { currentTarget: Window }
	) => any,
	options?: AddEventListenerOptions | undefined
): () => void;
```

```
function on<Type extends keyof DocumentEventMap>(
	document: Document,
	type: Type,
	handler: (
		this: Document,
		event: DocumentEventMap[Type] & {
			currentTarget: Document;
		}
	) => any,
	options?: AddEventListenerOptions | undefined
): () => void;
```

```
function on<
	Element extends HTMLElement,
	Type extends keyof HTMLElementEventMap
>(
	element: Element,
	type: Type,
	handler: (
		this: Element,
		event: HTMLElementEventMap[Type] & {
			currentTarget: Element;
		}
	) => any,
	options?: AddEventListenerOptions | undefined
): () => void;
```

```
function on<
	Element extends MediaQueryList,
	Type extends keyof MediaQueryListEventMap
>(
	element: Element,
	type: Type,
	handler: (
		this: Element,
		event: MediaQueryListEventMap[Type] & {
			currentTarget: Element;
		}
	) => any,
	options?: AddEventListenerOptions | undefined
): () => void;
```

```
function on(
	element: EventTarget,
	type: string,
	handler: EventListener,
	options?: AddEventListenerOptions | undefined
): () => void;
```

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/98-reference/21-svelte-events.md) [llms.txt](/docs/svelte/svelte-events/llms.txt)

previous next

[svelte/easing](/docs/svelte/svelte-easing) [svelte/legacy](/docs/svelte/svelte-legacy)

----
url: https://svelte.dev/docs/svelte/style/llms.txt
----

````
The `style:` directive provides a shorthand for setting multiple styles on an element.

```svelte
<!-- These are equivalent -->
<div style:color="red">...</div>
<div style="color: red;">...</div>
```

The value can contain arbitrary expressions:

```svelte
<div style:color={myColor}>...</div>
```

The shorthand form is allowed:

```svelte
<div style:color>...</div>
```

Multiple styles can be set on a single element:

```svelte
<div style:color style:width="12rem" style:background-color={darkMode ? 'black' : 'white'}>...</div>
```

To mark a style as important, use the `|important` modifier:

```svelte
<div style:color|important="red">...</div>
```

When `style:` directives are combined with `style` attributes, the directives will take precedence,
even over `!important` properties:

```svelte
<div style:color="red" style="color: blue">This will be red</div>
<div style:color="red" style="color: blue !important">This will still be red</div>
```

You can set CSS custom properties:

```svelte
<div style:--columns={columns}>...</div>
```
````

----
url: https://svelte.dev/docs/svelte/@html
----

[Skip to main content](#main)

To inject raw HTML into your component, use the `{@html ...}` tag:

```
<article>
	{@html content}
</article>
```

> Make sure that you either escape the passed string or only populate it with values that are under your control in order to prevent [XSS attacks](https://owasp.org/www-community/attacks/xss/). Never render unsanitized content.

The expression should be valid standalone HTML — this will not work, because `</div>` is not valid HTML:

```
{@html '<div>'}content{@html '</div>'}
```

It also will not compile Svelte code.

## Styling[](#Styling)

Content rendered this way is ‘invisible’ to Svelte and as such will not receive [scoped styles](scoped-styles). In other words, this will not work, and the `a` and `img` styles will be regarded as unused:

```
<article>
	{@html content}
</article>

<style>
	article {
		a { color: hotpink }
		img { width: 100% }
	}
</style>
```

Instead, use the `:global` modifier to target everything inside the `<article>`:

```
<style>
	article :global {
		a { color: hotpink }
		img { width: 100% }
	}
</style>
```

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/03-template-syntax/08-@html.md) [llms.txt](/docs/svelte/@html/llms.txt)

previous next

[{@render ...}](/docs/svelte/@render) [{@attach ...}](/docs/svelte/@attach)

----
url: https://svelte.dev/docs/svelte/custom-elements
----

[Skip to main content](#main)

Svelte components can also be compiled to custom elements (aka web components) using the `customElement: true` compiler option. You should specify a tag name for the component using the `<svelte:options>` [element](svelte-options). Within the custom element you can access the host element via the [`$host`](/docs/svelte/$host) rune.

```
<svelte:options customElement="my-element" />

<script>
	let { name = 'world' } = $props();
</script>

<h1>Hello {name}!</h1>
<slot />
```

You can leave out the tag name for any of your inner components which you don’t want to expose and use them like regular Svelte components. Consumers of the component can still name it afterwards if needed, using the static `element` property which contains the custom element constructor and which is available when the `customElement` compiler option is `true`.

```
import MyElement(alias) type MyElement = SvelteComponent<Record<string, any>, any, any>
(alias) const MyElement: LegacyComponentType
import MyElement from './MyElement.svelte';

customElementsvar customElements: CustomElementRegistry

The customElements read-only property of the Window interface returns a reference to the CustomElementRegistry object, which can be used to register new custom elements and get information about previously registered custom elements.




MDN Reference


.define(method) CustomElementRegistry.define(name: string, constructor: CustomElementConstructor, options?: ElementDefinitionOptions): void

The define() method of the CustomElementRegistry interface adds a definition for a custom element to the custom element registry, mapping its name to the constructor which will be used to create it.




MDN Reference


('my-element', MyElement(alias) const MyElement: LegacyComponentType
import MyElement.elementany);
```

Once a custom element has been defined, it can be used as a regular DOM element:

```
documentmodule document
var document: Document

window.document returns a reference to the document contained in the window.




MDN Reference


.body(property) Document.body: HTMLElement

The Document.body property represents the  or  node of the current document, or null if no such element exists.




MDN Reference


.innerHTML(property) Element.innerHTML: string

The innerHTML property of the Element interface gets or sets the HTML or XML markup contained within the element, omitting any shadow roots in both cases.




MDN Reference


 = `
	<my-element>
		<p>This is some slotted content</p>
	</my-element>
`;
```

Any [props](basic-markup#Component-props) are exposed as properties of the DOM element (as well as being readable/writable as attributes, where possible).

```
const elmodule el
const el: Element | null = documentvar document: Document

window.document returns a reference to the document contained in the window.




MDN Reference


.querySelector(method) ParentNode.querySelector<Element>(selectors: string): Element | null (+4 overloads)

Returns the first element that is a descendant of node that matches selectors.




MDN Reference


('my-element');

// get the current value of the 'name' prop
consolenamespace console
var console: Console

The console module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.




The module exports two specific components:





A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.


A global console instance configured to write to process.stdout and
process.stderr. The global console can be used without importing the node:console module.





Warning: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the note on process I/O for
more information.




Example using the global console:



console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
//   Error: Whoops, something bad happened
//     at [eval]:5:15
//     at Script.runInThisContext (node:vm:132:18)
//     at Object.runInThisContext (node:vm:309:38)
//     at node:internal/process/execution:77:19
//     at [eval]-wrapper:6:22
//     at evalScript (node:internal/process/execution:76:60)
//     at node:internal/main/eval_string:23:3

const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:



const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);

myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err

const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

source


.log(method) Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to printf(3)
(the arguments are all passed to util.format()).



const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.




v0.1.100


(elmodule el
const el: Element | null.nameany);

// set a new value, updating the shadow DOM
elmodule el
const el: Element | null.nameany = 'everybody';
```

Note that you need to list out all properties explicitly, i.e. doing `let props = $props()` without declaring `props` in the [component options](#Component-options) means that Svelte can’t know which props to expose as properties on the DOM element.

## Component lifecycle[](#Component-lifecycle)

Custom elements are created from Svelte components using a wrapper approach. This means the inner Svelte component has no knowledge that it is a custom element. The custom element wrapper takes care of handling its lifecycle appropriately.

When a custom element is created, the Svelte component it wraps is *not* created right away. It is only created in the next tick after the `connectedCallback` is invoked. Properties assigned to the custom element before it is inserted into the DOM are temporarily saved and then set on component creation, so their values are not lost. The same does not work for invoking exported functions on the custom element though, they are only available after the element has mounted. If you need to invoke functions before component creation, you can work around it by using the [`extend` option](#Component-options).

When a custom element written with Svelte is created or updated, the shadow DOM will reflect the value in the next tick, not immediately. This way updates can be batched, and DOM moves which temporarily (but synchronously) detach the element from the DOM don’t lead to unmounting the inner component.

The inner Svelte component is destroyed in the next tick after the `disconnectedCallback` is invoked.

## Component options[](#Component-options)

When constructing a custom element, you can tailor several aspects by defining `customElement` as an object within `<svelte:options>` since Svelte 4. This object may contain the following properties:

* `tag: string`: an optional `tag` property for the custom element’s name. If set, a custom element with this tag name will be defined with the document’s `customElements` registry upon importing this component.

* `shadow`: an optional property to modify shadow root properties. It accepts the following values:

  * `"none"`: No shadow root is created. Note that styles are then no longer encapsulated, and you can’t use slots.
  * `"open"`: Shadow root is created with the `mode: "open"` option.
  * [`ShadowRootInit`](https://developer.mozilla.org/en-US/docs/Web/API/Element/attachShadow#options): You can pass a settings object that will be passed to `attachShadow()` when shadow root is created.

* `props`: an optional property to modify certain details and behaviors of your component’s properties. It offers the following settings:

  * `attribute: string`: To update a custom element’s prop, you have two alternatives: either set the property on the custom element’s reference as illustrated above or use an HTML attribute. For the latter, the default attribute name is the lowercase property name. Modify this by assigning `attribute: "<desired name>"`.
  * `reflect: boolean`: By default, updated prop values do not reflect back to the DOM. To enable this behavior, set `reflect: true`.
  * `type: 'String' | 'Boolean' | 'Number' | 'Array' | 'Object'`: While converting an attribute value to a prop value and reflecting it back, the prop value is assumed to be a `String` by default. This may not always be accurate. For instance, for a number type, define it using `type: "Number"` You don’t need to list all properties, those not listed will use the default settings.

* `extend`: an optional property which expects a function as its argument. It is passed the custom element class generated by Svelte and expects you to return a custom element class. This comes in handy if you have very specific requirements to the life cycle of the custom element or want to enhance the class to for example use [ElementInternals](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals#examples) for better HTML form integration.

```
<svelte:options
	customElement={{
		tag: 'custom-element',
		shadow: {
			mode: import.meta.env.DEV ? 'open' : 'closed',
			clonable: true,
			// ...
		},
		props: {
			name: { reflect: true, type: 'Number', attribute: 'element-index' }
		},
		extend: (customElementConstructor) => {
			// Extend the class so we can let it participate in HTML forms
			return class extends customElementConstructor {
				static formAssociated = true;

				constructor() {
					super();
					this.attachedInternals = this.attachInternals();
				}

				// Add the function here, not below in the component so that
				// it's always available, not just when the inner Svelte component
				// is mounted
				randomIndex() {
					this.elementIndex = Math.random();
				}
			};
		}
	}}
/>

<script>
	let { elementIndex, attachedInternals } = $props();
	// ...
	function check() {
		attachedInternals.checkValidity();
	}
</script>

...
```

> While Typescript is supported in the `extend` function, it is subject to limitations: you need to set `lang="ts"` on one of the scripts AND you can only use [erasable syntax](https://www.typescriptlang.org/tsconfig/#erasableSyntaxOnly) in it. They are not processed by script preprocessors.

## Caveats and limitations[](#Caveats-and-limitations)

Custom elements can be a useful way to package components for consumption in a non-Svelte app, as they will work with vanilla HTML and JavaScript as well as [most frameworks](https://custom-elements-everywhere.com/). There are, however, some important differences to be aware of:

* Styles are *encapsulated*, rather than merely *scoped* (unless you set `shadow: "none"`). This means that any non-component styles (such as you might have in a `global.css` file) will not apply to the custom element, including styles with the `:global(...)` modifier
* Instead of being extracted out as a separate .css file, styles are inlined into the component as a JavaScript string
* Custom elements are not generally suitable for server-side rendering, as the shadow DOM is invisible until JavaScript loads
* In Svelte, slotted content renders *lazily*. In the DOM, it renders *eagerly*. In other words, it will always be created even if the component’s `<slot>` element is inside an `{#if ...}` block. Similarly, including a `<slot>` in an `{#each ...}` block will not cause the slotted content to be rendered multiple times
* The deprecated `let:` directive has no effect, because custom elements do not have a way to pass data to the parent component that fills the slot
* Polyfills are required to support older browsers
* You can use Svelte’s context feature between regular Svelte components within a custom element, but you can’t use them across custom elements. In other words, you can’t use `setContext` on a parent custom element and read that with `getContext` in a child custom element.
* Don’t declare properties or attributes starting with `on`, as their usage will be interpreted as an event listener. In other words, Svelte treats `<custom-element oneworld={true}></custom-element>` as `customElement.addEventListener('eworld', true)` (and not as `customElement.oneworld = true`)

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/07-misc/04-custom-elements.md) [llms.txt](/docs/svelte/custom-elements/llms.txt)

previous next

[TypeScript](/docs/svelte/typescript) [Browser support](/docs/svelte/browser-support)

----
url: https://svelte.dev/docs/svelte/legacy-let/llms.txt
----

````
In runes mode, reactive state is explicitly declared with the [`$state` rune]($state).

In legacy mode, variables declared at the top level of a component are automatically considered _reactive_. Reassigning or mutating these variables (`count += 1` or `object.x = y`) will cause the UI to update.

```svelte
<script>
	let count = 0;
</script>

<button on:click={() => count += 1}>
	clicks: {count}
</button>
```

Because Svelte's legacy mode reactivity is based on _assignments_, using array methods like `.push()` and `.splice()` won't automatically trigger updates. A subsequent assignment is required to 'tell' the compiler to update the UI:

```svelte
<script>
	let numbers = [1, 2, 3, 4];

	function addNumber() {
		// this method call does not trigger an update
		numbers.push(numbers.length + 1);

		// this assignment will update anything
		// that depends on `numbers`
		numbers = numbers;
	}
</script>
```
````

----
url: https://svelte.dev/docs/svelte/legacy-export-let/llms.txt
----

````
In runes mode, [component props](basic-markup#Component-props) are declared with the [`$props`]($props) rune, allowing parent components to pass in data.

In legacy mode, props are marked with the `export` keyword, and can have a default value:

```svelte
<script>
	export let foo;
	export let bar = 'default value';

	// Values that are passed in as props
	// are immediately available
	console.log({ foo });
</script>
```

The default value is used if it would otherwise be `undefined` when the component is created.

> [!NOTE] Unlike in runes mode, if the parent component changes a prop from a defined value to `undefined`, it does not revert to the initial value.

Props without default values are considered _required_, and Svelte will print a warning during development if no value is provided, which you can squelch by specifying `undefined` as the default value:

```js
export let foo +++= undefined;+++
```

## Component exports

An exported `const`, `class` or `function` declaration is _not_ considered a prop — instead, it becomes part of the component's API:

```svelte
<!--- file: Greeter.svelte--->
<script>
	export function greet(name) {
		alert(`hello ${name}!`);
	}
</script>
```

```svelte
<!--- file: App.svelte --->
<script>
	import Greeter from './Greeter.svelte';

	let greeter;
</script>

<Greeter bind:this={greeter} />

<button on:click={() => greeter.greet('world')}>
	greet
</button>
```

## Renaming props

The `export` keyword can appear separately from the declaration. This is useful for renaming props, for example in the case of a reserved word:

```svelte
<!--- file: App.svelte --->
<script>
	/** @type {string} */
	let className;

	// creates a `class` property, even
	// though it is a reserved word
	export { className as class };
</script>
```
````

----
url: https://svelte.dev/docs/svelte/legacy-svelte-fragment
----

[Skip to main content](#main)

The `<svelte:fragment>` element allows you to place content in a [named slot](legacy-slots) without wrapping it in a container DOM element. This keeps the flow layout of your document intact.

Widget

```
<div>
	<slot name="header">No header was provided</slot>
	<p>Some content between header and footer</p>
	<slot name="footer" />
</div>
```

App

```
<script>
	import Widget from './Widget.svelte';
</script>

<Widget>
	<h1 slot="header">Hello</h1>
	<svelte:fragment slot="footer">
		<p>All rights reserved.</p>
		<p>Copyright (c) 2019 Svelte Industries</p>
	</svelte:fragment>
</Widget>
```

```
<script lang="ts">
	import Widget from './Widget.svelte';
</script>

<Widget>
	<h1 slot="header">Hello</h1>
	<svelte:fragment slot="footer">
		<p>All rights reserved.</p>
		<p>Copyright (c) 2019 Svelte Industries</p>
	</svelte:fragment>
</Widget>
```

> In Svelte 5+, this concept is obsolete, as snippets don’t create a wrapping element

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/99-legacy/22-legacy-svelte-fragment.md) [llms.txt](/docs/svelte/legacy-svelte-fragment/llms.txt)

previous next

[$$slots](/docs/svelte/legacy-$$slots) [\<svelte:component>](/docs/svelte/legacy-svelte-component)

----
url: https://svelte.dev/docs/svelte/svelte-js-files
----

[Skip to main content](#main)

Besides `.svelte` files, Svelte also operates on `.svelte.js` and `.svelte.ts` files.

These behave like any other `.js` or `.ts` module, except that you can use runes. This is useful for creating reusable reactive logic, or sharing reactive state across your app (though note that you [cannot export reassigned state]($state#Passing-state-across-modules)).

> Legacy mode
>
> This is a concept that didn’t exist prior to Svelte 5

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/01-introduction/04-svelte-js-files.md) [llms.txt](/docs/svelte/svelte-js-files/llms.txt)

previous next

[.svelte files](/docs/svelte/svelte-files) [What are runes?](/docs/svelte/what-are-runes)

----
url: https://svelte.dev/docs/svelte/@html/llms.txt
----

````
To inject raw HTML into your component, use the `{@html ...}` tag:

```svelte
<article>
	{@html content}
</article>
```

> [!NOTE] Make sure that you either escape the passed string or only populate it with values that are under your control in order to prevent [XSS attacks](https://owasp.org/www-community/attacks/xss/). Never render unsanitized content.

The expression should be valid standalone HTML — this will not work, because `</div>` is not valid HTML:

```svelte
{@html '<div>'}content{@html '</div>'}
```

It also will not compile Svelte code.

## Styling

Content rendered this way is 'invisible' to Svelte and as such will not receive [scoped styles](scoped-styles). In other words, this will not work, and the `a` and `img` styles will be regarded as unused:

<!-- prettier-ignore -->
```svelte
<article>
	{@html content}
</article>

<style>
	article {
		a { color: hotpink }
		img { width: 100% }
	}
</style>
```

Instead, use the `:global` modifier to target everything inside the `<article>`:

<!-- prettier-ignore -->
```svelte
<style>
	article +++:global+++ {
		a { color: hotpink }
		img { width: 100% }
	}
</style>
```
````

----
url: https://svelte.dev/docs/svelte/svelte-options
----

[Skip to main content](#main)

```
<svelte:options option={value} />
```

The `<svelte:options>` element provides a place to specify per-component compiler options, which are detailed in the [compiler section](svelte-compiler#compile). The possible options are:

* `runes={true}` — forces a component into *runes mode* (see the [Legacy APIs](legacy-overview) section)
* `runes={false}` — forces a component into *legacy mode*
* `namespace="..."` — the namespace where this component will be used, can be “html” (the default), “svg” or “mathml”
* `customElement={...}` — the [options](custom-elements#Component-options) to use when compiling this component as a custom element. If a string is passed, it is used as the `tag` option
* `css="injected"` — the component will inject its styles inline: During server-side rendering, it’s injected as a `<style>` tag in the `head`, during client side rendering, it’s loaded via JavaScript

> Legacy mode
>
> Deprecated options Svelte 4 also included the following options. They are deprecated in Svelte 5 and non-functional in runes mode.
>
> * `immutable={true}` — you never use mutable data, so the compiler can do simple referential equality checks to determine if values have changed
> * `immutable={false}` — the default. Svelte will be more conservative about whether or not mutable objects have changed
> * `accessors={true}` — adds getters and setters for the component’s props
> * `accessors={false}` — the default

```
<svelte:options customElement="my-custom-element" />
```

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/05-special-elements/07-svelte-options.md) [llms.txt](/docs/svelte/svelte-options/llms.txt)

previous next

[\<svelte:element>](/docs/svelte/svelte-element) [Stores](/docs/svelte/stores)

----
url: https://svelte.dev/docs/svelte/svelte-window/llms.txt
----

````
```svelte
<svelte:window onevent={handler} />
```

```svelte
<svelte:window bind:prop={value} />
```

The `<svelte:window>` element allows you to add event listeners to the `window` object without worrying about removing them when the component is destroyed, or checking for the existence of `window` when server-side rendering.

This element may only appear at the top level of your component — it cannot be inside a block or element.

```svelte
<script>
	function handleKeydown(event) {
		alert(`pressed the ${event.key} key`);
	}
</script>

<svelte:window onkeydown={handleKeydown} />
```

You can also bind to the following properties:

- `innerWidth`
- `innerHeight`
- `outerWidth`
- `outerHeight`
- `scrollX`
- `scrollY`
- `online` — an alias for `window.navigator.onLine`
- `devicePixelRatio`

All except `scrollX` and `scrollY` are readonly.

```svelte
<svelte:window bind:scrollY={y} />
```

> [!NOTE] Note that the page will not be scrolled to the initial value to avoid accessibility issues. Only subsequent changes to the bound variable of `scrollX` and `scrollY` will cause scrolling. If you have a legitimate reason to scroll when the component is rendered, call `scrollTo()` in an `$effect`.
````

----
url: https://svelte.dev/docs/svelte/svelte-store/llms.txt
----

````
```js
// @noErrors
import {
	derived,
	fromStore,
	get,
	readable,
	readonly,
	toStore,
	writable
} from 'svelte/store';
```

## derived

Derived value store by synchronizing one or more readable stores and
applying an aggregation function over its input values.

<div class="ts-block">

```dts
function derived<S extends Stores, T>(
	stores: S,
	fn: (
		values: StoresValues<S>,
		set: (value: T) => void,
		update: (fn: Updater<T>) => void
	) => Unsubscriber | void,
	initial_value?: T | undefined
): Readable<T>;
```

</div>

<div class="ts-block">

```dts
function derived<S extends Stores, T>(
	stores: S,
	fn: (values: StoresValues<S>) => T,
	initial_value?: T | undefined
): Readable<T>;
```

</div>



## fromStore

<div class="ts-block">

```dts
function fromStore<V>(store: Writable<V>): {
	current: V;
};
```

</div>

<div class="ts-block">

```dts
function fromStore<V>(store: Readable<V>): {
	readonly current: V;
};
```

</div>



## get

Get the current value from a store by subscribing and immediately unsubscribing.

<div class="ts-block">

```dts
function get<T>(store: Readable<T>): T;
```

</div>



## readable

Creates a `Readable` store that allows reading by subscription.

<div class="ts-block">

```dts
function readable<T>(
	value?: T | undefined,
	start?: StartStopNotifier<T> | undefined
): Readable<T>;
```

</div>



## readonly

Takes a store and returns a new one derived from the old one that is readable.

<div class="ts-block">

```dts
function readonly<T>(store: Readable<T>): Readable<T>;
```

</div>



## toStore

<div class="ts-block">

```dts
function toStore<V>(
	get: () => V,
	set: (v: V) => void
): Writable<V>;
```

</div>

<div class="ts-block">

```dts
function toStore<V>(get: () => V): Readable<V>;
```

</div>



## writable

Create a `Writable` store that allows both updating and reading by subscription.

<div class="ts-block">

```dts
function writable<T>(
	value?: T | undefined,
	start?: StartStopNotifier<T> | undefined
): Writable<T>;
```

</div>



## Readable

Readable interface for subscribing.

<div class="ts-block">

```dts
interface Readable<T> {/*…*/}
```

<div class="ts-block-property">

```dts
subscribe(this: void, run: Subscriber<T>, invalidate?: () => void): Unsubscriber;
```

<div class="ts-block-property-details">

<div class="ts-block-property-bullets">

- `run` subscription callback
- `invalidate` cleanup callback

</div>

Subscribe on value changes.

</div>
</div></div>

## StartStopNotifier

Start and stop notification callbacks.
This function is called when the first subscriber subscribes.

<div class="ts-block">

```dts
type StartStopNotifier<T> = (
	set: (value: T) => void,
	update: (fn: Updater<T>) => void
) => void | (() => void);
```

</div>

## Subscriber

Callback to inform of a value updates.

<div class="ts-block">

```dts
type Subscriber<T> = (value: T) => void;
```

</div>

## Unsubscriber

Unsubscribes from value updates.

<div class="ts-block">

```dts
type Unsubscriber = () => void;
```

</div>

## Updater

Callback to update a value.

<div class="ts-block">

```dts
type Updater<T> = (value: T) => T;
```

</div>

## Writable

Writable interface for both updating and subscribing.

<div class="ts-block">

```dts
interface Writable<T> extends Readable<T> {/*…*/}
```

<div class="ts-block-property">

```dts
set(this: void, value: T): void;
```

<div class="ts-block-property-details">

<div class="ts-block-property-bullets">

- `value` to set

</div>

Set value and inform subscribers.

</div>
</div>

<div class="ts-block-property">

```dts
update(this: void, updater: Updater<T>): void;
```

<div class="ts-block-property-details">

<div class="ts-block-property-bullets">

- `updater` callback

</div>

Update value using callback and inform subscribers.

</div>
</div></div>
````

----
url: https://svelte.dev/docs/svelte/svelte-store
----

[Skip to main content](#main)

```
import {
	derived(alias) function derived<S extends Stores, T>(stores: S, fn: (values: StoresValues<S>, set: (value: T) => void, update: (fn: Updater<T>) => void) => Unsubscriber | void, initial_value?: T | undefined): Readable<T> (+1 overload)
import derived

Derived value store by synchronizing one or more readable stores and
applying an aggregation function over its input values.


reference,
	fromStore(alias) function fromStore<V>(store: Writable<V>): {
    current: V;
} (+1 overload)
import fromStorereference,
	get(alias) function get<T>(store: Readable<T>): T
import get

Get the current value from a store by subscribing and immediately unsubscribing.


reference,
	readable(alias) function readable<T>(value?: T | undefined, start?: StartStopNotifier<T> | undefined): Readable<T>
import readable

Creates a Readable store that allows reading by subscription.


value 

initial value


reference,
	readonly(alias) function readonly<T>(store: Readable<T>): Readable<T>
import readonly

Takes a store and returns a new one derived from the old one that is readable.


store 


store to make readonly



reference,
	toStore(alias) function toStore<V>(get: () => V, set: (v: V) => void): Writable<V> (+1 overload)
import toStorereference,
	writable(alias) function writable<T>(value?: T | undefined, start?: StartStopNotifier<T> | undefined): Writable<T>
import writable

Create a Writable store that allows both updating and reading by subscription.


value 

initial value


reference
} from 'svelte/store';
```

## derived[](#derived)

Derived value store by synchronizing one or more readable stores and applying an aggregation function over its input values.

```
function derived<S extends Stores, T>(
	stores: S,
	fn: (
		values: StoresValues<S>,
		set: (value: T) => void,
		update: (fn: Updater<T>) => void
	) => Unsubscriber | void,
	initial_value?: T | undefined
): Readable<T>;
```

```
function derived<S extends Stores, T>(
	stores: S,
	fn: (values: StoresValues<S>) => T,
	initial_value?: T | undefined
): Readable<T>;
```

## fromStore[](#fromStore)

```
function fromStore<V>(store: Writable<V>): {
	current: V;
};
```

```
function fromStore<V>(store: Readable<V>): {
	readonly current: V;
};
```

## get[](#get)

Get the current value from a store by subscribing and immediately unsubscribing.

```
function get<T>(store: Readable<T>): T;
```

## readable[](#readable)

Creates a `Readable` store that allows reading by subscription.

```
function readable<T>(
	value?: T | undefined,
	start?: StartStopNotifier<T> | undefined
): Readable<T>;
```

## readonly[](#readonly)

Takes a store and returns a new one derived from the old one that is readable.

```
function readonly<T>(store: Readable<T>): Readable<T>;
```

## toStore[](#toStore)

```
function toStore<V>(
	get: () => V,
	set: (v: V) => void
): Writable<V>;
```

```
function toStore<V>(get: () => V): Readable<V>;
```

## writable[](#writable)

Create a `Writable` store that allows both updating and reading by subscription.

```
function writable<T>(
	value?: T | undefined,
	start?: StartStopNotifier<T> | undefined
): Writable<T>;
```

## Readable[](#Readable)

Readable interface for subscribing.

```
interface Readable<T> {/*…*/}
```

```
subscribe(this: void, run: Subscriber<T>, invalidate?: () => void): Unsubscriber;
```

* `run` subscription callback
* `invalidate` cleanup callback

Subscribe on value changes.

## StartStopNotifier[](#StartStopNotifier)

Start and stop notification callbacks. This function is called when the first subscriber subscribes.

```
type StartStopNotifier<T> = (
	set: (value: T) => void,
	update: (fn: Updater<T>) => void
) => void | (() => void);
```

## Subscriber[](#Subscriber)

Callback to inform of a value updates.

```
type Subscriber<T> = (value: T) => void;
```

## Unsubscriber[](#Unsubscriber)

Unsubscribes from value updates.

```
type Unsubscriber = () => void;
```

## Updater[](#Updater)

Callback to update a value.

```
type Updater<T> = (value: T) => T;
```

## Writable[](#Writable)

Writable interface for both updating and subscribing.

```
interface Writable<T> extends Readable<T> {/*…*/}
```

```
set(this: void, value: T): void;
```

* `value` to set

Set value and inform subscribers.

```
update(this: void, updater: Updater<T>): void;
```

* `updater` callback

Update value using callback and inform subscribers.

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/98-reference/21-svelte-store.md) [llms.txt](/docs/svelte/svelte-store/llms.txt)

previous next

[svelte/server](/docs/svelte/svelte-server) [svelte/transition](/docs/svelte/svelte-transition)

----
url: https://svelte.dev/docs/svelte/compiler-errors
----

[Skip to main content](#main)

### animation\_duplicate[](#animation_duplicate)

```
An element can only have one 'animate' directive
```

### animation\_invalid\_placement[](#animation_invalid_placement)

```
An element that uses the `animate:` directive must be the only child of a keyed `{#each ...}` block
```

### animation\_missing\_key[](#animation_missing_key)

```
An element that uses the `animate:` directive must be the only child of a keyed `{#each ...}` block. Did you forget to add a key to your each block?
```

### attribute\_contenteditable\_dynamic[](#attribute_contenteditable_dynamic)

```
'contenteditable' attribute cannot be dynamic if element uses two-way binding
```

### attribute\_contenteditable\_missing[](#attribute_contenteditable_missing)

```
'contenteditable' attribute is required for textContent, innerHTML and innerText two-way bindings
```

### attribute\_duplicate[](#attribute_duplicate)

```
Attributes need to be unique
```

### attribute\_empty\_shorthand[](#attribute_empty_shorthand)

```
Attribute shorthand cannot be empty
```

### attribute\_invalid\_event\_handler[](#attribute_invalid_event_handler)

```
Event attribute must be a JavaScript expression, not a string
```

### attribute\_invalid\_multiple[](#attribute_invalid_multiple)

```
'multiple' attribute must be static if select uses two-way binding
```

### attribute\_invalid\_name[](#attribute_invalid_name)

```
'%name%' is not a valid attribute name
```

### attribute\_invalid\_sequence\_expression[](#attribute_invalid_sequence_expression)

```
Comma-separated expressions are not allowed as attribute/directive values in runes mode, unless wrapped in parentheses
```

An attribute value cannot be a comma-separated sequence of expressions — in other words this is disallowed:

```
<div class={size, color}>...</div>
```

Instead, make sure that the attribute value contains a single expression. In the example above it’s likely that this was intended (see the [class documentation](class) for more details):

```
<div class={[size, color]}>...</div>
```

If you *do* need to use the comma operator for some reason, wrap the sequence in parentheses:

```
<div class={(size, color)}>...</div>
```

Note that this will evaluate to `color`, ignoring `size`.

### attribute\_invalid\_type[](#attribute_invalid_type)

```
'type' attribute must be a static text value if input uses two-way binding
```

### attribute\_unquoted\_sequence[](#attribute_unquoted_sequence)

```
Attribute values containing `{...}` must be enclosed in quote marks, unless the value only contains the expression
```

### bind\_group\_invalid\_expression[](#bind_group_invalid_expression)

```
`bind:group` can only bind to an Identifier or MemberExpression
```

### bind\_group\_invalid\_snippet\_parameter[](#bind_group_invalid_snippet_parameter)

```
Cannot `bind:group` to a snippet parameter
```

### bind\_invalid\_expression[](#bind_invalid_expression)

```
Can only bind to an Identifier or MemberExpression or a `{get, set}` pair
```

### bind\_invalid\_name[](#bind_invalid_name)

```
`bind:%name%` is not a valid binding
```

```
`bind:%name%` is not a valid binding. %explanation%
```

### bind\_invalid\_parens[](#bind_invalid_parens)

```
`bind:%name%={get, set}` must not have surrounding parentheses
```

### bind\_invalid\_target[](#bind_invalid_target)

```
`bind:%name%` can only be used with %elements%
```

### bind\_invalid\_value[](#bind_invalid_value)

```
Can only bind to state or props
```

### bindable\_invalid\_location[](#bindable_invalid_location)

```
`$bindable()` can only be used inside a `$props()` declaration
```

### block\_duplicate\_clause[](#block_duplicate_clause)

```
%name% cannot appear more than once within a block
```

### block\_invalid\_continuation\_placement[](#block_invalid_continuation_placement)

```
{:...} block is invalid at this position (did you forget to close the preceding element or block?)
```

### block\_invalid\_elseif[](#block_invalid_elseif)

```
'elseif' should be 'else if'
```

### block\_invalid\_placement[](#block_invalid_placement)

```
{#%name% ...} block cannot be %location%
```

### block\_unclosed[](#block_unclosed)

```
Block was left open
```

### block\_unexpected\_character[](#block_unexpected_character)

```
Expected a `%character%` character immediately following the opening bracket
```

### block\_unexpected\_close[](#block_unexpected_close)

```
Unexpected block closing tag
```

### component\_invalid\_directive[](#component_invalid_directive)

```
This type of directive is not valid on components
```

### const\_tag\_cycle[](#const_tag_cycle)

```
Cyclical dependency detected: %cycle%
```

### const\_tag\_invalid\_expression[](#const_tag_invalid_expression)

```
{@const ...} must consist of a single variable declaration
```

### const\_tag\_invalid\_placement[](#const_tag_invalid_placement)

```
`{@const}` must be the immediate child of `{#snippet}`, `{#if}`, `{:else if}`, `{:else}`, `{#each}`, `{:then}`, `{:catch}`, `<svelte:fragment>`, `<svelte:boundary>` or `<Component>`
```

### const\_tag\_invalid\_reference[](#const_tag_invalid_reference)

```
The `{@const %name% = ...}` declaration is not available in this snippet
```

The following is an error:

```
<svelte:boundary>
	{@const foo = 'bar'}

	{#snippet failed()}
		{foo}
	{/snippet}
</svelte:boundary>
```

Here, `foo` is not available inside `failed`. The top level code inside `<svelte:boundary>` becomes part of the implicit `children` snippet, in other words the above code is equivalent to this:

```
<svelte:boundary>
	{#snippet children()}
		{@const foo = 'bar'}
	{/snippet}

	{#snippet failed()}
		{foo}
	{/snippet}
</svelte:boundary>
```

The same applies to components:

```
<Component>
	{@const foo = 'bar'}

	{#snippet someProp()}
		<!-- error -->
		{foo}
	{/snippet}
</Component>
```

### constant\_assignment[](#constant_assignment)

```
Cannot assign to %thing%
```

### constant\_binding[](#constant_binding)

```
Cannot bind to %thing%
```

### css\_empty\_declaration[](#css_empty_declaration)

```
Declaration cannot be empty
```

### css\_expected\_identifier[](#css_expected_identifier)

```
Expected a valid CSS identifier
```

### css\_global\_block\_invalid\_combinator[](#css_global_block_invalid_combinator)

```
A `:global` selector cannot follow a `%name%` combinator
```

### css\_global\_block\_invalid\_declaration[](#css_global_block_invalid_declaration)

```
A top-level `:global {...}` block can only contain rules, not declarations
```

### css\_global\_block\_invalid\_list[](#css_global_block_invalid_list)

```
A `:global` selector cannot be part of a selector list with entries that don't contain `:global`
```

The following CSS is invalid:

```
:global, x {
	y {
		color: red;
	}
}
```

This is mixing a `:global` block, which means “everything in here is unscoped”, with a scoped selector (`x` in this case). As a result it’s not possible to transform the inner selector (`y` in this case) into something that satisfies both requirements. You therefore have to split this up into two selectors:

```
:global {
	y {
		color: red;
	}
}

x y {
	color: red;
}
```

### css\_global\_block\_invalid\_modifier[](#css_global_block_invalid_modifier)

```
A `:global` selector cannot modify an existing selector
```

### css\_global\_block\_invalid\_modifier\_start[](#css_global_block_invalid_modifier_start)

```
A `:global` selector can only be modified if it is a descendant of other selectors
```

### css\_global\_block\_invalid\_placement[](#css_global_block_invalid_placement)

```
A `:global` selector cannot be inside a pseudoclass
```

### css\_global\_invalid\_placement[](#css_global_invalid_placement)

```
`:global(...)` can be at the start or end of a selector sequence, but not in the middle
```

### css\_global\_invalid\_selector[](#css_global_invalid_selector)

```
`:global(...)` must contain exactly one selector
```

### css\_global\_invalid\_selector\_list[](#css_global_invalid_selector_list)

```
`:global(...)` must not contain type or universal selectors when used in a compound selector
```

### css\_nesting\_selector\_invalid\_placement[](#css_nesting_selector_invalid_placement)

```
Nesting selectors can only be used inside a rule or as the first selector inside a lone `:global(...)`
```

### css\_selector\_invalid[](#css_selector_invalid)

```
Invalid selector
```

### css\_type\_selector\_invalid\_placement[](#css_type_selector_invalid_placement)

```
`:global(...)` must not be followed by a type selector
```

### debug\_tag\_invalid\_arguments[](#debug_tag_invalid_arguments)

```
{@debug ...} arguments must be identifiers, not arbitrary expressions
```

### declaration\_duplicate[](#declaration_duplicate)

```
`%name%` has already been declared
```

### declaration\_duplicate\_module\_import[](#declaration_duplicate_module_import)

```
Cannot declare a variable with the same name as an import from `<script module>`
```

### declaration\_tag\_invalid\_type[](#declaration_tag_invalid_type)

```
Declaration tags must be `let` or `const` declarations
```

### declaration\_tag\_no\_legacy\_mode[](#declaration_tag_no_legacy_mode)

```
Declaration tags cannot be used in legacy mode
```

### derived\_invalid\_export[](#derived_invalid_export)

```
Cannot export derived state from a module. To expose the current derived value, export a function returning its value
```

### directive\_invalid\_value[](#directive_invalid_value)

```
Directive value must be a JavaScript expression enclosed in curly braces
```

### directive\_missing\_name[](#directive_missing_name)

```
`%type%` name cannot be empty
```

### dollar\_binding\_invalid[](#dollar_binding_invalid)

```
The $ name is reserved, and cannot be used for variables and imports
```

### dollar\_prefix\_invalid[](#dollar_prefix_invalid)

```
The $ prefix is reserved, and cannot be used for variables and imports
```

### duplicate\_class\_field[](#duplicate_class_field)

```
`%name%` has already been declared
```

### each\_item\_invalid\_assignment[](#each_item_invalid_assignment)

```
Cannot reassign or bind to each block argument in runes mode. Use the array and index variables instead (e.g. `array[i] = value` instead of `entry = value`, or `bind:value={array[i]}` instead of `bind:value={entry}`)
```

In legacy mode, it was possible to reassign or bind to the each block argument itself:

```
<script>
	let array = [1, 2, 3];
</script>

{#each array as entry}
	<!-- reassignment -->
	<button on:click={() => entry = 4}>change</button>

	<!-- binding -->
	<input bind:value={entry}>
{/each}
```

This turned out to be buggy and unpredictable, particularly when working with derived values (such as `array.map(...)`), and as such is forbidden in runes mode. You can achieve the same outcome by using the index instead:

```
<script>
	let array = $state([1, 2, 3]);
</script>

{#each array as entry, i}
	<!-- reassignment -->
	<button onclick={() => array[i] = 4}>change</button>

	<!-- binding -->
	<input bind:value={array[i]}>
{/each}
```

### each\_key\_without\_as[](#each_key_without_as)

```
An `{#each ...}` block without an `as` clause cannot have a key
```

### effect\_invalid\_placement[](#effect_invalid_placement)

```
`$effect()` can only be used as an expression statement
```

### element\_invalid\_closing\_tag[](#element_invalid_closing_tag)

```
`</%name%>` attempted to close an element that was not open
```

### element\_invalid\_closing\_tag\_autoclosed[](#element_invalid_closing_tag_autoclosed)

```
`</%name%>` attempted to close element that was already automatically closed by `<%reason%>` (cannot nest `<%reason%>` inside `<%name%>`)
```

### element\_unclosed[](#element_unclosed)

```
`<%name%>` was left open
```

### event\_handler\_invalid\_component\_modifier[](#event_handler_invalid_component_modifier)

```
Event modifiers other than 'once' can only be used on DOM elements
```

### event\_handler\_invalid\_modifier[](#event_handler_invalid_modifier)

```
Valid event modifiers are %list%
```

### event\_handler\_invalid\_modifier\_combination[](#event_handler_invalid_modifier_combination)

```
The '%modifier1%' and '%modifier2%' modifiers cannot be used together
```

### expected\_attribute\_value[](#expected_attribute_value)

```
Expected attribute value
```

### expected\_block\_type[](#expected_block_type)

```
Expected 'if', 'each', 'await', 'key' or 'snippet'
```

### expected\_identifier[](#expected_identifier)

```
Expected an identifier
```

### expected\_pattern[](#expected_pattern)

```
Expected identifier or destructure pattern
```

### expected\_tag[](#expected_tag)

```
Expected 'html', 'render', 'attach', 'const', or 'debug'
```

### expected\_token[](#expected_token)

```
Expected token %token%
```

### expected\_whitespace[](#expected_whitespace)

```
Expected whitespace
```

### experimental\_async[](#experimental_async)

```
Cannot use `await` in deriveds and template expressions, or at the top level of a component, unless the `experimental.async` compiler option is `true`
```

### export\_undefined[](#export_undefined)

```
`%name%` is not defined
```

### global\_reference\_invalid[](#global_reference_invalid)

```
`%name%` is an illegal variable name. To reference a global variable called `%name%`, use `globalThis.%name%`
```

### host\_invalid\_placement[](#host_invalid_placement)

```
`$host()` can only be used inside custom element component instances
```

### illegal\_await\_expression[](#illegal_await_expression)

```
`use:`, `transition:` and `animate:` directives, attachments and bindings do not support await expressions
```

### illegal\_element\_attribute[](#illegal_element_attribute)

```
`<%name%>` does not support non-event attributes or spread attributes
```

### import\_svelte\_internal\_forbidden[](#import_svelte_internal_forbidden)

```
Imports of `svelte/internal/*` are forbidden. It contains private runtime code which is subject to change without notice. If you're importing from `svelte/internal/*` to work around a limitation of Svelte, please open an issue at https://github.com/sveltejs/svelte and explain your use case
```

### inspect\_trace\_generator[](#inspect_trace_generator)

```
`$inspect.trace(...)` cannot be used inside a generator function
```

### inspect\_trace\_invalid\_placement[](#inspect_trace_invalid_placement)

```
`$inspect.trace(...)` must be the first statement of a function body
```

### invalid\_arguments\_usage[](#invalid_arguments_usage)

```
The arguments keyword cannot be used within the template or at the top level of a component
```

### js\_parse\_error[](#js_parse_error)

```
%message%
```

### legacy\_await\_invalid[](#legacy_await_invalid)

```
Cannot use `await` in deriveds and template expressions, or at the top level of a component, unless in runes mode
```

### legacy\_export\_invalid[](#legacy_export_invalid)

```
Cannot use `export let` in runes mode — use `$props()` instead
```

### legacy\_props\_invalid[](#legacy_props_invalid)

```
Cannot use `$$props` in runes mode
```

### legacy\_reactive\_statement\_invalid[](#legacy_reactive_statement_invalid)

```
`$:` is not allowed in runes mode, use `$derived` or `$effect` instead
```

### legacy\_rest\_props\_invalid[](#legacy_rest_props_invalid)

```
Cannot use `$$restProps` in runes mode
```

### let\_directive\_invalid\_placement[](#let_directive_invalid_placement)

```
`let:` directive at invalid position
```

### let\_directive\_snippet\_conflict[](#let_directive_snippet_conflict)

```
Cannot use `let:` directives on a component that has a `children` snippet. Use snippet parameters instead (e.g. `{#snippet children({ %name% })}`)
```

### mixed\_event\_handler\_syntaxes[](#mixed_event_handler_syntaxes)

```
Mixing old (on:%name%) and new syntaxes for event handling is not allowed. Use only the on%name% syntax
```

### module\_illegal\_default\_export[](#module_illegal_default_export)

```
A component cannot have a default export
```

### node\_invalid\_placement[](#node_invalid_placement)

```
%message%. The browser will 'repair' the HTML (by moving, removing, or inserting elements) which breaks Svelte's assumptions about the structure of your components.
```

HTML restricts where certain elements can appear. In case of a violation the browser will ‘repair’ the HTML in a way that breaks Svelte’s assumptions about the structure of your components. Some examples:

* `<p>hello <div>world</div></p>` will result in `<p>hello </p><div>world</div><p></p>` (the `<div>` autoclosed the `<p>` because `<p>` cannot contain block-level elements)
* `<option><div>option a</div></option>` will result in `<option>option a</option>` (the `<div>` is removed)
* `<table><tr><td>cell</td></tr></table>` will result in `<table><tbody><tr><td>cell</td></tr></tbody></table>` (a `<tbody>` is auto-inserted)

### options\_invalid\_value[](#options_invalid_value)

```
Invalid compiler option: %details%
```

### options\_removed[](#options_removed)

```
Invalid compiler option: %details%
```

### options\_unrecognised[](#options_unrecognised)

```
Unrecognised compiler option %keypath%
```

### props\_duplicate[](#props_duplicate)

```
Cannot use `%rune%()` more than once
```

### props\_id\_invalid\_placement[](#props_id_invalid_placement)

```
`$props.id()` can only be used at the top level of components as a variable declaration initializer
```

### props\_illegal\_name[](#props_illegal_name)

```
Declaring or accessing a prop starting with `$$` is illegal (they are reserved for Svelte internals)
```

### props\_invalid\_identifier[](#props_invalid_identifier)

```
`$props()` can only be used with an object destructuring pattern
```

### props\_invalid\_pattern[](#props_invalid_pattern)

```
`$props()` assignment must not contain nested properties or computed keys
```

### props\_invalid\_placement[](#props_invalid_placement)

```
`$props()` can only be used at the top level of components as a variable declaration initializer
```

### reactive\_declaration\_cycle[](#reactive_declaration_cycle)

```
Cyclical dependency detected: %cycle%
```

### render\_tag\_invalid\_call\_expression[](#render_tag_invalid_call_expression)

```
Calling a snippet function using apply, bind or call is not allowed
```

### render\_tag\_invalid\_expression[](#render_tag_invalid_expression)

```
`{@render ...}` tags can only contain call expressions
```

### render\_tag\_invalid\_spread\_argument[](#render_tag_invalid_spread_argument)

```
cannot use spread arguments in `{@render ...}` tags
```

### rune\_invalid\_arguments[](#rune_invalid_arguments)

```
`%rune%` cannot be called with arguments
```

### rune\_invalid\_arguments\_length[](#rune_invalid_arguments_length)

```
`%rune%` must be called with %args%
```

### rune\_invalid\_computed\_property[](#rune_invalid_computed_property)

```
Cannot access a computed property of a rune
```

### rune\_invalid\_name[](#rune_invalid_name)

```
`%name%` is not a valid rune
```

### rune\_invalid\_spread[](#rune_invalid_spread)

```
`%rune%` cannot be called with a spread argument
```

### rune\_invalid\_usage[](#rune_invalid_usage)

```
Cannot use `%rune%` rune in non-runes mode
```

### rune\_missing\_parentheses[](#rune_missing_parentheses)

```
Cannot use rune without parentheses
```

Runes are keywords rather than values — they can’t be assigned to a variable or passed to a function, only called. Referencing one without parentheses is therefore an error...

```
let countlet count: typeof $state = $statenamespace $state
function $state<T>(initial: T): T (+1 overload)

Declares reactive state.




Example:



let count = $state(0);

{@link https://svelte.dev/docs/svelte/$state Documentation}


initial 

The initial value


;
```

...whether it’s a rune like `$state` or one reached through a property, like `$derived.by`. Add the parentheses, along with any arguments the rune expects:

```
let countlet count: number = $statefunction $state<0>(initial: 0): 0 (+1 overload)
namespace $state

Declares reactive state.




Example:



let count = $state(0);

{@link https://svelte.dev/docs/svelte/$state Documentation}


initial 

The initial value


(0);
```

### rune\_removed[](#rune_removed)

```
The `%name%` rune has been removed
```

### rune\_renamed[](#rune_renamed)

```
`%name%` is now `%replacement%`
```

### runes\_mode\_invalid\_import[](#runes_mode_invalid_import)

```
%name% cannot be used in runes mode
```

### script\_duplicate[](#script_duplicate)

```
A component can have a single top-level `<script>` element and/or a single top-level `<script module>` element
```

### script\_invalid\_attribute\_value[](#script_invalid_attribute_value)

```
If the `%name%` attribute is supplied, it must be a boolean attribute
```

### script\_invalid\_context[](#script_invalid_context)

```
If the context attribute is supplied, its value must be "module"
```

### script\_reserved\_attribute[](#script_reserved_attribute)

```
The `%name%` attribute is reserved and cannot be used
```

### slot\_attribute\_duplicate[](#slot_attribute_duplicate)

```
Duplicate slot name '%name%' in <%component%>
```

### slot\_attribute\_invalid[](#slot_attribute_invalid)

```
slot attribute must be a static value
```

### slot\_attribute\_invalid\_placement[](#slot_attribute_invalid_placement)

```
Element with a slot='...' attribute must be a child of a component or a descendant of a custom element
```

### slot\_default\_duplicate[](#slot_default_duplicate)

```
Found default slot content alongside an explicit slot="default"
```

### slot\_element\_invalid\_attribute[](#slot_element_invalid_attribute)

```
`<slot>` can only receive attributes and (optionally) let directives
```

### slot\_element\_invalid\_name[](#slot_element_invalid_name)

```
slot attribute must be a static value
```

### slot\_element\_invalid\_name\_default[](#slot_element_invalid_name_default)

```
`default` is a reserved word — it cannot be used as a slot name
```

### slot\_snippet\_conflict[](#slot_snippet_conflict)

```
Cannot use `<slot>` syntax and `{@render ...}` tags in the same component. Migrate towards `{@render ...}` tags completely
```

### snippet\_conflict[](#snippet_conflict)

```
Cannot use explicit children snippet at the same time as implicit children content. Remove either the non-whitespace content or the children snippet block
```

### snippet\_invalid\_export[](#snippet_invalid_export)

```
An exported snippet can only reference things declared in a `<script module>`, or other exportable snippets
```

It’s possible to export a snippet from a `<script module>` block, but only if it doesn’t reference anything defined inside a non-module-level `<script>`. For example you can’t do this...

```
<script module>
	export { greeting };
</script>

<script>
	let message = 'hello';
</script>

{#snippet greeting(name)}
	<p>{message} {name}!</p>
{/snippet}
```

...because `greeting` references `message`, which is defined in the second `<script>`.

### snippet\_invalid\_rest\_parameter[](#snippet_invalid_rest_parameter)

```
Snippets do not support rest parameters; use an array instead
```

### snippet\_parameter\_assignment[](#snippet_parameter_assignment)

```
Cannot reassign or bind to snippet parameter
```

### snippet\_shadowing\_prop[](#snippet_shadowing_prop)

```
This snippet is shadowing the prop `%prop%` with the same name
```

### state\_field\_duplicate[](#state_field_duplicate)

```
`%name%` has already been declared on this class
```

An assignment to a class field that uses a `$state` or `$derived` rune is considered a *state field declaration*. The declaration can happen in the class body...

```
class Counterclass Counter {
	count(property) Counter.count: number = $statefunction $state<0>(initial: 0): 0 (+1 overload)
namespace $state

Declares reactive state.




Example:



let count = $state(0);

{@link https://svelte.dev/docs/svelte/$state Documentation}


initial 

The initial value


(0);
}
```

...or inside the constructor...

```
class Counterclass Counter {
	constructor() {
		this.count(property) Counter.count: any = $statefunction $state<0>(initial: 0): 0 (+1 overload)
namespace $state

Declares reactive state.




Example:



let count = $state(0);

{@link https://svelte.dev/docs/svelte/$state Documentation}


initial 

The initial value


(0);
	}
}
```

...but it can only happen once.

### state\_field\_invalid\_assignment[](#state_field_invalid_assignment)

```
Cannot assign to a state field before its declaration
```

### state\_invalid\_export[](#state_invalid_export)

```
Cannot export state from a module if it is reassigned. Either export a function returning the state value or only mutate the state value's properties
```

### state\_invalid\_placement[](#state_invalid_placement)

```
`%rune%(...)` can only be used as a variable declaration initializer, a class field declaration, or the first assignment to a class field at the top level of the constructor.
```

### store\_invalid\_scoped\_subscription[](#store_invalid_scoped_subscription)

```
Cannot subscribe to stores that are not declared at the top level of the component
```

### store\_invalid\_subscription[](#store_invalid_subscription)

```
Cannot reference store value inside `<script module>`
```

### store\_invalid\_subscription\_module[](#store_invalid_subscription_module)

```
Cannot reference store value outside a `.svelte` file
```

Using a `$` prefix to refer to the value of a store is only possible inside `.svelte` files, where Svelte can automatically create subscriptions when a component is mounted and unsubscribe when the component is unmounted. Consider migrating to runes instead.

### style\_directive\_invalid\_modifier[](#style_directive_invalid_modifier)

```
`style:` directive can only use the `important` modifier
```

### style\_duplicate[](#style_duplicate)

```
A component can have a single top-level `<style>` element
```

### svelte\_body\_illegal\_attribute[](#svelte_body_illegal_attribute)

```
`<svelte:body>` does not support non-event attributes or spread attributes
```

### svelte\_boundary\_invalid\_attribute[](#svelte_boundary_invalid_attribute)

```
Valid attributes on `<svelte:boundary>` are `onerror` and `failed`
```

### svelte\_boundary\_invalid\_attribute\_value[](#svelte_boundary_invalid_attribute_value)

```
Attribute value must be a non-string expression
```

### svelte\_component\_invalid\_this[](#svelte_component_invalid_this)

```
Invalid component definition — must be an `{expression}`
```

### svelte\_component\_missing\_this[](#svelte_component_missing_this)

```
`<svelte:component>` must have a 'this' attribute
```

### svelte\_element\_missing\_this[](#svelte_element_missing_this)

```
`<svelte:element>` must have a 'this' attribute with a value
```

### svelte\_fragment\_invalid\_attribute[](#svelte_fragment_invalid_attribute)

```
`<svelte:fragment>` can only have a slot attribute and (optionally) a let: directive
```

### svelte\_fragment\_invalid\_placement[](#svelte_fragment_invalid_placement)

```
`<svelte:fragment>` must be the direct child of a component
```

### svelte\_head\_illegal\_attribute[](#svelte_head_illegal_attribute)

```
`<svelte:head>` cannot have attributes nor directives
```

### svelte\_meta\_duplicate[](#svelte_meta_duplicate)

```
A component can only have one `<%name%>` element
```

### svelte\_meta\_invalid\_content[](#svelte_meta_invalid_content)

```
<%name%> cannot have children
```

### svelte\_meta\_invalid\_placement[](#svelte_meta_invalid_placement)

```
`<%name%>` tags cannot be inside elements or blocks
```

### svelte\_meta\_invalid\_tag[](#svelte_meta_invalid_tag)

```
Valid `<svelte:...>` tag names are %list%
```

### svelte\_options\_deprecated\_tag[](#svelte_options_deprecated_tag)

```
"tag" option is deprecated — use "customElement" instead
```

### svelte\_options\_invalid\_attribute[](#svelte_options_invalid_attribute)

```
`<svelte:options>` can only receive static attributes
```

### svelte\_options\_invalid\_attribute\_value[](#svelte_options_invalid_attribute_value)

```
Value must be %list%, if specified
```

### svelte\_options\_invalid\_customelement[](#svelte_options_invalid_customelement)

```
"customElement" must be a string literal defining a valid custom element name or an object of the form { tag?: string; shadow?: "open" | "none" | `ShadowRootInit`; props?: { [key: string]: { attribute?: string; reflect?: boolean; type: .. } } }
```

### svelte\_options\_invalid\_customelement\_props[](#svelte_options_invalid_customelement_props)

```
"props" must be a statically analyzable object literal of the form "{ [key: string]: { attribute?: string; reflect?: boolean; type?: "String" | "Boolean" | "Number" | "Array" | "Object" }"
```

### svelte\_options\_invalid\_customelement\_shadow[](#svelte_options_invalid_customelement_shadow)

```
"shadow" must be either "open", "none" or `ShadowRootInit` object.
```

See <https://developer.mozilla.org/en-US/docs/Web/API/Element/attachShadow#options> for more information on valid shadow root constructor options

### svelte\_options\_invalid\_tagname[](#svelte_options_invalid_tagname)

```
Tag name must be lowercase and hyphenated
```

See <https://html.spec.whatwg.org/multipage/custom-elements.html#valid-custom-element-name> for more information on valid tag names

### svelte\_options\_reserved\_tagname[](#svelte_options_reserved_tagname)

```
Tag name is reserved
```

See <https://html.spec.whatwg.org/multipage/custom-elements.html#valid-custom-element-name> for more information on valid tag names

### svelte\_options\_unknown\_attribute[](#svelte_options_unknown_attribute)

```
`<svelte:options>` unknown attribute '%name%'
```

### svelte\_self\_invalid\_placement[](#svelte_self_invalid_placement)

```
`<svelte:self>` components can only exist inside `{#if}` blocks, `{#each}` blocks, `{#snippet}` blocks or slots passed to components
```

### tag\_invalid\_name[](#tag_invalid_name)

```
Expected a valid element or component name. Components must have a valid variable name or dot notation expression
```

### tag\_invalid\_placement[](#tag_invalid_placement)

```
{@%name% ...} tag cannot be %location%
```

### textarea\_invalid\_content[](#textarea_invalid_content)

```
A `<textarea>` can have either a value attribute or (equivalently) child content, but not both
```

### title\_illegal\_attribute[](#title_illegal_attribute)

```
`<title>` cannot have attributes nor directives
```

### title\_invalid\_content[](#title_invalid_content)

```
`<title>` can only contain text and {tags}
```

### transition\_conflict[](#transition_conflict)

```
Cannot use `%type%:` alongside existing `%existing%:` directive
```

### transition\_duplicate[](#transition_duplicate)

```
Cannot use multiple `%type%:` directives on a single element
```

### typescript\_invalid\_feature[](#typescript_invalid_feature)

```
TypeScript language features like %feature% are not natively supported, and their use is generally discouraged. Outside of `<script>` tags, these features are not supported. For use within `<script>` tags, you will need to use a preprocessor to convert it to JavaScript before it gets passed to the Svelte compiler. If you are using `vitePreprocess`, make sure to specifically enable preprocessing script tags (`vitePreprocess({ script: true })`)
```

### unexpected\_eof[](#unexpected_eof)

```
Unexpected end of input
```

### unexpected\_reserved\_word[](#unexpected_reserved_word)

```
'%word%' is a reserved word in JavaScript and cannot be used here
```

### unterminated\_string\_constant[](#unterminated_string_constant)

```
Unterminated string constant
```

### void\_element\_invalid\_content[](#void_element_invalid_content)

```
Void elements cannot have children or closing tags
```

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/98-reference/30-compiler-errors.md) [llms.txt](/docs/svelte/compiler-errors/llms.txt)

previous next

[svelte/transition](/docs/svelte/svelte-transition) [Compiler warnings](/docs/svelte/compiler-warnings)

----
url: https://svelte.dev/docs/svelte/await-expressions/llms.txt
----

````
As of Svelte 5.36, you can use the `await` keyword inside your components in three places where it was previously unavailable:

- at the top level of your component's `<script>`
- inside `$derived(...)` declarations
- inside your markup

This feature is currently experimental, and you must opt in by adding the `experimental.async` option wherever you [configure](/docs/kit/configuration) Svelte, usually `svelte.config.js`:

```js
/// file: svelte.config.js
export default {
	compilerOptions: {
		experimental: {
			async: true
		}
	}
};
```

The experimental flag will be removed in Svelte 6.

## Synchronized updates

When an `await` expression depends on a particular piece of state, changes to that state will not be reflected in the UI until the asynchronous work has completed, so that the UI is not left in an inconsistent state. In other words, in an example like this...

<!-- codeblock:start {"title":"Synchronized updates"} -->
```svelte
<!--- file: App.svelte --->
<script>
	let a = $state(1);
	let b = $state(2);

	async function add(a, b) {
		await new Promise((f) => setTimeout(f, 500)); // artificial delay
		return a + b;
	}
</script>

<input type="number" bind:value={a}>
<input type="number" bind:value={b}>

<p>{a} + {b} = {await add(a, b)}</p>
```
<!-- codeblock:end -->

...if you increment `a`, the contents of the `<p>` will _not_ immediately update to read this —

```html
<p>2 + 2 = 3</p>
```

— instead, the text will update to `2 + 2 = 4` when `add(a, b)` resolves.

Updates can overlap — a fast update will be reflected in the UI while an earlier slow update is still ongoing.

## Concurrency

Svelte will do as much asynchronous work as it can in parallel. For example if you have two `await` expressions in your markup...

```svelte
<p>{await one(x)}</p>
<p>{await two(y)}</p>
```

...both functions will run at the same time, as they are independent expressions, even though they are _visually_ sequential.

This does not apply to sequential `await` expressions inside your `<script>` or inside async functions — these run like any other asynchronous JavaScript. An exception is that independent `$derived` expressions will update independently, even though they will run sequentially when they are first created:

```js
/** @param {number} x */
async function one(x) { return x; }
/** @param {number} y */
async function two(y) { return y; }
let x = $state(1);
let y = $state(2);
// ---cut---
// `b` will not be created until `a` has resolved,
// but once created they will update independently
// even if `x` and `y` update simultaneously
let a = $derived(await one(x));
let b = $derived(await two(y));
```

> [!NOTE] If you write code like this, expect Svelte to give you an [`await_waterfall`](runtime-warnings#Client-warnings-await_waterfall) warning

## Indicating loading states

To render placeholder UI, you can wrap content in a `<svelte:boundary>` with a [`pending`](svelte-boundary#Properties-pending) snippet. This will be shown when the boundary is first created, but not for subsequent updates, which are globally coordinated.

After the contents of a boundary have resolved for the first time and have replaced the `pending` snippet, you can detect subsequent async work with [`$effect.pending()`]($effect#$effect.pending). This is what you would use to display a "we're asynchronously validating your input" spinner next to a form field, for example.

You can also use [`settled()`](svelte#settled) to get a promise that resolves when the current update is complete:

```js
let color = 'red';
let answer = -1;
let updating = false;
// ---cut---
import { tick, settled } from 'svelte';

async function onclick() {
	updating = true;

	// without this, the change to `updating` will be
	// grouped with the other changes, meaning it
	// won't be reflected in the UI
	await tick();

	color = 'octarine';
	answer = 42;

	await settled();

	// any updates affected by `color` or `answer`
	// have now been applied
	updating = false;
}
```

## Error handling

Errors in `await` expressions will bubble to the nearest [error boundary](svelte-boundary).

## Server-side rendering

Svelte supports asynchronous server-side rendering (SSR) with the `render(...)` API. To use it, simply await the return value:

```js
/// file: server.js
import { render } from 'svelte/server';
import App from './App.svelte';

const { head, body } = +++await+++ render(App);
```

> [!NOTE] If you're using a framework like SvelteKit, this is done on your behalf.

If a `<svelte:boundary>` with a `pending` snippet is encountered during SSR, that snippet will be rendered while the rest of the content is ignored. All `await` expressions encountered outside boundaries with `pending` snippets will resolve and render their contents prior to `await render(...)` returning.

> [!NOTE] In the future, we plan to add a streaming implementation that renders the content in the background.

## Forking

The [`fork(...)`](svelte#fork) API, added in 5.42, makes it possible to run `await` expressions that you _expect_ to happen in the near future. This is mainly intended for frameworks like SvelteKit to implement preloading when (for example) users signal an intent to navigate.

```svelte
<script>
	import { fork } from 'svelte';
	import Menu from './Menu.svelte';

	let open = $state(false);

	/** @type {import('svelte').Fork | null} */
	let pending = null;

	function preload() {
		pending ??= fork(() => {
			open = true;
		});
	}

	function discard() {
		pending?.discard();
		pending = null;
	}
</script>

<button
	onfocusin={preload}
	onfocusout={discard}
	onpointerenter={preload}
	onpointerleave={discard}
	onclick={() => {
		pending?.commit();
		pending = null;

		// in case `pending` didn't exist
		// (if it did, this is a no-op)
		open = true;
	}}
>open menu</button>

{#if open}
	<!-- any async work inside this component will start
	     as soon as the fork is created -->
	<Menu onclose={() => open = false} />
{/if}
```

## Caveats

As an experimental feature, the details of how `await` is handled (and related APIs like `$effect.pending()`) are subject to breaking changes outside of a semver major release, though we intend to keep such changes to a bare minimum.

## Breaking changes

Effects run in a slightly different order when the `experimental.async` option is `true`. Specifically, _block_ effects like `{#if ...}` and `{#each ...}` now run before an `$effect.pre` or `beforeUpdate` in the same component, which means that in very rare situations.
````

----
url: https://svelte.dev/docs/svelte/compiler-errors/llms.txt
----

````
<!-- This file is generated by scripts/process-messages/index.js. Do not edit! -->

### animation_duplicate

```
An element can only have one 'animate' directive
```

### animation_invalid_placement

```
An element that uses the `animate:` directive must be the only child of a keyed `{#each ...}` block
```

### animation_missing_key

```
An element that uses the `animate:` directive must be the only child of a keyed `{#each ...}` block. Did you forget to add a key to your each block?
```

### attribute_contenteditable_dynamic

```
'contenteditable' attribute cannot be dynamic if element uses two-way binding
```

### attribute_contenteditable_missing

```
'contenteditable' attribute is required for textContent, innerHTML and innerText two-way bindings
```

### attribute_duplicate

```
Attributes need to be unique
```

### attribute_empty_shorthand

```
Attribute shorthand cannot be empty
```

### attribute_invalid_event_handler

```
Event attribute must be a JavaScript expression, not a string
```

### attribute_invalid_multiple

```
'multiple' attribute must be static if select uses two-way binding
```

### attribute_invalid_name

```
'%name%' is not a valid attribute name
```

### attribute_invalid_sequence_expression

```
Comma-separated expressions are not allowed as attribute/directive values in runes mode, unless wrapped in parentheses
```

An attribute value cannot be a comma-separated sequence of expressions — in other words this is disallowed:

```svelte
<div class={size, color}>...</div>
```

Instead, make sure that the attribute value contains a single expression. In the example above it's likely that this was intended (see the [class documentation](class) for more details):

```svelte
<div class={[size, color]}>...</div>
```

If you _do_ need to use the comma operator for some reason, wrap the sequence in parentheses:

```svelte
<div class={(size, color)}>...</div>
```

Note that this will evaluate to `color`, ignoring `size`.

### attribute_invalid_type

```
'type' attribute must be a static text value if input uses two-way binding
```

### attribute_unquoted_sequence

```
Attribute values containing `{...}` must be enclosed in quote marks, unless the value only contains the expression
```

### bind_group_invalid_expression

```
`bind:group` can only bind to an Identifier or MemberExpression
```

### bind_group_invalid_snippet_parameter

```
Cannot `bind:group` to a snippet parameter
```

### bind_invalid_expression

```
Can only bind to an Identifier or MemberExpression or a `{get, set}` pair
```

### bind_invalid_name

```
`bind:%name%` is not a valid binding
```

```
`bind:%name%` is not a valid binding. %explanation%
```

### bind_invalid_parens

```
`bind:%name%={get, set}` must not have surrounding parentheses
```

### bind_invalid_target

```
`bind:%name%` can only be used with %elements%
```

### bind_invalid_value

```
Can only bind to state or props
```

### bindable_invalid_location

```
`$bindable()` can only be used inside a `$props()` declaration
```

### block_duplicate_clause

```
%name% cannot appear more than once within a block
```

### block_invalid_continuation_placement

```
{:...} block is invalid at this position (did you forget to close the preceding element or block?)
```

### block_invalid_elseif

```
'elseif' should be 'else if'
```

### block_invalid_placement

```
{#%name% ...} block cannot be %location%
```

### block_unclosed

```
Block was left open
```

### block_unexpected_character

```
Expected a `%character%` character immediately following the opening bracket
```

### block_unexpected_close

```
Unexpected block closing tag
```

### component_invalid_directive

```
This type of directive is not valid on components
```

### const_tag_cycle

```
Cyclical dependency detected: %cycle%
```

### const_tag_invalid_expression

```
{@const ...} must consist of a single variable declaration
```

### const_tag_invalid_placement

```
`{@const}` must be the immediate child of `{#snippet}`, `{#if}`, `{:else if}`, `{:else}`, `{#each}`, `{:then}`, `{:catch}`, `<svelte:fragment>`, `<svelte:boundary>` or `<Component>`
```

### const_tag_invalid_reference

```
The `{@const %name% = ...}` declaration is not available in this snippet
```

The following is an error:

```svelte
<svelte:boundary>
    {@const foo = 'bar'}

    {#snippet failed()}
        {foo}
    {/snippet}
</svelte:boundary>
```

Here, `foo` is not available inside `failed`. The top level code inside `<svelte:boundary>` becomes part of the implicit `children` snippet, in other words the above code is equivalent to this:

```svelte
<svelte:boundary>
    {#snippet children()}
        {@const foo = 'bar'}
    {/snippet}

    {#snippet failed()}
        {foo}
    {/snippet}
</svelte:boundary>
```

The same applies to components:

```svelte
<Component>
    {@const foo = 'bar'}

    {#snippet someProp()}
        <!-- error -->
        {foo}
    {/snippet}
</Component>
```

### constant_assignment

```
Cannot assign to %thing%
```

### constant_binding

```
Cannot bind to %thing%
```

### css_empty_declaration

```
Declaration cannot be empty
```

### css_expected_identifier

```
Expected a valid CSS identifier
```

### css_global_block_invalid_combinator

```
A `:global` selector cannot follow a `%name%` combinator
```

### css_global_block_invalid_declaration

```
A top-level `:global {...}` block can only contain rules, not declarations
```

### css_global_block_invalid_list

```
A `:global` selector cannot be part of a selector list with entries that don't contain `:global`
```

The following CSS is invalid:

```css
:global, x {
    y {
        color: red;
    }
}
```

This is mixing a `:global` block, which means "everything in here is unscoped", with a scoped selector (`x` in this case). As a result it's not possible to transform the inner selector (`y` in this case) into something that satisfies both requirements. You therefore have to split this up into two selectors:

```css
:global {
    y {
        color: red;
    }
}

x y {
    color: red;
}
```

### css_global_block_invalid_modifier

```
A `:global` selector cannot modify an existing selector
```

### css_global_block_invalid_modifier_start

```
A `:global` selector can only be modified if it is a descendant of other selectors
```

### css_global_block_invalid_placement

```
A `:global` selector cannot be inside a pseudoclass
```

### css_global_invalid_placement

```
`:global(...)` can be at the start or end of a selector sequence, but not in the middle
```

### css_global_invalid_selector

```
`:global(...)` must contain exactly one selector
```

### css_global_invalid_selector_list

```
`:global(...)` must not contain type or universal selectors when used in a compound selector
```

### css_nesting_selector_invalid_placement

```
Nesting selectors can only be used inside a rule or as the first selector inside a lone `:global(...)`
```

### css_selector_invalid

```
Invalid selector
```

### css_type_selector_invalid_placement

```
`:global(...)` must not be followed by a type selector
```

### debug_tag_invalid_arguments

```
{@debug ...} arguments must be identifiers, not arbitrary expressions
```

### declaration_duplicate

```
`%name%` has already been declared
```

### declaration_duplicate_module_import

```
Cannot declare a variable with the same name as an import from `<script module>`
```

### declaration_tag_invalid_type

```
Declaration tags must be `let` or `const` declarations
```

### declaration_tag_no_legacy_mode

```
Declaration tags cannot be used in legacy mode
```

### derived_invalid_export

```
Cannot export derived state from a module. To expose the current derived value, export a function returning its value
```

### directive_invalid_value

```
Directive value must be a JavaScript expression enclosed in curly braces
```

### directive_missing_name

```
`%type%` name cannot be empty
```

### dollar_binding_invalid

```
The $ name is reserved, and cannot be used for variables and imports
```

### dollar_prefix_invalid

```
The $ prefix is reserved, and cannot be used for variables and imports
```

### duplicate_class_field

```
`%name%` has already been declared
```

### each_item_invalid_assignment

```
Cannot reassign or bind to each block argument in runes mode. Use the array and index variables instead (e.g. `array[i] = value` instead of `entry = value`, or `bind:value={array[i]}` instead of `bind:value={entry}`)
```

In legacy mode, it was possible to reassign or bind to the each block argument itself:

```svelte
<script>
	let array = [1, 2, 3];
</script>

{#each array as entry}
	<!-- reassignment -->
	<button on:click={() => entry = 4}>change</button>

	<!-- binding -->
	<input bind:value={entry}>
{/each}
```

This turned out to be buggy and unpredictable, particularly when working with derived values (such as `array.map(...)`), and as such is forbidden in runes mode. You can achieve the same outcome by using the index instead:

```svelte
<script>
	let array = $state([1, 2, 3]);
</script>

{#each array as entry, i}
	<!-- reassignment -->
	<button onclick={() => array[i] = 4}>change</button>

	<!-- binding -->
	<input bind:value={array[i]}>
{/each}
```

### each_key_without_as

```
An `{#each ...}` block without an `as` clause cannot have a key
```

### effect_invalid_placement

```
`$effect()` can only be used as an expression statement
```

### element_invalid_closing_tag

```
`</%name%>` attempted to close an element that was not open
```

### element_invalid_closing_tag_autoclosed

```
`</%name%>` attempted to close element that was already automatically closed by `<%reason%>` (cannot nest `<%reason%>` inside `<%name%>`)
```

### element_unclosed

```
`<%name%>` was left open
```

### event_handler_invalid_component_modifier

```
Event modifiers other than 'once' can only be used on DOM elements
```

### event_handler_invalid_modifier

```
Valid event modifiers are %list%
```

### event_handler_invalid_modifier_combination

```
The '%modifier1%' and '%modifier2%' modifiers cannot be used together
```

### expected_attribute_value

```
Expected attribute value
```

### expected_block_type

```
Expected 'if', 'each', 'await', 'key' or 'snippet'
```

### expected_identifier

```
Expected an identifier
```

### expected_pattern

```
Expected identifier or destructure pattern
```

### expected_tag

```
Expected 'html', 'render', 'attach', 'const', or 'debug'
```

### expected_token

```
Expected token %token%
```

### expected_whitespace

```
Expected whitespace
```

### experimental_async

```
Cannot use `await` in deriveds and template expressions, or at the top level of a component, unless the `experimental.async` compiler option is `true`
```

### export_undefined

```
`%name%` is not defined
```

### global_reference_invalid

```
`%name%` is an illegal variable name. To reference a global variable called `%name%`, use `globalThis.%name%`
```

### host_invalid_placement

```
`$host()` can only be used inside custom element component instances
```

### illegal_await_expression

```
`use:`, `transition:` and `animate:` directives, attachments and bindings do not support await expressions
```

### illegal_element_attribute

```
`<%name%>` does not support non-event attributes or spread attributes
```

### import_svelte_internal_forbidden

```
Imports of `svelte/internal/*` are forbidden. It contains private runtime code which is subject to change without notice. If you're importing from `svelte/internal/*` to work around a limitation of Svelte, please open an issue at https://github.com/sveltejs/svelte and explain your use case
```

### inspect_trace_generator

```
`$inspect.trace(...)` cannot be used inside a generator function
```

### inspect_trace_invalid_placement

```
`$inspect.trace(...)` must be the first statement of a function body
```

### invalid_arguments_usage

```
The arguments keyword cannot be used within the template or at the top level of a component
```

### js_parse_error

```
%message%
```

### legacy_await_invalid

```
Cannot use `await` in deriveds and template expressions, or at the top level of a component, unless in runes mode
```

### legacy_export_invalid

```
Cannot use `export let` in runes mode — use `$props()` instead
```

### legacy_props_invalid

```
Cannot use `$$props` in runes mode
```

### legacy_reactive_statement_invalid

```
`$:` is not allowed in runes mode, use `$derived` or `$effect` instead
```

### legacy_rest_props_invalid

```
Cannot use `$$restProps` in runes mode
```

### let_directive_invalid_placement

```
`let:` directive at invalid position
```

### let_directive_snippet_conflict

```
Cannot use `let:` directives on a component that has a `children` snippet. Use snippet parameters instead (e.g. `{#snippet children({ %name% })}`)
```

### mixed_event_handler_syntaxes

```
Mixing old (on:%name%) and new syntaxes for event handling is not allowed. Use only the on%name% syntax
```

### module_illegal_default_export

```
A component cannot have a default export
```

### node_invalid_placement

```
%message%. The browser will 'repair' the HTML (by moving, removing, or inserting elements) which breaks Svelte's assumptions about the structure of your components.
```

HTML restricts where certain elements can appear. In case of a violation the browser will 'repair' the HTML in a way that breaks Svelte's assumptions about the structure of your components. Some examples:

- `<p>hello <div>world</div></p>` will result in `<p>hello </p><div>world</div><p></p>` (the `<div>` autoclosed the `<p>` because `<p>` cannot contain block-level elements)
- `<option><div>option a</div></option>` will result in `<option>option a</option>` (the `<div>` is removed)
- `<table><tr><td>cell</td></tr></table>` will result in `<table><tbody><tr><td>cell</td></tr></tbody></table>` (a `<tbody>` is auto-inserted)

### options_invalid_value

```
Invalid compiler option: %details%
```

### options_removed

```
Invalid compiler option: %details%
```

### options_unrecognised

```
Unrecognised compiler option %keypath%
```

### props_duplicate

```
Cannot use `%rune%()` more than once
```

### props_id_invalid_placement

```
`$props.id()` can only be used at the top level of components as a variable declaration initializer
```

### props_illegal_name

```
Declaring or accessing a prop starting with `$$` is illegal (they are reserved for Svelte internals)
```

### props_invalid_identifier

```
`$props()` can only be used with an object destructuring pattern
```

### props_invalid_pattern

```
`$props()` assignment must not contain nested properties or computed keys
```

### props_invalid_placement

```
`$props()` can only be used at the top level of components as a variable declaration initializer
```

### reactive_declaration_cycle

```
Cyclical dependency detected: %cycle%
```

### render_tag_invalid_call_expression

```
Calling a snippet function using apply, bind or call is not allowed
```

### render_tag_invalid_expression

```
`{@render ...}` tags can only contain call expressions
```

### render_tag_invalid_spread_argument

```
cannot use spread arguments in `{@render ...}` tags
```

### rune_invalid_arguments

```
`%rune%` cannot be called with arguments
```

### rune_invalid_arguments_length

```
`%rune%` must be called with %args%
```

### rune_invalid_computed_property

```
Cannot access a computed property of a rune
```

### rune_invalid_name

```
`%name%` is not a valid rune
```

### rune_invalid_spread

```
`%rune%` cannot be called with a spread argument
```

### rune_invalid_usage

```
Cannot use `%rune%` rune in non-runes mode
```

### rune_missing_parentheses

```
Cannot use rune without parentheses
```

Runes are keywords rather than values — they can't be assigned to a variable or passed to a function, only called. Referencing one without parentheses is therefore an error...

```js
let count = $state;
```

...whether it's a rune like `$state` or one reached through a property, like `$derived.by`. Add the parentheses, along with any arguments the rune expects:

```js
let count = $state(0);
```

### rune_removed

```
The `%name%` rune has been removed
```

### rune_renamed

```
`%name%` is now `%replacement%`
```

### runes_mode_invalid_import

```
%name% cannot be used in runes mode
```

### script_duplicate

```
A component can have a single top-level `<script>` element and/or a single top-level `<script module>` element
```

### script_invalid_attribute_value

```
If the `%name%` attribute is supplied, it must be a boolean attribute
```

### script_invalid_context

```
If the context attribute is supplied, its value must be "module"
```

### script_reserved_attribute

```
The `%name%` attribute is reserved and cannot be used
```

### slot_attribute_duplicate

```
Duplicate slot name '%name%' in <%component%>
```

### slot_attribute_invalid

```
slot attribute must be a static value
```

### slot_attribute_invalid_placement

```
Element with a slot='...' attribute must be a child of a component or a descendant of a custom element
```

### slot_default_duplicate

```
Found default slot content alongside an explicit slot="default"
```

### slot_element_invalid_attribute

```
`<slot>` can only receive attributes and (optionally) let directives
```

### slot_element_invalid_name

```
slot attribute must be a static value
```

### slot_element_invalid_name_default

```
`default` is a reserved word — it cannot be used as a slot name
```

### slot_snippet_conflict

```
Cannot use `<slot>` syntax and `{@render ...}` tags in the same component. Migrate towards `{@render ...}` tags completely
```

### snippet_conflict

```
Cannot use explicit children snippet at the same time as implicit children content. Remove either the non-whitespace content or the children snippet block
```

### snippet_invalid_export

```
An exported snippet can only reference things declared in a `<script module>`, or other exportable snippets
```

It's possible to export a snippet from a `<script module>` block, but only if it doesn't reference anything defined inside a non-module-level `<script>`. For example you can't do this...

```svelte
<script module>
	export { greeting };
</script>

<script>
	let message = 'hello';
</script>

{#snippet greeting(name)}
	<p>{message} {name}!</p>
{/snippet}
```

...because `greeting` references `message`, which is defined in the second `<script>`.

### snippet_invalid_rest_parameter

```
Snippets do not support rest parameters; use an array instead
```

### snippet_parameter_assignment

```
Cannot reassign or bind to snippet parameter
```

### snippet_shadowing_prop

```
This snippet is shadowing the prop `%prop%` with the same name
```

### state_field_duplicate

```
`%name%` has already been declared on this class
```

An assignment to a class field that uses a `$state` or `$derived` rune is considered a _state field declaration_. The declaration can happen in the class body...

```js
class Counter {
	count = $state(0);
}
```

...or inside the constructor...

```js
class Counter {
	constructor() {
		this.count = $state(0);
	}
}
```

...but it can only happen once.

### state_field_invalid_assignment

```
Cannot assign to a state field before its declaration
```

### state_invalid_export

```
Cannot export state from a module if it is reassigned. Either export a function returning the state value or only mutate the state value's properties
```

### state_invalid_placement

```
`%rune%(...)` can only be used as a variable declaration initializer, a class field declaration, or the first assignment to a class field at the top level of the constructor.
```

### store_invalid_scoped_subscription

```
Cannot subscribe to stores that are not declared at the top level of the component
```

### store_invalid_subscription

```
Cannot reference store value inside `<script module>`
```

### store_invalid_subscription_module

```
Cannot reference store value outside a `.svelte` file
```

Using a `$` prefix to refer to the value of a store is only possible inside `.svelte` files, where Svelte can automatically create subscriptions when a component is mounted and unsubscribe when the component is unmounted. Consider migrating to runes instead.

### style_directive_invalid_modifier

```
`style:` directive can only use the `important` modifier
```

### style_duplicate

```
A component can have a single top-level `<style>` element
```

### svelte_body_illegal_attribute

```
`<svelte:body>` does not support non-event attributes or spread attributes
```

### svelte_boundary_invalid_attribute

```
Valid attributes on `<svelte:boundary>` are `onerror` and `failed`
```

### svelte_boundary_invalid_attribute_value

```
Attribute value must be a non-string expression
```

### svelte_component_invalid_this

```
Invalid component definition — must be an `{expression}`
```

### svelte_component_missing_this

```
`<svelte:component>` must have a 'this' attribute
```

### svelte_element_missing_this

```
`<svelte:element>` must have a 'this' attribute with a value
```

### svelte_fragment_invalid_attribute

```
`<svelte:fragment>` can only have a slot attribute and (optionally) a let: directive
```

### svelte_fragment_invalid_placement

```
`<svelte:fragment>` must be the direct child of a component
```

### svelte_head_illegal_attribute

```
`<svelte:head>` cannot have attributes nor directives
```

### svelte_meta_duplicate

```
A component can only have one `<%name%>` element
```

### svelte_meta_invalid_content

```
<%name%> cannot have children
```

### svelte_meta_invalid_placement

```
`<%name%>` tags cannot be inside elements or blocks
```

### svelte_meta_invalid_tag

```
Valid `<svelte:...>` tag names are %list%
```

### svelte_options_deprecated_tag

```
"tag" option is deprecated — use "customElement" instead
```

### svelte_options_invalid_attribute

```
`<svelte:options>` can only receive static attributes
```

### svelte_options_invalid_attribute_value

```
Value must be %list%, if specified
```

### svelte_options_invalid_customelement

```
"customElement" must be a string literal defining a valid custom element name or an object of the form { tag?: string; shadow?: "open" | "none" | `ShadowRootInit`; props?: { [key: string]: { attribute?: string; reflect?: boolean; type: .. } } }
```

### svelte_options_invalid_customelement_props

```
"props" must be a statically analyzable object literal of the form "{ [key: string]: { attribute?: string; reflect?: boolean; type?: "String" | "Boolean" | "Number" | "Array" | "Object" }"
```

### svelte_options_invalid_customelement_shadow

```
"shadow" must be either "open", "none" or `ShadowRootInit` object.
```

See https://developer.mozilla.org/en-US/docs/Web/API/Element/attachShadow#options for more information on valid shadow root constructor options

### svelte_options_invalid_tagname

```
Tag name must be lowercase and hyphenated
```

See https://html.spec.whatwg.org/multipage/custom-elements.html#valid-custom-element-name for more information on valid tag names

### svelte_options_reserved_tagname

```
Tag name is reserved
```

See https://html.spec.whatwg.org/multipage/custom-elements.html#valid-custom-element-name for more information on valid tag names

### svelte_options_unknown_attribute

```
`<svelte:options>` unknown attribute '%name%'
```

### svelte_self_invalid_placement

```
`<svelte:self>` components can only exist inside `{#if}` blocks, `{#each}` blocks, `{#snippet}` blocks or slots passed to components
```

### tag_invalid_name

```
Expected a valid element or component name. Components must have a valid variable name or dot notation expression
```

### tag_invalid_placement

```
{@%name% ...} tag cannot be %location%
```

### textarea_invalid_content

```
A `<textarea>` can have either a value attribute or (equivalently) child content, but not both
```

### title_illegal_attribute

```
`<title>` cannot have attributes nor directives
```

### title_invalid_content

```
`<title>` can only contain text and {tags}
```

### transition_conflict

```
Cannot use `%type%:` alongside existing `%existing%:` directive
```

### transition_duplicate

```
Cannot use multiple `%type%:` directives on a single element
```

### typescript_invalid_feature

```
TypeScript language features like %feature% are not natively supported, and their use is generally discouraged. Outside of `<script>` tags, these features are not supported. For use within `<script>` tags, you will need to use a preprocessor to convert it to JavaScript before it gets passed to the Svelte compiler. If you are using `vitePreprocess`, make sure to specifically enable preprocessing script tags (`vitePreprocess({ script: true })`)
```

### unexpected_eof

```
Unexpected end of input
```

### unexpected_reserved_word

```
'%word%' is a reserved word in JavaScript and cannot be used here
```

### unterminated_string_constant

```
Unterminated string constant
```

### void_element_invalid_content

```
Void elements cannot have children or closing tags
```
````

----
url: https://svelte.dev/docs/svelte/typescript
----

[Skip to main content](#main)

You can use TypeScript within Svelte components. IDE extensions like the [Svelte VS Code extension](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode) will help you catch errors right in your editor, and [`svelte-check`](https://www.npmjs.com/package/svelte-check) does the same on the command line, which you can integrate into your CI.

## \<script lang="ts">[](#script-lang-ts)

To use TypeScript inside your Svelte components, add `lang="ts"` to your `script` tags:

```
<script lang="ts">
	let name: string = 'world';

	function greet(name: string) {
		alert(`Hello, ${name}!`);
	}
</script>

<button onclick={(e: Event) => greet(e.target.innerText)}>
	{name as string}
</button>
```

Doing so allows you to use TypeScript’s *type-only* features. That is, all features that just disappear when transpiling to JavaScript, such as type annotations or interface declarations. Features that require the TypeScript compiler to output actual code are not supported. This includes:

* using enums
* using `private`, `protected` or `public` modifiers in constructor functions together with initializers
* using features that are not yet part of the ECMAScript standard (i.e. not level 4 in the TC39 process) and therefore not implemented yet within Acorn, the parser we use for parsing JavaScript

If you want to use one of these features, you need to setup up a `script` preprocessor.

## Preprocessor setup[](#Preprocessor-setup)

To use non-type-only TypeScript features within Svelte components, you need to add a preprocessor that will turn TypeScript into JavaScript.

### Using Vite[](#Preprocessor-setup-Using-Vite)

If you’re using SvelteKit, or Vite *without* SvelteKit, you can use `vitePreprocess` from `@sveltejs/vite-plugin-svelte` in your config file:

svelte.config

```
import { vitePreprocess(alias) function vitePreprocess(opts?: VitePreprocessOptions): PreprocessorGroup
import vitePreprocess } from '@sveltejs/vite-plugin-svelte';

const configconst config: {
    preprocess: PreprocessorGroup;
} = {
	// Note the additional `{ script: true }`
	preprocess(property) preprocess: PreprocessorGroup: vitePreprocess(alias) vitePreprocess(opts?: VitePreprocessOptions): PreprocessorGroup
import vitePreprocess({ script(property) VitePreprocessOptions.script?: boolean | undefined

preprocess script block with vite pipeline.
Since svelte5 this is not needed for typescript anymore




false


: true })
};

export default configconst config: {
    preprocess: PreprocessorGroup;
};
```

### Using other build tools[](#Preprocessor-setup-Using-other-build-tools)

If you’re using tools like Rollup (via [rollup-plugin-svelte](https://github.com/sveltejs/rollup-plugin-svelte)) or Webpack (via [svelte-loader](https://github.com/sveltejs/svelte-loader)) instead, install `typescript` and `svelte-preprocess` and add the preprocessor to the plugin config. See the respective plugin READMEs for more info.

> If you’re starting a new project, we recommend using SvelteKit or Vite instead

## tsconfig.json settings[](#tsconfig.json-settings)

When using TypeScript, make sure your `tsconfig.json` is setup correctly.

* Use a [`target`](https://www.typescriptlang.org/tsconfig/#target) of at least `ES2015` so classes are not compiled to functions
* Set [`verbatimModuleSyntax`](https://www.typescriptlang.org/tsconfig/#verbatimModuleSyntax) to `true` so that imports are left as-is
* Set [`isolatedModules`](https://www.typescriptlang.org/tsconfig/#isolatedModules) to `true` so that each file is looked at in isolation. TypeScript has a few features which require cross-file analysis and compilation, which the Svelte compiler and tooling like Vite don’t do.

## Typing $props[](#Typing-$props)

Type `$props` just like a regular object with certain properties.

```
<script lang="ts">
	import type { Snippet } from 'svelte';

	interface Props {
		requiredProperty: number;
		optionalProperty?: boolean;
		snippetWithStringArgument: Snippet<[string]>;
		eventHandler: (arg: string) => void;
		[key: string]: unknown;
	}

	let {
		requiredProperty,
		optionalProperty,
		snippetWithStringArgument,
		eventHandler,
		...everythingElse
	}: Props = $props();
</script>

<button onclick={() => eventHandler('clicked button')}>
	{@render snippetWithStringArgument('hello')}
</button>
```

## Generic $props[](#Generic-$props)

Components can declare a generic relationship between their properties. One example is a generic list component that receives a list of items and a callback property that receives an item from the list. To declare that the `items` property and the `select` callback operate on the same types, add the `generics` attribute to the `script` tag:

```
<script lang="ts" generics="Item extends { text: string }">
	interface Props {
		items: Item[];
		select(item: Item): void;
	}

	let { items, select }: Props = $props();
</script>

{#each items as item}
	<button onclick={() => select(item)}>
		{item.text}
	</button>
{/each}
```

The content of `generics` is what you would put between the `<...>` tags of a generic function. In other words, you can use multiple generics, `extends` and fallback types.

## Typing wrapper components[](#Typing-wrapper-components)

In case you’re writing a component that wraps a native element, you may want to expose all the attributes of the underlying element to the user. In that case, use (or extend from) one of the interfaces provided by `svelte/elements`. Here’s an example for a `Button` component:

```
<script lang="ts">
	import type { HTMLButtonAttributes } from 'svelte/elements';

	let { children, ...rest }: HTMLButtonAttributes = $props();
</script>

<button {...rest}>
	{@render children?.()}
</button>
```

Not all elements have a dedicated type definition. For those without one, use `SvelteHTMLElements`:

```
<script lang="ts">
	import type { SvelteHTMLElements } from 'svelte/elements';

	let { children, ...rest }: SvelteHTMLElements['div'] = $props();
</script>

<div {...rest}>
	{@render children?.()}
</div>
```

## Typing $state[](#Typing-$state)

You can type `$state` like any other variable.

```
let countlet count: number: number = $statefunction $state<0>(initial: 0): 0 (+1 overload)
namespace $state

Declares reactive state.




Example:



let count = $state(0);

{@link https://svelte.dev/docs/svelte/$state Documentation}


initial 

The initial value


(0);
```

If you don’t give `$state` an initial value, part of its types will be `undefined`.

```
// Error: Type 'number | undefined' is not assignable to type 'number'
let countlet count: number: number = $statefunction $state<number>(): number | undefined (+1 overload)
namespace $state

Declares reactive state.




Example:



let count = $state(0);

{@link https://svelte.dev/docs/svelte/$state Documentation}


initial 

The initial value


();
```

You can pass the type directly as a generic parameter to safely handle this. TypeScript will infer the variable as `number | undefined`.

```
let countlet count: number | undefined = $statefunction $state<number>(): number | undefined (+1 overload)
namespace $state

Declares reactive state.




Example:



let count = $state(0);

{@link https://svelte.dev/docs/svelte/$state Documentation}


initial 

The initial value


<number>();
```

If you know that the variable *will* be defined before you first use it, use an `as` casting. This is especially useful in the context of classes:

```
class Counterclass Counter {
	count(property) Counter.count: number = $statefunction $state<number>(): number | undefined (+1 overload)
namespace $state

Declares reactive state.




Example:



let count = $state(0);

{@link https://svelte.dev/docs/svelte/$state Documentation}


initial 

The initial value


() as number;
	constructor(initial(parameter) initial: number: number) {
		this.count(property) Counter.count: number = initial(parameter) initial: number;
	}
}
```

## The Component type[](#The-Component-type)

Svelte components are of type `Component`. You can use it and its related types to express a variety of constraints.

Using it together with dynamic components to restrict what kinds of component can be passed to it:

```
<script lang="ts">
	import type { Component } from 'svelte';

	interface Props {
		// only components that have at most the "prop"
		// property required can be passed
		DynamicComponent: Component<{ prop: string }>;
	}

	let { DynamicComponent }: Props = $props();
</script>

<DynamicComponent prop="foo" />
```

> Legacy mode
>
> In Svelte 4, components were of type `SvelteComponent`

To extract the properties from a component, use `ComponentProps`.

```
import type { Component(alias) interface Component<Props extends Record<string, any> = {}, Exports extends Record<string, any> = {}, Bindings extends keyof Props | "" = string>
import Component

Can be used to create strongly typed Svelte components.



Example:



You have component library on npm called component-library, from which
you export a component called MyComponent. For Svelte+TypeScript users,
you want to provide typings. Therefore you create a index.d.ts:



import type { Component } from 'svelte';
export declare const MyComponent: Component<{ foo: string }> {}

Typing this makes it possible for IDEs like VS Code with the Svelte extension
to provide intellisense and to use the component like this in a Svelte file
with TypeScript:



<script lang="ts">
	import { MyComponent } from "component-library";
</script>
<MyComponent foo={'bar'} />
reference, ComponentProps(alias) type ComponentProps<Comp extends SvelteComponent | Component<any, any>> = Comp extends SvelteComponent<infer Props extends Record<string, any>, any, any> ? Props : Comp extends Component<infer Props extends Record<string, any>, any, string> ? Props : never
import ComponentProps

Convenience type to get the props the given component expects.




Example: Ensure a variable contains the props expected by MyComponent:



import type { ComponentProps } from 'svelte';
import MyComponent from './MyComponent.svelte';

// Errors if these aren't the correct props expected by MyComponent.
const props: ComponentProps<typeof MyComponent> = { foo: 'bar' };



[!NOTE] In Svelte 4, you would do ComponentProps<MyComponent> because MyComponent was a class.






Example: A generic function that accepts some component and infers the type of its props:



import type { Component, ComponentProps } from 'svelte';
import MyComponent from './MyComponent.svelte';

function withProps<TComponent extends Component<any>>(
	component: TComponent,
	props: ComponentProps<TComponent>
) {};

// Errors if the second argument is not the correct props expected by the component in the first argument.
withProps(MyComponent, { foo: 'bar' });
reference } from 'svelte';
import MyComponent(alias) type MyComponent = SvelteComponent<Record<string, any>, any, any>
(alias) const MyComponent: LegacyComponentType
import MyComponent from './MyComponent.svelte';

function withPropsfunction withProps<TComponent extends Component<any>>(component: TComponent, props: ComponentProps<TComponent>): void<TComponent(type parameter) TComponent in withProps<TComponent extends Component<any>>(component: TComponent, props: ComponentProps<TComponent>): void extends Component(alias) interface Component<Props extends Record<string, any> = {}, Exports extends Record<string, any> = {}, Bindings extends keyof Props | "" = string>
import Component

Can be used to create strongly typed Svelte components.



Example:



You have component library on npm called component-library, from which
you export a component called MyComponent. For Svelte+TypeScript users,
you want to provide typings. Therefore you create a index.d.ts:



import type { Component } from 'svelte';
export declare const MyComponent: Component<{ foo: string }> {}

Typing this makes it possible for IDEs like VS Code with the Svelte extension
to provide intellisense and to use the component like this in a Svelte file
with TypeScript:



<script lang="ts">
	import { MyComponent } from "component-library";
</script>
<MyComponent foo={'bar'} />
reference<any>>(
	component(parameter) component: TComponent extends Component<any>: TComponent(type parameter) TComponent in withProps<TComponent extends Component<any>>(component: TComponent, props: ComponentProps<TComponent>): void,
	props(parameter) props: ComponentProps<TComponent>: ComponentProps(alias) type ComponentProps<Comp extends SvelteComponent | Component<any, any>> = Comp extends SvelteComponent<infer Props extends Record<string, any>, any, any> ? Props : Comp extends Component<infer Props extends Record<string, any>, any, string> ? Props : never
import ComponentProps

Convenience type to get the props the given component expects.




Example: Ensure a variable contains the props expected by MyComponent:



import type { ComponentProps } from 'svelte';
import MyComponent from './MyComponent.svelte';

// Errors if these aren't the correct props expected by MyComponent.
const props: ComponentProps<typeof MyComponent> = { foo: 'bar' };



[!NOTE] In Svelte 4, you would do ComponentProps<MyComponent> because MyComponent was a class.






Example: A generic function that accepts some component and infers the type of its props:



import type { Component, ComponentProps } from 'svelte';
import MyComponent from './MyComponent.svelte';

function withProps<TComponent extends Component<any>>(
	component: TComponent,
	props: ComponentProps<TComponent>
) {};

// Errors if the second argument is not the correct props expected by the component in the first argument.
withProps(MyComponent, { foo: 'bar' });
reference<TComponent(type parameter) TComponent in withProps<TComponent extends Component<any>>(component: TComponent, props: ComponentProps<TComponent>): void>
) {}

// Errors if the second argument is not the correct props expected
// by the component in the first argument.
withPropsfunction withProps<LegacyComponentType>(component: LegacyComponentType, props: Record<string, any>): void(MyComponent(alias) const MyComponent: LegacyComponentType
import MyComponent, { foo(property) foo: string: 'bar' });
```

To declare that a variable expects the constructor or instance type of a component:

```
<script lang="ts">
	import MyComponent from './MyComponent.svelte';

	let componentConstructor: typeof MyComponent = MyComponent;
	let componentInstance: MyComponent;
</script>

<MyComponent bind:this={componentInstance} />
```

## Enhancing built-in DOM types[](#Enhancing-built-in-DOM-types)

Svelte provides a best effort of all the HTML DOM types that exist. Sometimes you may want to use experimental attributes or custom events coming from an action. In these cases, TypeScript will throw a type error, saying that it does not know these types. If it’s a non-experimental standard attribute/event, this may very well be a missing typing from our [HTML typings](https://github.com/sveltejs/svelte/blob/main/packages/svelte/elements.d.ts). In that case, you are welcome to open an issue and/or a PR fixing it.

In case this is a custom or experimental attribute/event, you can enhance the typings by augmenting the `svelte/elements` module like this:

additional-svelte-typings.d

```
import { HTMLButtonAttributes(alias) interface HTMLButtonAttributes
import HTMLButtonAttributes } from 'svelte/elements';

declare module 'svelte/elements' {
	// add a new element
	export interface SvelteHTMLElementsinterface SvelteHTMLElements {
		'custom-button': HTMLButtonAttributesinterface HTMLButtonAttributes;
	}

	// add a new global attribute that is available on all html elements
	export interface HTMLAttributesinterface HTMLAttributes<T extends EventTarget><T(type parameter) T in HTMLAttributes<T extends EventTarget>> {
		globalattribute(property) HTMLAttributes<T extends EventTarget>.globalattribute?: string | undefined?: string;
	}

	// add a new attribute for button elements
	export interface HTMLButtonAttributesinterface HTMLButtonAttributes {
		veryexperimentalattribute(property) HTMLButtonAttributes.veryexperimentalattribute?: string | undefined?: string;
	}
}

export {}; // ensure this is not an ambient module, else types will be overridden instead of augmented
```

Then make sure that the `d.ts` file is referenced in your `tsconfig.json`. If it reads something like `"include": ["src/**/*"]` and your `d.ts` file is inside `src`, it should work. You may need to reload for the changes to take effect.

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/07-misc/03-typescript.md) [llms.txt](/docs/svelte/typescript/llms.txt)

previous next

[Testing](/docs/svelte/testing) [Custom elements](/docs/svelte/custom-elements)

----
url: https://svelte.dev/docs/svelte/snippet
----

[Skip to main content](#main)

```
{#snippet name()}...{/snippet}
```

```
{#snippet name(param1, param2, paramN)}...{/snippet}
```

Snippets, and [render tags](@render), are a way to create reusable chunks of markup inside your components. Instead of writing duplicative code like [this](/playground/untitled#H4sIAAAAAAAAE5VUYW-kIBD9K8Tmsm2yXXRzvQ-s3eR-R-0HqqOQKhAZb9sz_vdDkV1t000vRmHewMx7w2AflbIGG7GnPlK8gYhFv42JthG-m9Gwf6BGcLbVXZuPSGrzVho8ZirDGpDIhldgySN5GpEMez9kaNuckY1ANJZRamRuu2ZnhEZt6a84pvs43mzD4pMsUDDi8DMkQFYCGdkvsJwblFq5uCik9bmJ4JZwUkv1eoknWigX2eGNN6aGXa6bjV8ybP-X7sM36T58SVcrIIV2xVIaA41xeD5kKqWXuqpUJEefOqVuOkL9DfBchGrzWfu0vb-RpTd3o-zBR045Ga3HfuE5BmJpKauuhbPtENlUF2sqR9jqpsPSxWsMrlngyj3VJiyYjJXb1-lMa7IWC-iSk2M5Zzh-SJjShe-siq5kpZRPs55BbSGU5YPyte4vVV_VfFXxVb10dSLf17pS2lM5HnpPxw4Zpv6x-F57p0jI3OKlVnhv5V9wPQrNYQQ9D_f6aGHlC89fq1Z3qmDkJCTCweOGF4VUFSPJvD_DhreVdA0eu8ehJJ5x91dBaBkpWm3ureCFPt3uzRv56d4kdp-2euG38XZ6dsnd3ZmPG9yRBCrzRUvi-MccOdwz3qE-fOZ7AwAhlrtTUx3c76vRhSwlFBHDtoPhefgHX3dM0PkEAAA=)...

```
{#each images as image}
	{#if image.href}
		<a href={image.href}>
			<figure>
				<img src={image.src} alt={image.caption} width={image.width} height={image.height} />
				<figcaption>{image.caption}</figcaption>
			</figure>
		</a>
	{:else}
		<figure>
			<img src={image.src} alt={image.caption} width={image.width} height={image.height} />
			<figcaption>{image.caption}</figcaption>
		</figure>
	{/if}
{/each}
```

...you can write [this](/playground/untitled#H4sIAAAAAAAAE5VUYW-bMBD9KxbRlERKY4jWfSA02n5H6QcXDmwVbMs-lnaI_z6D7TTt1moTAnPvzvfenQ_GpBEd2CS_HxPJekjy5IfWyS7BFz0b9id0CM62ajDVjBS2MkLjqZQldoBE9KwFS-7I_YyUOPqlRGuqnKw5orY5pVpUduj3mitUln5LU3pI0_UuBp9FjTwnDr9AHETLMSeHK6xiGoWSLi9yYT034cwSRjohn17zcQPNFTs8s153sK9Uv_Yh0-5_5d7-o9zbD-UqCaRWrllSYZQxLw_HUhb0ta-y4NnJUxfUvc7QuLJSaO0a3oh2MLBZat8u-wsPnXzKQvTtVVF34xK5d69ThFmHEQ4SpzeVRediTG8rjD5vBSeN3E5JyHh6R1DQK9-iml5kjzQUN_lSgVU8DhYLx7wwjSvRkMDvTjiwF4zM1kXZ7DlF1eN3A7IG85e-zRrYEjjm0FkI4Cc7Ripm0pHOChexhcWXzreeZyRMU6Mk3ljxC9w4QH-cQZ_b3T5pjHxk1VNr1CDrnJy5QDh6XLO6FrLNSRb2l9gz0wo3S6m7HErSgLsPGMHkpDZK31jOanXeHPQz-eruLHUP0z6yTbpbrn223V70uMXNSpQSZjpL0y8hcxxpNqA6_ql3BQAxlxvfpQ_uT9GrWjQC6iRHM8D0MP0GQsIi92QEAAA=):

```
{#snippet figure(image)}
	<figure>
		<img src={image.src} alt={image.caption} width={image.width} height={image.height} />
		<figcaption>{image.caption}</figcaption>
	</figure>
{/snippet}

{#each images as image}
	{#if image.href}
		<a href={image.href}>
			{@render figure(image)}
		</a>
	{:else}
		{@render figure(image)}
	{/if}
{/each}
```

Like function declarations, snippets can have an arbitrary number of parameters, which can have default values, and you can destructure each parameter. You cannot use rest parameters, however.

## Snippet scope[](#Snippet-scope)

Snippets can be declared anywhere inside your component. They can reference values declared outside themselves, for example in the `<script>` tag or in `{#each ...}` blocks...

[Open in playground](/playground/untitled#H4sIAAAAAAAAA22Q0WrDMAxFf0VRB2nALO9eGrZv6OMyqJOqncG1jaVuK8b_PtwFBmOv96BzJWX05kKoce9tjCSMCk_WEaN-zTgbppW_xPjIH-SEUOESvJAXRo0DL8lGGSc_iSOBDBdiNmeCHRystAznREZAAjAR3MK1OUCBHTzEFCJvu6fJD_2vxOcN_6wC7-Rc2Nb-rlT9EMd7BLlmpYG8VpVm6OM4-dyvo-Uuek7kj5RWT2ucXaitqr9kDnPbFVT4361CX4Ja0pUUyi1WXh-E5U2hGOs-rT-iPhnHVL4BFIsl2E4BAAA)

```
<script>
	let { message = `it's great to see you!` } = $props();
</script>

{#snippet hello(name)}
	<p>hello {name}! {message}!</p>
{/snippet}

{@render hello('alice')}
{@render hello('bob')}
```

```
<script lang="ts">
	let { message = `it's great to see you!` } = $props();
</script>

{#snippet hello(name)}
	<p>hello {name}! {message}!</p>
{/snippet}

{@render hello('alice')}
{@render hello('bob')}
```

...and they are ‘visible’ to everything in the same lexical scope (i.e. siblings, and children of those siblings):

```
<div>
	{#snippet x()}
		{#snippet y()}...{/snippet}

		<!-- this is fine -->
		{@render y()}
	{/snippet}

	<!-- this will error, as `y` is not in scope -->
	{@render y()}
</div>

<!-- this will also error, as `x` is not in scope -->
{@render x()}
```

Snippets can reference themselves and each other:

[Open in playground](/playground/untitled#H4sIAAAAAAAAA22QS2oDMRBEryLaGxvkGXsrjInPkGUmC3mmFQRKj1C3P0EIco5scsUcIciZfLCz66aqHkVlIPuMYOAeg1smdJiQek9PisnHiMKgwfmADOYhw94yToFdjA0fMQiChn4kQRIGA3k2JdU-WJbRufmidNTJhqOl7cf72-umvZwd5XbyVgP9JvvxQDKMJ5rTVzbPvFOktmp1eb9hmUrTND-4KuS7hDRg-stQS7WeOAYDY7myXhXNrXflptwtd71aFNDw3x6CZwEj6YAa5CVWvY4I5VGDWB9OngYwztYyn_B_XViDAQAA)

```
{#snippet blastoff()}
	<span>🚀</span>
{/snippet}

{#snippet countdown(n)}
	{#if n > 0}
		<span>{n}...</span>
		{@render countdown(n - 1)}
	{:else}
		{@render blastoff()}
	{/if}
{/snippet}

{@render countdown(10)}
```

## Passing snippets to components[](#Passing-snippets-to-components)

### Explicit props[](#Passing-snippets-to-components-Explicit-props)

Within the template, snippets are values just like any other. As such, they can be passed to components as props:

[Open in playground](/playground/untitled#H4sIAAAAAAAAA3VS224bIRD9lRGpZLtde5NIeSFk1VZqv6BvcR7YhfWiYsAwbmIh_r1iL74leZzDmTMznBOJ4VtJKPn15rRqFEIwyjmJ4Lx1gRSkVVoGQp8jqXmQI_uHc6vwT2qUpCCNNSgNBkIJC41XDqu1WaPaOusR_vBaS2i93cJsVfbV2Dp7XJtMbKwJCK3fKwzwBM8ZW2OEPIvCjDunZZgVsMMDhYcCnFeNpHAPqbii1txww4_cu9sj-e49uemk9-qkfH9i364eIGX6y-PasPJ0lIk30_90kgvp54uex7Cr-gNYiV01ITs8XNS9-gWCFrkekViO0ulykLevczGNEVUUq3xAYiWK6gzc4eEd1g_8iAlf4er1cjobXBMc-VMcnEkQh5MTRG9fE5QVKchHeUD5hoSi38uC4MHl9xwikoqLDJ1H4fMUaYkQ-0WK8cuL_COQ4Am-9BmdL65NYpil-_Z4o9qxLw3-M8xlNRS59FX87qUR0p88ZSX6kZLdmRpiqdo0hJZhbcVh5MQbyZuu3xJ4AJE-VB-NPNOOZe4brC0nQVYe1zcs4GG8pAchDo35i5dcq42hoGWLjwNcWy-kXwbHG2U2FG57fNy41wf01GC3bDqlxfzefLtbTJo1b_5uvN0bQeHnHtGa37yRFwr9CnSjbc31HLtFAVeQOKo5LsSww-pBbicVVg4HnZJzlYJPs_NSEORKvyojCG25DjL9BzevAka8BAAA)

```
<script>
	import Table from './Table.svelte';

	const fruits = [
		{ name: 'apples', qty: 5, price: 2 },
		{ name: 'bananas', qty: 10, price: 1 },
		{ name: 'cherries', qty: 20, price: 0.5 }
	];
</script>

{#snippet header()}
	<th>fruit</th>
	<th>qty</th>
	<th>price</th>
	<th>total</th>
{/snippet}

{#snippet row(d)}
	<td>{d.name}</td>
	<td>{d.qty}</td>
	<td>{d.price}</td>
	<td>{d.qty * d.price}</td>
{/snippet}

<Table data={fruits} {header} {row} />
```

```
<script lang="ts">
	import Table from './Table.svelte';

	const fruits = [
		{ name: 'apples', qty: 5, price: 2 },
		{ name: 'bananas', qty: 10, price: 1 },
		{ name: 'cherries', qty: 20, price: 0.5 }
	];
</script>

{#snippet header()}
	<th>fruit</th>
	<th>qty</th>
	<th>price</th>
	<th>total</th>
{/snippet}

{#snippet row(d)}
	<td>{d.name}</td>
	<td>{d.qty}</td>
	<td>{d.price}</td>
	<td>{d.qty * d.price}</td>
{/snippet}

<Table data={fruits} {header} {row} />
```

```
<script>
	let { data, header, row } = $props();
</script>

<table>
	{#if header}
		<thead>
			<tr>{@render header()}</tr>
		</thead>
	{/if}

	<tbody>
		{#each data as d}
			<tr>{@render row(d)}</tr>
		{/each}
	</tbody>
</table>

<style>
	table {
		text-align: left;
		border-spacing: 0;
	}

	tbody tr:nth-child(2n+1) {
		background: ButtonFace;
	}

	table :global(th), table :global(td) {
		padding: 0.5em;
	}
</style>
```

```
<script lang="ts">
	let { data, header, row } = $props();
</script>

<table>
	{#if header}
		<thead>
			<tr>{@render header()}</tr>
		</thead>
	{/if}

	<tbody>
		{#each data as d}
			<tr>{@render row(d)}</tr>
		{/each}
	</tbody>
</table>

<style>
	table {
		text-align: left;
		border-spacing: 0;
	}

	tbody tr:nth-child(2n+1) {
		background: ButtonFace;
	}

	table :global(th), table :global(td) {
		padding: 0.5em;
	}
</style>
```

Think about it like passing content instead of data to a component. The concept is similar to slots in web components.

### Implicit props[](#Passing-snippets-to-components-Implicit-props)

As an authoring convenience, snippets declared directly *inside* a component implicitly become props *on* the component:

[Open in playground](/playground/untitled#H4sIAAAAAAAAA3VSwW7bMAz9FUIdkKRz47ZAL4pibDsM2H23pgfZomNhiqxKzLpA8L8Plp24SdOjnh4fH8kXmZU7ZJz92jmjK00QrHYOCZxvXWAZq7XBwPhzZKUMOLK_O7cMf9EQsoxVrSW0FBhnIlReOyo2dkN651pP8FuWBqH27Q5myzy9xtLZamN7YtXaQFD7vaYAa3jusQ1F6HtxmEnnDIZZBq904PCUgfO6Qg6P0GUX1FJaaeWJ-3B_Ij98JFcNeq8n5ceJfb98gq6nv6w2VuTTUFYM4yhJch0Hy12aNt4cF9egVOjni27oJ6gpElHk1BQT9kqHCyQ1v8CoJWlOWMzHJt2wuampb9_mamqpiqiW_ZydyEkVZ_ArHa6gqfl1NtzCh__3TsRw1YJl7Fo8CP8R4-T3mDE6uP6_zxTrsrNIvU_G56EySBDT-rNx0Vk_O3Swhi8psvPFh5tRsjcsTNdj3XQelMeZ-6cv4jePVqGfLily8se15FNBzHU9XkJQ2arDyIk3KKsmuQQZQHVX1ceTvdOOeV-X2CI_Cor8ZN-KQIdxkgRCHAr7Fd9Jo7eWg8GaVgNctl6hvwtOVtpuOdwnfHSc9IE8t9TcVY02av5ovz4sjpqlrP5sfbu3isOPPVFrf8oKzxSSBb41bSnNnJpFBheQOqk5qdTgYfmEu6OKyIeBpuRcpODT7LxkjKQ2b9oqxmtpAnb_AUx9fWbLBAAA)

```
<script>
	import Table from './Table.svelte';

	const fruits = [
		{ name: 'apples', qty: 5, price: 2 },
		{ name: 'bananas', qty: 10, price: 1 },
		{ name: 'cherries', qty: 20, price: 0.5 }
	];
</script>

<Table data={fruits}>
	{#snippet header()}
		<th>fruit</th>
		<th>qty</th>
		<th>price</th>
		<th>total</th>
	{/snippet}

	{#snippet row(d)}
		<td>{d.name}</td>
		<td>{d.qty}</td>
		<td>{d.price}</td>
		<td>{d.qty * d.price}</td>
	{/snippet}
</Table>
```

```
<script lang="ts">
	import Table from './Table.svelte';

	const fruits = [
		{ name: 'apples', qty: 5, price: 2 },
		{ name: 'bananas', qty: 10, price: 1 },
		{ name: 'cherries', qty: 20, price: 0.5 }
	];
</script>

<Table data={fruits}>
	{#snippet header()}
		<th>fruit</th>
		<th>qty</th>
		<th>price</th>
		<th>total</th>
	{/snippet}

	{#snippet row(d)}
		<td>{d.name}</td>
		<td>{d.qty}</td>
		<td>{d.price}</td>
		<td>{d.qty * d.price}</td>
	{/snippet}
</Table>
```

```
<script>
	let { data, header, row } = $props();
</script>

<table>
	{#if header}
		<thead>
			<tr>{@render header()}</tr>
		</thead>
	{/if}

	<tbody>
		{#each data as d}
			<tr>{@render row(d)}</tr>
		{/each}
	</tbody>
</table>

<style>
	table {
		text-align: left;
		border-spacing: 0;
	}

	tbody tr:nth-child(2n+1) {
		background: ButtonFace;
	}

	table :global(th), table :global(td) {
		padding: 0.5em;
	}
</style>
```

```
<script lang="ts">
	let { data, header, row } = $props();
</script>

<table>
	{#if header}
		<thead>
			<tr>{@render header()}</tr>
		</thead>
	{/if}

	<tbody>
		{#each data as d}
			<tr>{@render row(d)}</tr>
		{/each}
	</tbody>
</table>

<style>
	table {
		text-align: left;
		border-spacing: 0;
	}

	tbody tr:nth-child(2n+1) {
		background: ButtonFace;
	}

	table :global(th), table :global(td) {
		padding: 0.5em;
	}
</style>
```

### Implicit children snippet[](#Passing-snippets-to-components-Implicit-children-snippet)

Any content inside the component tags that is *not* a snippet declaration implicitly becomes part of the `children` snippet:

[Open in playground](/playground/untitled#H4sIAAAAAAAAA3WQwU7DQAxEf8VYSG2lTXsPIQJufAPhkGwcsarXWe06FBTl31HV0KiFHu3xaN54RKk9YY6vPrCzTsF-OG4jCSRxIZCiwc4xJczfRmzqRLPhOYRt-iRWQoO2FyXRhDkWyUYXtKykUudDHxVeBtVeoIu9h9V2dxpn8-qhkmK3eKQ4yaVlZ_fgqZjvSzT4X7TSl2KucSCD-h2O-pEXJ3OBexF6m5hJYVx-MMEj3IfYh7Te_AG9yzKIlAZWODhmaAiK5hp-XkCWlZX8yuNTJGkpnoPWm-l8uvS8Zr5Z9d2g1o4PTlrMu5oTTT8t5Ku72QEAAA)

```
<script>
	import Button from './Button.svelte';
</script>

<Button>click me</Button>
```

```
<script lang="ts">
	import Button from './Button.svelte';
</script>

<Button>click me</Button>
```

```
<script>
	let { children } = $props();
</script>

<!-- result will be <button>click me</button> -->
<button>{@render children()}</button>
```

```
<script lang="ts">
	let { children } = $props();
</script>

<!-- result will be <button>click me</button> -->
<button>{@render children()}</button>
```

> Note that you cannot have a prop called `children` if you also have content inside the component — for this reason, you should avoid having props with that name

### Optional snippet props[](#Passing-snippets-to-components-Optional-snippet-props)

You can declare snippet props as being optional. You can either use optional chaining to not render anything if the snippet isn’t set...

```
<script>
	let { children } = $props();
</script>

{@render children?.()}
```

...or use an `#if` block to render fallback content:

```
<script>
	let { children } = $props();
</script>

{#if children}
	{@render children()}
{:else}
	fallback content
{/if}
```

## Typing snippets[](#Typing-snippets)

Snippets implement the `Snippet` interface imported from `'svelte'`:

```
<script lang="ts">
	import type { Snippet } from 'svelte';

	interface Props {
		data: any[];
		children: Snippet;
		row: Snippet<[any]>;
	}

	let { data, children, row }: Props = $props();
</script>
```

With this change, red squigglies will appear if you try and use the component without providing a `data` prop and a `row` snippet. Notice that the type argument provided to `Snippet` is a tuple, since snippets can have multiple parameters.

We can tighten things up further by declaring a generic, so that `data` and `row` refer to the same type:

```
<script lang="ts" generics="T">
	import type { Snippet } from 'svelte';

	let {
		data,
		children,
		row
	}: {
		data: T[];
		children: Snippet;
		row: Snippet<[T]>;
	} = $props();
</script>
```

## Exporting snippets[](#Exporting-snippets)

Snippets declared at the top level of a `.svelte` file can be exported from a `<script module>` for use in other components, provided they don’t reference any declarations in a non-module `<script>` (whether directly or indirectly, via other snippets):

[Open in playground](/playground/untitled#H4sIAAAAAAAAA3XPwU4DIRAG4FeZjIdqStroEVtjDz6FeGDLbELCzhKY1jWEdzc021RtPcP_z_cXZDsQanyb4piEHGT2MZJkVNj7QBn1e8HOZpo_7mJc5SMFIVS4H1mIJaPGTd4nH-XFsBE_tDIoYJ2DCn0aB1is1ufqOb94NrxZX2JcXhOxo9Ri948Knh6qYVR467LQJKglHUihfMX23rhY1S_tn5M3yTCM7hDoJKfpp_wKeDf3nYRWQdeERoqtsITSVdhCsbCErhou5731MuGa8--OD4Viffj07FD3NmSq3-doRU-tAQAA)

```
<script>
	import { add } from './snippets.svelte';
</script>

{@render add(1, 2)}
```

```
<script lang="ts">
	import { add } from './snippets.svelte';
</script>

{@render add(1, 2)}
```

```
<script module>
	export { add };
</script>

{#snippet add(a, b)}
	{a} + {b} = {a + b}
{/snippet}
```

> This requires Svelte 5.5.0 or newer

## Programmatic snippets[](#Programmatic-snippets)

Snippets can be created programmatically with the [`createRawSnippet`](svelte#createRawSnippet) API. This is intended for advanced use cases.

## Snippets and slots[](#Snippets-and-slots)

In Svelte 4, content can be passed to components using [slots](legacy-slots). Snippets are more powerful and flexible, and so slots have been deprecated in Svelte 5.

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/03-template-syntax/06-snippet.md) [llms.txt](/docs/svelte/snippet/llms.txt)

previous next

[{#await ...}](/docs/svelte/await) [{@render ...}](/docs/svelte/@render)

----
url: https://svelte.dev/docs/svelte/svelte-reactivity
----

[Skip to main content](#main)

Svelte provides reactive versions of various built-ins like [`Map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map), [`Set`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set) and [`URL`](https://developer.mozilla.org/en-US/docs/Web/API/URL) that can be used just like their native counterparts, as well as a handful of additional utilities for handling reactivity.

```
import {
	MediaQuery(alias) class MediaQuery
import MediaQuery

Creates a media query and provides a current property that reflects whether or not it matches.




Use it carefully — during server-side rendering, there is no way to know what the correct value should be, potentially causing content to change upon hydration.
If you can use the media query in CSS to achieve the same effect, do that.



<script>
	import { MediaQuery } from 'svelte/reactivity';

	const large = new MediaQuery('min-width: 800px');
</script>

<h1>{large.current ? 'large screen' : 'small screen'}</h1>

ReactiveValue *




5.7.0


reference,
	SvelteDate(alias) class SvelteDate
import SvelteDate

A reactive version of the built-in Date object.
Reading the date (whether with methods like date.getTime() or date.toString(), or via things like Intl.DateTimeFormat)
in an effect or derived
will cause it to be re-evaluated when the value of the date changes.



<script>
	import { SvelteDate } from 'svelte/reactivity';

	const date = new SvelteDate();

	const formatter = new Intl.DateTimeFormat(undefined, {
	  hour: 'numeric',
	  minute: 'numeric',
	  second: 'numeric'
	});

	$effect(() => {
		const interval = setInterval(() => {
			date.setTime(Date.now());
		}, 1000);

		return () => {
			clearInterval(interval);
		};
	});
</script>

<p>The time is {formatter.format(date)}</p>
reference,
	SvelteMap(alias) class SvelteMap<K, V>
import SvelteMap

A reactive version of the built-in Map object.
Reading contents of the map (by iterating, or by reading map.size or calling map.get(...) or map.has(...) as in the tic-tac-toe example below) in an effect or derived
will cause it to be re-evaluated as necessary when the map is updated.




Note that values in a reactive map are not made deeply reactive.



<script>
	import { SvelteMap } from 'svelte/reactivity';
	import { result } from './game.js';

	let board = new SvelteMap();
	let player = $state('x');
	let winner = $derived(result(board));

	function reset() {
		player = 'x';
		board.clear();
	}
</script>

<div class="board">
	{#each Array(9), i}
		<button
			disabled={board.has(i) || winner}
			onclick={() => {
				board.set(i, player);
				player = player === 'x' ? 'o' : 'x';
			}}
		>{board.get(i)}</button>
	{/each}
</div>

{#if winner}
	<p>{winner} wins!</p>
	<button onclick={reset}>reset</button>
{:else}
	<p>{player} is next</p>
{/if}
reference,
	SvelteSet(alias) class SvelteSet<T>
import SvelteSet

A reactive version of the built-in Set object.
Reading contents of the set (by iterating, or by reading set.size or calling set.has(...) as in the example below) in an effect or derived
will cause it to be re-evaluated as necessary when the set is updated.




Note that values in a reactive set are not made deeply reactive.



<script>
	import { SvelteSet } from 'svelte/reactivity';
	let monkeys = new SvelteSet();

	function toggle(monkey) {
		if (monkeys.has(monkey)) {
			monkeys.delete(monkey);
		} else {
			monkeys.add(monkey);
		}
	}
</script>

{#each ['🙈', '🙉', '🙊'] as monkey}
	<button onclick={() => toggle(monkey)}>{monkey}</button>
{/each}

<button onclick={() => monkeys.clear()}>clear</button>

{#if monkeys.has('🙈')}<p>see no evil</p>{/if}
{#if monkeys.has('🙉')}<p>hear no evil</p>{/if}
{#if monkeys.has('🙊')}<p>speak no evil</p>{/if}
reference,
	SvelteURL(alias) class SvelteURL
import SvelteURL

A reactive version of the built-in URL object.
Reading properties of the URL (such as url.href or url.pathname) in an effect or derived
will cause it to be re-evaluated as necessary when the URL changes.




The searchParams property is an instance of SvelteURLSearchParams.




Example:



<script>
	import { SvelteURL } from 'svelte/reactivity';

	const url = new SvelteURL('https://example.com/path');
</script>

<!-- changes to these... -->
<input bind:value={url.protocol} />
<input bind:value={url.hostname} />
<input bind:value={url.pathname} />

<hr />

<!-- will update `href` and vice versa -->
<input bind:value={url.href} size="65" />
reference,
	SvelteURLSearchParams(alias) class SvelteURLSearchParams
import SvelteURLSearchParams

A reactive version of the built-in URLSearchParams object.
Reading its contents (by iterating, or by calling params.get(...) or params.getAll(...) as in the example below) in an effect or derived
will cause it to be re-evaluated as necessary when the params are updated.



<script>
	import { SvelteURLSearchParams } from 'svelte/reactivity';

	const params = new SvelteURLSearchParams('message=hello');

	let key = $state('key');
	let value = $state('value');
</script>

<input bind:value={key} />
<input bind:value={value} />
<button onclick={() => params.append(key, value)}>append</button>

<p>?{params.toString()}</p>

{#each params as [key, value]}
	<p>{key}: {value}</p>
{/each}
reference,
	createSubscriber(alias) function createSubscriber(start: (update: () => void) => (() => void) | void): () => void
import createSubscriber

Returns a subscribe function that integrates external event-based systems with Svelte's reactivity.
It's particularly useful for integrating with web APIs like MediaQuery, IntersectionObserver, or WebSocket.




If subscribe is called inside an effect (including indirectly, for example inside a getter),
the start callback will be called with an update function. Whenever update is called, the effect re-runs.




If start returns a cleanup function, it will be called when the effect is destroyed.




If subscribe is called in multiple effects, start will only be called once as long as the effects
are active, and the returned teardown function will only be called when all effects are destroyed.




It's best understood with an example. Here's an implementation of MediaQuery:



import { createSubscriber } from 'svelte/reactivity';
import { on } from 'svelte/events';

export class MediaQuery {
	#query;
	#subscribe;

	constructor(query) {
		this.#query = window.matchMedia(`(${query})`);

		this.#subscribe = createSubscriber((update) => {
			// when the `change` event occurs, re-run any effects that read `this.current`
			const off = on(this.#query, 'change', update);

			// stop listening when all the effects are destroyed
			return () => off();
		});
	}

	get current() {
		// This makes the getter reactive, if read in an effect
		this.#subscribe();

		// Return the current state of the query, whether or not we're in an effect
		return this.#query.matches;
	}
}

5.7.0


reference
} from 'svelte/reactivity';
```

## MediaQuery[](#MediaQuery)

> Available since 5.7.0

Creates a media query and provides a `current` property that reflects whether or not it matches.

Use it carefully — during server-side rendering, there is no way to know what the correct value should be, potentially causing content to change upon hydration. If you can use the media query in CSS to achieve the same effect, do that.

```
<script>
	import { MediaQuery } from 'svelte/reactivity';

	const large = new MediaQuery('min-width: 800px');
</script>

<h1>{large.current ? 'large screen' : 'small screen'}</h1>
```

```
class MediaQuery extends ReactiveValue<boolean> {/*…*/}
```

```
constructor(query: string, fallback?: boolean | undefined);
```

* `query` A media query string
* `fallback` Fallback value for the server

## SvelteDate[](#SvelteDate)

A reactive version of the built-in [`Date`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) object. Reading the date (whether with methods like `date.getTime()` or `date.toString()`, or via things like [`Intl.DateTimeFormat`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat)) in an [effect](/docs/svelte/$effect) or [derived](/docs/svelte/$derived) will cause it to be re-evaluated when the value of the date changes.

```
<script>
	import { SvelteDate } from 'svelte/reactivity';

	const date = new SvelteDate();

	const formatter = new Intl.DateTimeFormat(undefined, {
	  hour: 'numeric',
	  minute: 'numeric',
	  second: 'numeric'
	});

	$effect(() => {
		const interval = setInterval(() => {
			date.setTime(Date.now());
		}, 1000);

		return () => {
			clearInterval(interval);
		};
	});
</script>

<p>The time is {formatter.format(date)}</p>
```

```
class SvelteDate extends Date {/*…*/}
```

```
constructor(...params: any[]);
```

## SvelteMap[](#SvelteMap)

A reactive version of the built-in [`Map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) object. Reading contents of the map (by iterating, or by reading `map.size` or calling `map.get(...)` or `map.has(...)` as in the [tic-tac-toe example](/playground/0b0ff4aa49c9443f9b47fe5203c78293) below) in an [effect](/docs/svelte/$effect) or [derived](/docs/svelte/$derived) will cause it to be re-evaluated as necessary when the map is updated.

Note that values in a reactive map are *not* made [deeply reactive](/docs/svelte/$state#Deep-state).

```
<script>
	import { SvelteMap } from 'svelte/reactivity';
	import { result } from './game.js';

	let board = new SvelteMap();
	let player = $state('x');
	let winner = $derived(result(board));

	function reset() {
		player = 'x';
		board.clear();
	}
</script>

<div class="board">
	{#each Array(9), i}
		<button
			disabled={board.has(i) || winner}
			onclick={() => {
				board.set(i, player);
				player = player === 'x' ? 'o' : 'x';
			}}
		>{board.get(i)}</button>
	{/each}
</div>

{#if winner}
	<p>{winner} wins!</p>
	<button onclick={reset}>reset</button>
{:else}
	<p>{player} is next</p>
{/if}
```

```
class SvelteMap<K, V> extends Map<K, V> {/*…*/}
```

```
constructor(value?: Iterable<readonly [K, V]> | null | undefined);
```

```
getOrInsert(key: K, value: V): V;
```

```
getOrInsertComputed(key: K, callbackFn: (key: K) => V): V;
```

```
set(key: K, value: V): this;
```

## SvelteSet[](#SvelteSet)

A reactive version of the built-in [`Set`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set) object. Reading contents of the set (by iterating, or by reading `set.size` or calling `set.has(...)` as in the [example](/playground/53438b51194b4882bcc18cddf9f96f15) below) in an [effect](/docs/svelte/$effect) or [derived](/docs/svelte/$derived) will cause it to be re-evaluated as necessary when the set is updated.

Note that values in a reactive set are *not* made [deeply reactive](/docs/svelte/$state#Deep-state).

```
<script>
	import { SvelteSet } from 'svelte/reactivity';
	let monkeys = new SvelteSet();

	function toggle(monkey) {
		if (monkeys.has(monkey)) {
			monkeys.delete(monkey);
		} else {
			monkeys.add(monkey);
		}
	}
</script>

{#each ['🙈', '🙉', '🙊'] as monkey}
	<button onclick={() => toggle(monkey)}>{monkey}</button>
{/each}

<button onclick={() => monkeys.clear()}>clear</button>

{#if monkeys.has('🙈')}<p>see no evil</p>{/if}
{#if monkeys.has('🙉')}<p>hear no evil</p>{/if}
{#if monkeys.has('🙊')}<p>speak no evil</p>{/if}
```

```
class SvelteSet<T> extends Set<T> {/*…*/}
```

```
constructor(value?: Iterable<T> | null | undefined);
```

```
add(value: T): this;
```

## SvelteURL[](#SvelteURL)

A reactive version of the built-in [`URL`](https://developer.mozilla.org/en-US/docs/Web/API/URL) object. Reading properties of the URL (such as `url.href` or `url.pathname`) in an [effect](/docs/svelte/$effect) or [derived](/docs/svelte/$derived) will cause it to be re-evaluated as necessary when the URL changes.

The `searchParams` property is an instance of [SvelteURLSearchParams](/docs/svelte/svelte-reactivity#SvelteURLSearchParams).

[Example](/playground/5a694758901b448c83dc40dc31c71f2a):

```
<script>
	import { SvelteURL } from 'svelte/reactivity';

	const url = new SvelteURL('https://example.com/path');
</script>

<!-- changes to these... -->
<input bind:value={url.protocol} />
<input bind:value={url.hostname} />
<input bind:value={url.pathname} />

<hr />

<!-- will update `href` and vice versa -->
<input bind:value={url.href} size="65" />
```

```
class SvelteURL extends URL {/*…*/}
```

```
get searchParams(): SvelteURLSearchParams;
```

## SvelteURLSearchParams[](#SvelteURLSearchParams)

A reactive version of the built-in [`URLSearchParams`](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams) object. Reading its contents (by iterating, or by calling `params.get(...)` or `params.getAll(...)` as in the [example](/playground/b3926c86c5384bab9f2cf993bc08c1c8) below) in an [effect](/docs/svelte/$effect) or [derived](/docs/svelte/$derived) will cause it to be re-evaluated as necessary when the params are updated.

```
<script>
	import { SvelteURLSearchParams } from 'svelte/reactivity';

	const params = new SvelteURLSearchParams('message=hello');

	let key = $state('key');
	let value = $state('value');
</script>

<input bind:value={key} />
<input bind:value={value} />
<button onclick={() => params.append(key, value)}>append</button>

<p>?{params.toString()}</p>

{#each params as [key, value]}
	<p>{key}: {value}</p>
{/each}
```

```
class SvelteURLSearchParams extends URLSearchParams {/*…*/}
```

```
[REPLACE](params: URLSearchParams): void;
```

## createSubscriber[](#createSubscriber)

> Available since 5.7.0

Returns a `subscribe` function that integrates external event-based systems with Svelte’s reactivity. It’s particularly useful for integrating with web APIs like `MediaQuery`, `IntersectionObserver`, or `WebSocket`.

If `subscribe` is called inside an effect (including indirectly, for example inside a getter), the `start` callback will be called with an `update` function. Whenever `update` is called, the effect re-runs.

If `start` returns a cleanup function, it will be called when the effect is destroyed.

If `subscribe` is called in multiple effects, `start` will only be called once as long as the effects are active, and the returned teardown function will only be called when all effects are destroyed.

It’s best understood with an example. Here’s an implementation of [`MediaQuery`](/docs/svelte/svelte-reactivity#MediaQuery):

```
import { createSubscriber(alias) function createSubscriber(start: (update: () => void) => (() => void) | void): () => void
import createSubscriber

Returns a subscribe function that integrates external event-based systems with Svelte's reactivity.
It's particularly useful for integrating with web APIs like MediaQuery, IntersectionObserver, or WebSocket.




If subscribe is called inside an effect (including indirectly, for example inside a getter),
the start callback will be called with an update function. Whenever update is called, the effect re-runs.




If start returns a cleanup function, it will be called when the effect is destroyed.




If subscribe is called in multiple effects, start will only be called once as long as the effects
are active, and the returned teardown function will only be called when all effects are destroyed.




It's best understood with an example. Here's an implementation of MediaQuery:



import { createSubscriber } from 'svelte/reactivity';
import { on } from 'svelte/events';

export class MediaQuery {
	#query;
	#subscribe;

	constructor(query) {
		this.#query = window.matchMedia(`(${query})`);

		this.#subscribe = createSubscriber((update) => {
			// when the `change` event occurs, re-run any effects that read `this.current`
			const off = on(this.#query, 'change', update);

			// stop listening when all the effects are destroyed
			return () => off();
		});
	}

	get current() {
		// This makes the getter reactive, if read in an effect
		this.#subscribe();

		// Return the current state of the query, whether or not we're in an effect
		return this.#query.matches;
	}
}

5.7.0


reference } from 'svelte/reactivity';
import { on(alias) function on<Type extends keyof WindowEventMap>(window: Window, type: Type, handler: (this: Window, event: WindowEventMap[Type] & {
    currentTarget: Window;
}) => any, options?: AddEventListenerOptions | undefined): () => void (+4 overloads)
import on

Attaches an event handler to the window and returns a function that removes the handler. Using this
rather than addEventListener will preserve the correct order relative to handlers added declaratively
(with attributes like onclick), which use event delegation for performance reasons


reference } from 'svelte/events';

export class MediaQueryclass MediaQuery {
	#query;
	#subscribe;

	constructor(query(parameter) query: any) {
		this.#query = windowvar window: Window & typeof globalThis

The window property of a Window object points to the window object itself.




MDN Reference


.matchMedia(method) matchMedia(query: string): MediaQueryList

The Window interface's matchMedia() method returns a new MediaQueryList object that can then be used to determine if the document matches the media query string, as well as to monitor the document to detect when it matches (or stops matching) that media query.




MDN Reference


(`(${query(parameter) query: any})`);

		this.#subscribe = createSubscriber(alias) createSubscriber(start: (update: () => void) => (() => void) | void): () => void
import createSubscriber

Returns a subscribe function that integrates external event-based systems with Svelte's reactivity.
It's particularly useful for integrating with web APIs like MediaQuery, IntersectionObserver, or WebSocket.




If subscribe is called inside an effect (including indirectly, for example inside a getter),
the start callback will be called with an update function. Whenever update is called, the effect re-runs.




If start returns a cleanup function, it will be called when the effect is destroyed.




If subscribe is called in multiple effects, start will only be called once as long as the effects
are active, and the returned teardown function will only be called when all effects are destroyed.




It's best understood with an example. Here's an implementation of MediaQuery:



import { createSubscriber } from 'svelte/reactivity';
import { on } from 'svelte/events';

export class MediaQuery {
	#query;
	#subscribe;

	constructor(query) {
		this.#query = window.matchMedia(`(${query})`);

		this.#subscribe = createSubscriber((update) => {
			// when the `change` event occurs, re-run any effects that read `this.current`
			const off = on(this.#query, 'change', update);

			// stop listening when all the effects are destroyed
			return () => off();
		});
	}

	get current() {
		// This makes the getter reactive, if read in an effect
		this.#subscribe();

		// Return the current state of the query, whether or not we're in an effect
		return this.#query.matches;
	}
}

5.7.0


reference((update(parameter) update: () => void) => {
			// when the `change` event occurs, re-run any effects that read `this.current`
			const offconst off: () => void = on(alias) on<MediaQueryList, "change">(element: MediaQueryList, type: "change", handler: (this: MediaQueryList, event: MediaQueryListEvent & {
    currentTarget: MediaQueryList;
}) => any, options?: AddEventListenerOptions | undefined): () => void (+4 overloads)
import on

Attaches an event handler to an element and returns a function that removes the handler. Using this
rather than addEventListener will preserve the correct order relative to handlers added declaratively
(with attributes like onclick), which use event delegation for performance reasons


reference(this.#query, 'change', update(parameter) update: () => void);

			// stop listening when all the effects are destroyed
			return () => offconst off: () => void();
		});
	}

	get current(getter) MediaQuery.current: boolean() {
		// This makes the getter reactive, if read in an effect
		this.#subscribe();

		// Return the current state of the query, whether or not we're in an effect
		return this.#query.matches(property) MediaQueryList.matches: boolean

The matches read-only property of the MediaQueryList interface is a boolean value that returns true if the document currently matches the media query list, or false if not.




MDN Reference


;
	}
}
```

```
function createSubscriber(
	start: (update: () => void) => (() => void) | void
): () => void;
```

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/98-reference/21-svelte-reactivity.md) [llms.txt](/docs/svelte/svelte-reactivity/llms.txt)

previous next

[svelte/reactivity/window](/docs/svelte/svelte-reactivity-window) [svelte/server](/docs/svelte/svelte-server)

----
url: https://svelte.dev/docs/svelte/svelte-easing/llms.txt
----

````
This module provides a set of functions that allow you to manipulate time values in different ways. It’s particularly useful for animations when combined with the `motion` module. 



```js
// @noErrors
import {
	backIn,
	backInOut,
	backOut,
	bounceIn,
	bounceInOut,
	bounceOut,
	circIn,
	circInOut,
	circOut,
	cubicIn,
	cubicInOut,
	cubicOut,
	elasticIn,
	elasticInOut,
	elasticOut,
	expoIn,
	expoInOut,
	expoOut,
	linear,
	quadIn,
	quadInOut,
	quadOut,
	quartIn,
	quartInOut,
	quartOut,
	quintIn,
	quintInOut,
	quintOut,
	sineIn,
	sineInOut,
	sineOut
} from 'svelte/easing';
```

## backIn

Rebound effect on start.

<div class="ts-block">

```dts
function backIn(t: number): number;
```

</div>



## backInOut

Rebound effect on start and end of value range.

<div class="ts-block">

```dts
function backInOut(t: number): number;
```

</div>



## backOut

Rebound effect on end.

<div class="ts-block">

```dts
function backOut(t: number): number;
```

</div>



## bounceIn

Bounce effect on start.

<div class="ts-block">

```dts
function bounceIn(t: number): number;
```

</div>



## bounceInOut

Bounce effect on start and end.

<div class="ts-block">

```dts
function bounceInOut(t: number): number;
```

</div>



## bounceOut

Bounce effect on end.

<div class="ts-block">

```dts
function bounceOut(t: number): number;
```

</div>



## circIn

Circular effect, accelerate on start.

<div class="ts-block">

```dts
function circIn(t: number): number;
```

</div>



## circInOut

Circular effect, accelerate on start, decelerate towards end.

<div class="ts-block">

```dts
function circInOut(t: number): number;
```

</div>



## circOut

Circular effect, decelerate towards end.

<div class="ts-block">

```dts
function circOut(t: number): number;
```

</div>



## cubicIn

Cubic scaling, accelerate on start

<div class="ts-block">

```dts
function cubicIn(t: number): number;
```

</div>



## cubicInOut

Cubic scaling, accelerate on start, decelerate towards end.

<div class="ts-block">

```dts
function cubicInOut(t: number): number;
```

</div>



## cubicOut

Cubic scaling, decelerate towards end.

<div class="ts-block">

```dts
function cubicOut(t: number): number;
```

</div>



## elasticIn

Elastic effect on start.

<div class="ts-block">

```dts
function elasticIn(t: number): number;
```

</div>



## elasticInOut

Elastic effect on start and end.

<div class="ts-block">

```dts
function elasticInOut(t: number): number;
```

</div>



## elasticOut

Elastic effect on end.

<div class="ts-block">

```dts
function elasticOut(t: number): number;
```

</div>



## expoIn

Exponential effect on start.

<div class="ts-block">

```dts
function expoIn(t: number): number;
```

</div>



## expoInOut

Exponential effect on start and end.

<div class="ts-block">

```dts
function expoInOut(t: number): number;
```

</div>



## expoOut

Exponential effect on end.

<div class="ts-block">

```dts
function expoOut(t: number): number;
```

</div>



## linear

Returns value as is.

<div class="ts-block">

```dts
function linear(t: number): number;
```

</div>



## quadIn

Quadratic scaling, accelerate on start.

<div class="ts-block">

```dts
function quadIn(t: number): number;
```

</div>



## quadInOut

Quadratic scaling, accelerate on start, decelerate towards end.

<div class="ts-block">

```dts
function quadInOut(t: number): number;
```

</div>



## quadOut

Quadratic scaling, decelerate towards end.

<div class="ts-block">

```dts
function quadOut(t: number): number;
```

</div>



## quartIn

Quartic scaling, accelerate on start.

<div class="ts-block">

```dts
function quartIn(t: number): number;
```

</div>



## quartInOut

Quartic scaling, accelerate on start, decelerate towards end.

<div class="ts-block">

```dts
function quartInOut(t: number): number;
```

</div>



## quartOut

Quartic scaling, decelerate towards end.

<div class="ts-block">

```dts
function quartOut(t: number): number;
```

</div>



## quintIn

Quintic scaling, accelerate on start.

<div class="ts-block">

```dts
function quintIn(t: number): number;
```

</div>



## quintInOut

Quintic scaling, accelerate on start, decelerate towards end.

<div class="ts-block">

```dts
function quintInOut(t: number): number;
```

</div>



## quintOut

Quintic scaling, decelerate towards end.

<div class="ts-block">

```dts
function quintOut(t: number): number;
```

</div>



## sineIn

Sinusoidal effect, accelerate on start.

<div class="ts-block">

```dts
function sineIn(t: number): number;
```

</div>



## sineInOut

Sinusoidal effect, accelerate on start, decelerate towards end.

<div class="ts-block">

```dts
function sineInOut(t: number): number;
```

</div>



## sineOut

Sinusoidal effect, decelerate towards end.

<div class="ts-block">

```dts
function sineOut(t: number): number;
```

</div>
````

----
url: https://svelte.dev/docs/svelte/v4-migration-guide
----

[Skip to main content](#main)

This migration guide provides an overview of how to migrate from Svelte version 3 to 4. See the linked PRs for more details about each change. Use the migration script to migrate some of these automatically: `npx svelte-migrate@latest svelte-4`

If you’re a library author, consider whether to only support Svelte 4 or if it’s possible to support Svelte 3 too. Since most of the breaking changes don’t affect many people, this may be easily possible. Also remember to update the version range in your `peerDependencies`.

## Minimum version requirements[](#Minimum-version-requirements)

* Upgrade to Node 16 or higher. Earlier versions are no longer supported. ([#8566](https://github.com/sveltejs/svelte/issues/8566))
* If you are using SvelteKit, upgrade to 1.20.4 or newer ([sveltejs/kit#10172](https://github.com/sveltejs/kit/pull/10172))
* If you are using Vite without SvelteKit, upgrade to `vite-plugin-svelte` 2.4.1 or newer ([#8516](https://github.com/sveltejs/svelte/issues/8516))
* If you are using webpack, upgrade to webpack 5 or higher and `svelte-loader` 3.1.8 or higher. Earlier versions are no longer supported. ([#8515](https://github.com/sveltejs/svelte/issues/8515), [198dbcf](https://github.com/sveltejs/svelte/commit/198dbcf))
* If you are using Rollup, upgrade to `rollup-plugin-svelte` 7.1.5 or higher ([198dbcf](https://github.com/sveltejs/svelte/commit/198dbcf))
* If you are using TypeScript, upgrade to TypeScript 5 or higher. Lower versions might still work, but no guarantees are made about that. ([#8488](https://github.com/sveltejs/svelte/issues/8488))

## Browser conditions for bundlers[](#Browser-conditions-for-bundlers)

Bundlers must now specify the `browser` condition when building a frontend bundle for the browser. SvelteKit and Vite will handle this automatically for you. If you’re using any others, you may observe lifecycle callbacks such as `onMount` not get called and you’ll need to update the module resolution configuration.

* For Rollup this is done within the `@rollup/plugin-node-resolve` plugin by setting `browser: true` in its options. See the [`rollup-plugin-svelte`](https://github.com/sveltejs/rollup-plugin-svelte/#usage) documentation for more details
* For webpack this is done by adding `"browser"` to the `conditionNames` array. You may also have to update your `alias` config, if you have set it. See the [`svelte-loader`](https://github.com/sveltejs/svelte-loader#usage) documentation for more details

([#8516](https://github.com/sveltejs/svelte/issues/8516))

## Removal of CJS related output[](#Removal-of-CJS-related-output)

Svelte no longer supports the CommonJS (CJS) format for compiler output and has also removed the `svelte/register` hook and the CJS runtime version. If you need to stay on the CJS output format, consider using a bundler to convert Svelte’s ESM output to CJS in a post-build step. ([#8613](https://github.com/sveltejs/svelte/issues/8613))

## Stricter types for Svelte functions[](#Stricter-types-for-Svelte-functions)

There are now stricter types for `createEventDispatcher`, `Action`, `ActionReturn`, and `onMount`:

* `createEventDispatcher` now supports specifying that a payload is optional, required, or non-existent, and the call sites are checked accordingly ([#7224](https://github.com/sveltejs/svelte/issues/7224))

```
import { createEventDispatcher(alias) function createEventDispatcher<EventMap extends Record<string, any> = any>(): EventDispatcher<EventMap>
import createEventDispatcher

Creates an event dispatcher that can be used to dispatch component events.
Event dispatchers are functions that can take two arguments: name and detail.




Component events created with createEventDispatcher create a
CustomEvent.
These events do not bubble.
The detail argument corresponds to the CustomEvent.detail
property and can contain any type of data.




The event dispatcher can be typed to narrow the allowed event names and the type of the detail argument:



const dispatch = createEventDispatcher<{
 loaded: null; // does not take a detail argument
 change: string; // takes a detail argument of type string, which is required
 optional: number | null; // takes an optional detail argument of type number
}>();

Use callback props and/or the $host() rune instead — see migration guide


reference } from 'svelte';

const dispatchconst dispatch: EventDispatcher<{
    optional: number | null;
    required: string;
    noArgument: null;
}> = createEventDispatcher(alias) createEventDispatcher<{
    optional: number | null;
    required: string;
    noArgument: null;
}>(): EventDispatcher<{
    optional: number | null;
    required: string;
    noArgument: null;
}>
import createEventDispatcher

Creates an event dispatcher that can be used to dispatch component events.
Event dispatchers are functions that can take two arguments: name and detail.




Component events created with createEventDispatcher create a
CustomEvent.
These events do not bubble.
The detail argument corresponds to the CustomEvent.detail
property and can contain any type of data.




The event dispatcher can be typed to narrow the allowed event names and the type of the detail argument:



const dispatch = createEventDispatcher<{
 loaded: null; // does not take a detail argument
 change: string; // takes a detail argument of type string, which is required
 optional: number | null; // takes an optional detail argument of type number
}>();

Use callback props and/or the $host() rune instead — see migration guide


reference<{
	optional(property) optional: number | null: number | null;
	required(property) required: string: string;
	noArgument(property) noArgument: null: null;
}>();

// Svelte version 3:
dispatchconst dispatch: EventDispatcher
<"optional">(type: "optional", parameter?: number | null | undefined, options?: DispatchOptions | undefined) => boolean('optional');
dispatchconst dispatch: EventDispatcher
<"required">(type: "required", parameter: string, options?: DispatchOptions | undefined) => boolean('required'); // I can still omit the detail argument
dispatchconst dispatch: EventDispatcher
<"noArgument">(type: "noArgument", parameter?: null | undefined, options?: DispatchOptions | undefined) => boolean('noArgument', 'surprise'); // I can still add a detail argument

// Svelte version 4 using TypeScript strict mode:
dispatchconst dispatch: EventDispatcher
<"optional">(type: "optional", parameter?: number | null | undefined, options?: DispatchOptions | undefined) => boolean('optional');
dispatchconst dispatch: EventDispatcher
<"required">(type: "required", parameter: string, options?: DispatchOptions | undefined) => boolean('required'); // error, missing argument
dispatchconst dispatch: EventDispatcher
<"noArgument">(type: "noArgument", parameter?: null | undefined, options?: DispatchOptions | undefined) => boolean('noArgument', 'surprise'); // error, cannot pass an argument
```

* `Action` and `ActionReturn` have a default parameter type of `undefined` now, which means you need to type the generic if you want to specify that this action receives a parameter. The migration script will migrate this automatically ([#7442](https://github.com/sveltejs/svelte/pull/7442))

```
const action: Action = (node, params) => { ... } // this is now an error if you use params in any way
const actionconst action: Action<HTMLElement, string>: Actiontype Action = /*unresolved*/ any<HTMLElementinterface HTMLElement

The HTMLElement interface represents any HTML element. Some elements directly implement this interface, while others implement it via an interface that inherits it.




MDN Reference


, string> = (node(parameter) node: any, params(parameter) params: any) => { ... } // params is of type string
```

* `onMount` now shows a type error if you return a function asynchronously from it, because this is likely a bug in your code where you expect the callback to be called on destroy, which it will only do for synchronously returned functions ([#8136](https://github.com/sveltejs/svelte/issues/8136))

```
// Example where this change reveals an actual bug
onMountany(
	// someCleanup() not called because function handed to onMount is async
	async () => {
		const something = await foo();
                                         	// someCleanup() is called because function handed to onMount is sync
	() => {
		fooany().thenany(something(parameter) something: any => {...});
		// ...
		return () => someCleanupany();
	}
);
```

## Custom Elements with Svelte[](#Custom-Elements-with-Svelte)

The creation of custom elements with Svelte has been overhauled and significantly improved. The `tag` option is deprecated in favor of the new `customElement` option:

```
<svelte:options tag="my-component" />
<svelte:options customElement="my-component" />
```

This change was made to allow [more configurability](custom-elements#Component-options) for advanced use cases. The migration script will adjust your code automatically. The update timing of properties has changed slightly as well. ([#8457](https://github.com/sveltejs/svelte/issues/8457))

## SvelteComponentTyped is deprecated[](#SvelteComponentTyped-is-deprecated)

`SvelteComponentTyped` is deprecated, as `SvelteComponent` now has all its typing capabilities. Replace all instances of `SvelteComponentTyped` with `SvelteComponent`.

```
import { SvelteComponentTyped } from 'svelte';
import { SvelteComponent(alias) class SvelteComponent<Props extends Record<string, any> = Record<string, any>, Events extends Record<string, any> = any, Slots extends Record<string, any> = any>
import SvelteComponent

This was the base class for Svelte components in Svelte 4. Svelte 5+ components
are completely different under the hood. For typing, use Component instead.
To instantiate components, use mount instead.
See migration guide for more info.


reference } from 'svelte';

export class Foo extends SvelteComponentTyped<{ aProp: string }> {}
export class Fooclass Foo extends SvelteComponent(alias) class SvelteComponent<Props extends Record<string, any> = Record<string, any>, Events extends Record<string, any> = any, Slots extends Record<string, any> = any>
import SvelteComponent

This was the base class for Svelte components in Svelte 4. Svelte 5+ components
are completely different under the hood. For typing, use Component instead.
To instantiate components, use mount instead.
See migration guide for more info.


reference<{ aProp(property) aProp: string: string }> {}
```

If you have used `SvelteComponent` as the component instance type previously, you may see a somewhat opaque type error now, which is solved by changing `: typeof SvelteComponent` to `: typeof SvelteComponent<any>`.

```
<script>
	import ComponentA from './ComponentA.svelte';
	import ComponentB from './ComponentB.svelte';
	import { SvelteComponent } from 'svelte';

	let component: typeof SvelteComponent<any>;

	function choseRandomly() {
		component = Math.random() > 0.5 ? ComponentA : ComponentB;
	}
</script>

<button on:click={choseRandomly}>random</button>
<svelte:element this={component} />
```

The migration script will do both automatically for you. ([#8512](https://github.com/sveltejs/svelte/issues/8512))

## Transitions are local by default[](#Transitions-are-local-by-default)

Transitions are now local by default to prevent confusion around page navigations. “local” means that a transition will not play if it’s within a nested control flow block (`each/if/await/key`) and not the direct parent block but a block above it is created/destroyed. In the following example, the `slide` intro animation will only play when `success` goes from `false` to `true`, but it will *not* play when `show` goes from `false` to `true`:

```
{#if show}
	...
	{#if success}
		<p in:slide>Success</p>
	{/each}
{/if}
```

To make transitions global, add the `|global` modifier — then they will play when *any* control flow block above is created/destroyed. The migration script will do this automatically for you. ([#6686](https://github.com/sveltejs/svelte/issues/6686))

## Default slot bindings[](#Default-slot-bindings)

Default slot bindings are no longer exposed to named slots and vice versa:

```
<script>
	import Nested from './Nested.svelte';
</script>

<Nested let:count>
	<p>
		count in default slot — is available: {count}
	</p>
	<p slot="bar">
		count in bar slot — is not available: {count}
	</p>
</Nested>
```

This makes slot bindings more consistent as the behavior is undefined when for example the default slot is from a list and the named slot is not. ([#6049](https://github.com/sveltejs/svelte/issues/6049))

## Preprocessors[](#Preprocessors)

The order in which preprocessors are applied has changed. Now, preprocessors are executed in order, and within one group, the order is markup, script, style.

```
import { preprocess(alias) function preprocess(source: string, preprocessor: PreprocessorGroup | PreprocessorGroup[], options?: {
    filename?: string;
} | undefined): Promise<Processed>
import preprocess

The preprocess function provides convenient hooks for arbitrarily transforming component source code.
For example, it can be used to convert a <style lang="sass"> block into vanilla CSS.


reference } from 'svelte/compiler';

const { codeconst code: string

The new code


 } = await preprocess(alias) preprocess(source: string, preprocessor: PreprocessorGroup | PreprocessorGroup[], options?: {
    filename?: string;
} | undefined): Promise<Processed>
import preprocess

The preprocess function provides convenient hooks for arbitrarily transforming component source code.
For example, it can be used to convert a <style lang="sass"> block into vanilla CSS.


reference(
	sourceany,
	[
		{
			markup(property) PreprocessorGroup.markup?: MarkupPreprocessor | undefined: () => {
				consolenamespace console
var console: Console

The console module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.




The module exports two specific components:





A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.


A global console instance configured to write to process.stdout and
process.stderr. The global console can be used without importing the node:console module.





Warning: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the note on process I/O for
more information.




Example using the global console:



console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
//   Error: Whoops, something bad happened
//     at [eval]:5:15
//     at Script.runInThisContext (node:vm:132:18)
//     at Object.runInThisContext (node:vm:309:38)
//     at node:internal/process/execution:77:19
//     at [eval]-wrapper:6:22
//     at evalScript (node:internal/process/execution:76:60)
//     at node:internal/main/eval_string:23:3

const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:



const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);

myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err

const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

source


.log(method) Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to printf(3)
(the arguments are all passed to util.format()).



const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.




v0.1.100


('markup-1');
			},
			script(property) PreprocessorGroup.script?: Preprocessor | undefined: () => {
				consolenamespace console
var console: Console

The console module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.




The module exports two specific components:





A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.


A global console instance configured to write to process.stdout and
process.stderr. The global console can be used without importing the node:console module.





Warning: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the note on process I/O for
more information.




Example using the global console:



console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
//   Error: Whoops, something bad happened
//     at [eval]:5:15
//     at Script.runInThisContext (node:vm:132:18)
//     at Object.runInThisContext (node:vm:309:38)
//     at node:internal/process/execution:77:19
//     at [eval]-wrapper:6:22
//     at evalScript (node:internal/process/execution:76:60)
//     at node:internal/main/eval_string:23:3

const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:



const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);

myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err

const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

source


.log(method) Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to printf(3)
(the arguments are all passed to util.format()).



const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.




v0.1.100


('script-1');
			},
			style(property) PreprocessorGroup.style?: Preprocessor | undefined: () => {
				consolenamespace console
var console: Console

The console module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.




The module exports two specific components:





A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.


A global console instance configured to write to process.stdout and
process.stderr. The global console can be used without importing the node:console module.





Warning: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the note on process I/O for
more information.




Example using the global console:



console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
//   Error: Whoops, something bad happened
//     at [eval]:5:15
//     at Script.runInThisContext (node:vm:132:18)
//     at Object.runInThisContext (node:vm:309:38)
//     at node:internal/process/execution:77:19
//     at [eval]-wrapper:6:22
//     at evalScript (node:internal/process/execution:76:60)
//     at node:internal/main/eval_string:23:3

const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:



const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);

myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err

const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

source


.log(method) Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to printf(3)
(the arguments are all passed to util.format()).



const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.




v0.1.100


('style-1');
			}
		},
		{
			markup(property) PreprocessorGroup.markup?: MarkupPreprocessor | undefined: () => {
				consolenamespace console
var console: Console

The console module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.




The module exports two specific components:





A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.


A global console instance configured to write to process.stdout and
process.stderr. The global console can be used without importing the node:console module.





Warning: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the note on process I/O for
more information.




Example using the global console:



console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
//   Error: Whoops, something bad happened
//     at [eval]:5:15
//     at Script.runInThisContext (node:vm:132:18)
//     at Object.runInThisContext (node:vm:309:38)
//     at node:internal/process/execution:77:19
//     at [eval]-wrapper:6:22
//     at evalScript (node:internal/process/execution:76:60)
//     at node:internal/main/eval_string:23:3

const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:



const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);

myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err

const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

source


.log(method) Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to printf(3)
(the arguments are all passed to util.format()).



const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.




v0.1.100


('markup-2');
			},
			script(property) PreprocessorGroup.script?: Preprocessor | undefined: () => {
				consolenamespace console
var console: Console

The console module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.




The module exports two specific components:





A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.


A global console instance configured to write to process.stdout and
process.stderr. The global console can be used without importing the node:console module.





Warning: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the note on process I/O for
more information.




Example using the global console:



console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
//   Error: Whoops, something bad happened
//     at [eval]:5:15
//     at Script.runInThisContext (node:vm:132:18)
//     at Object.runInThisContext (node:vm:309:38)
//     at node:internal/process/execution:77:19
//     at [eval]-wrapper:6:22
//     at evalScript (node:internal/process/execution:76:60)
//     at node:internal/main/eval_string:23:3

const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:



const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);

myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err

const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

source


.log(method) Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to printf(3)
(the arguments are all passed to util.format()).



const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.




v0.1.100


('script-2');
			},
			style(property) PreprocessorGroup.style?: Preprocessor | undefined: () => {
				consolenamespace console
var console: Console

The console module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.




The module exports two specific components:





A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.


A global console instance configured to write to process.stdout and
process.stderr. The global console can be used without importing the node:console module.





Warning: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the note on process I/O for
more information.




Example using the global console:



console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
//   Error: Whoops, something bad happened
//     at [eval]:5:15
//     at Script.runInThisContext (node:vm:132:18)
//     at Object.runInThisContext (node:vm:309:38)
//     at node:internal/process/execution:77:19
//     at [eval]-wrapper:6:22
//     at evalScript (node:internal/process/execution:76:60)
//     at node:internal/main/eval_string:23:3

const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:



const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);

myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err

const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

source


.log(method) Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to printf(3)
(the arguments are all passed to util.format()).



const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.




v0.1.100


('style-2');
			}
		}
	],
	{
		filename(property) filename?: string | undefined: 'App.svelte'
	}
);

// Svelte 3 logs:
// markup-1
// markup-2
// script-1
// script-2
// style-1
// style-2

// Svelte 4 logs:
// markup-1
// script-1
// style-1
// markup-2
// script-2
// style-2
```

This could affect you for example if you are using `MDsveX` - in which case you should make sure it comes before any script or style preprocessor.

```
preprocess: [
	vitePreprocess(),
	mdsvex(mdsvexConfig)
	mdsvexany(mdsvexConfigany),
	vitePreprocessany()
]
```

Each preprocessor must also have a name. ([#8618](https://github.com/sveltejs/svelte/issues/8618))

## New eslint package[](#New-eslint-package)

`eslint-plugin-svelte3` is deprecated. It may still work with Svelte 4 but we make no guarantees about that. We recommend switching to our new package [eslint-plugin-svelte](https://github.com/sveltejs/eslint-plugin-svelte). See [this Github post](https://github.com/sveltejs/kit/issues/10242#issuecomment-1610798405) for an instruction how to migrate. Alternatively, you can create a new project using `npm create svelte@latest`, select the eslint (and possibly TypeScript) option and then copy over the related files into your existing project.

## Other breaking changes[](#Other-breaking-changes)

* the `inert` attribute is now applied to outroing elements to make them invisible to assistive technology and prevent interaction. ([#8628](https://github.com/sveltejs/svelte/pull/8628))
* the runtime now uses `classList.toggle(name, boolean)` which may not work in very old browsers. Consider using a [polyfill](https://github.com/eligrey/classList.js) if you need to support these browsers. ([#8629](https://github.com/sveltejs/svelte/issues/8629))
* the runtime now uses the `CustomEvent` constructor which may not work in very old browsers. Consider using a [polyfill](https://github.com/theftprevention/event-constructor-polyfill/tree/master) if you need to support these browsers. ([#8775](https://github.com/sveltejs/svelte/pull/8775))
* people implementing their own stores from scratch using the `StartStopNotifier` interface (which is passed to the create function of `writable` etc) from `svelte/store` now need to pass an update function in addition to the set function. This has no effect on people using stores or creating stores using the existing Svelte stores. ([#6750](https://github.com/sveltejs/svelte/issues/6750))
* `derived` will now throw an error on falsy values instead of stores passed to it. ([#7947](https://github.com/sveltejs/svelte/issues/7947))
* type definitions for `svelte/internal` were removed to further discourage usage of those internal methods which are not public API. Most of these will likely change for Svelte 5
* Removal of DOM nodes is now batched which slightly changes its order, which might affect the order of events fired if you’re using a `MutationObserver` on these elements ([#8763](https://github.com/sveltejs/svelte/pull/8763))
* if you enhanced the global typings through the `svelte.JSX` namespace before, you need to migrate this to use the `svelteHTML` namespace. Similarly if you used the `svelte.JSX` namespace to use type definitions from it, you need to migrate those to use the types from `svelte/elements` instead. You can find more information about what to do [here](https://github.com/sveltejs/language-tools/blob/master/docs/preprocessors/typescript.md#im-getting-deprecation-warnings-for-sveltejsx--i-want-to-migrate-to-the-new-typings)

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/07-misc/06-v4-migration-guide.md) [llms.txt](/docs/svelte/v4-migration-guide/llms.txt)

previous next

[Browser support](/docs/svelte/browser-support) [Svelte 5 migration guide](/docs/svelte/v5-migration-guide)

----
url: https://svelte.dev/docs/svelte/svelte-motion
----

[Skip to main content](#main)

```
import {
	Spring(alias) class Spring<T>
(alias) interface Spring<T>
import Spring

A wrapper for a value that behaves in a spring-like fashion. Changes to spring.target will cause spring.current to
move towards it over time, taking account of the spring.stiffness and spring.damping parameters.



<script>
	import { Spring } from 'svelte/motion';

	const spring = new Spring(0);
</script>

<input type="range" bind:value={spring.target} />
<input type="range" bind:value={spring.current} disabled />

5.8.0


reference,
	Tween(alias) class Tween<T>
import Tween

A wrapper for a value that tweens smoothly to its target value. Changes to tween.target will cause tween.current to
move towards it over time, taking account of the delay, duration and easing options.



<script>
	import { Tween } from 'svelte/motion';

	const tween = new Tween(0);
</script>

<input type="range" bind:value={tween.target} />
<input type="range" bind:value={tween.current} disabled />

5.8.0


reference,
	prefersReducedMotion(alias) const prefersReducedMotion: MediaQuery
import prefersReducedMotion

A media query that matches if the user prefers reduced motion.



<script>
	import { prefersReducedMotion } from 'svelte/motion';
	import { fly } from 'svelte/transition';

	let visible = $state(false);
</script>

<button onclick={() => visible = !visible}>
	toggle
</button>

{#if visible}
	<p transition:fly={{ y: prefersReducedMotion.current ? 0 : 200 }}>
		flies in, unless the user prefers reduced motion
	</p>
{/if}

5.7.0


reference,
	spring(alias) function spring<T = any>(value?: T | undefined, opts?: SpringOptions | undefined): Spring<T>
import spring

The spring function in Svelte creates a store whose value is animated, with a motion that simulates the behavior of a spring. This means when the value changes, instead of transitioning at a steady rate, it "bounces" like a spring would, depending on the physics parameters provided. This adds a level of realism to the transitions and can enhance the user experience.




Use Spring instead


reference,
	tweened(alias) function tweened<T>(value?: T | undefined, defaults?: TweenOptions<T> | undefined): Tweened<T>
import tweened

A tweened store in Svelte is a special type of store that provides smooth transitions between state values over time.




Use Tween instead


reference
} from 'svelte/motion';
```

## Spring[](#Spring)

> Available since 5.8.0

A wrapper for a value that behaves in a spring-like fashion. Changes to `spring.target` will cause `spring.current` to move towards it over time, taking account of the `spring.stiffness` and `spring.damping` parameters.

```
<script>
	import { Spring } from 'svelte/motion';

	const spring = new Spring(0);
</script>

<input type="range" bind:value={spring.target} />
<input type="range" bind:value={spring.current} disabled />
```

```
class Spring<T> {/*…*/}
```

```
constructor(value: T, options?: SpringOptions);
```

```
static of<U>(fn: () => U, options?: SpringOptions): Spring<U>;
```

Create a spring whose value is bound to the return value of `fn`. This must be called inside an effect root (for example, during component initialisation).

```
<script>
	import { Spring } from 'svelte/motion';

	let { number } = $props();

	const spring = Spring.of(() => number);
</script>
```

```
set(value: T, options?: SpringUpdateOptions): Promise<void>;
```

Sets `spring.target` to `value` and returns a `Promise` that resolves if and when `spring.current` catches up to it.

If `options.instant` is `true`, `spring.current` immediately matches `spring.target`.

If `options.preserveMomentum` is provided, the spring will continue on its current trajectory for the specified number of milliseconds. This is useful for things like ‘fling’ gestures.

```
damping: number;
```

```
precision: number;
```

```
stiffness: number;
```

```
target: T;
```

The end value of the spring. This property only exists on the `Spring` class, not the legacy `spring` store.

```
get current(): T;
```

The current value of the spring. This property only exists on the `Spring` class, not the legacy `spring` store.

## Tween[](#Tween)

> Available since 5.8.0

A wrapper for a value that tweens smoothly to its target value. Changes to `tween.target` will cause `tween.current` to move towards it over time, taking account of the `delay`, `duration` and `easing` options.

```
<script>
	import { Tween } from 'svelte/motion';

	const tween = new Tween(0);
</script>

<input type="range" bind:value={tween.target} />
<input type="range" bind:value={tween.current} disabled />
```

```
class Tween<T> {/*…*/}
```

```
static of<U>(fn: () => U, options?: TweenOptions<U> | undefined): Tween<U>;
```

Create a tween whose value is bound to the return value of `fn`. This must be called inside an effect root (for example, during component initialisation).

```
<script>
	import { Tween } from 'svelte/motion';

	let { number } = $props();

	const tween = Tween.of(() => number);
</script>
```

```
constructor(value: T, options?: TweenOptions<T>);
```

```
set(value: T, options?: TweenOptions<T> | undefined): Promise<void>;
```

Sets `tween.target` to `value` and returns a `Promise` that resolves if and when `tween.current` catches up to it.

If `options` are provided, they will override the tween’s defaults.

```
get current(): T;
```

```
set target(v: T);
```

```
get target(): T;
```

## prefersReducedMotion[](#prefersReducedMotion)

> Available since 5.7.0

A [media query](/docs/svelte/svelte-reactivity#MediaQuery) that matches if the user [prefers reduced motion](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion).

```
<script>
	import { prefersReducedMotion } from 'svelte/motion';
	import { fly } from 'svelte/transition';

	let visible = $state(false);
</script>

<button onclick={() => visible = !visible}>
	toggle
</button>

{#if visible}
	<p transition:fly={{ y: prefersReducedMotion.current ? 0 : 200 }}>
		flies in, unless the user prefers reduced motion
	</p>
{/if}
```

```
const prefersReducedMotion: MediaQuery;
```

## spring[](#spring)

> Use [`Spring`](/docs/svelte/svelte-motion#Spring) instead

The spring function in Svelte creates a store whose value is animated, with a motion that simulates the behavior of a spring. This means when the value changes, instead of transitioning at a steady rate, it “bounces” like a spring would, depending on the physics parameters provided. This adds a level of realism to the transitions and can enhance the user experience.

```
function spring<T = any>(
	value?: T | undefined,
	opts?: SpringOptions | undefined
): Spring<T>;
```

## tweened[](#tweened)

> Use [`Tween`](/docs/svelte/svelte-motion#Tween) instead

A tweened store in Svelte is a special type of store that provides smooth transitions between state values over time.

```
function tweened<T>(
	value?: T | undefined,
	defaults?: TweenOptions<T> | undefined
): Tweened<T>;
```

## Spring[](#Spring)

```
interface Spring<T> extends Readable<T> {/*…*/}
```

```
set(new_value: T, opts?: SpringUpdateOptions): Promise<void>;
```

```
update: (fn: Updater<T>, opts?: SpringUpdateOptions) => Promise<void>;
```

* deprecated Only exists on the legacy `spring` store, not the `Spring` class

```
subscribe(fn: (value: T) => void): Unsubscriber;
```

* deprecated Only exists on the legacy `spring` store, not the `Spring` class

```
precision: number;
```

```
damping: number;
```

```
stiffness: number;
```

## SpringOptions[](#SpringOptions)

```
interface SpringOptions {/*…*/}
```

```
stiffness?: number;
```

```
damping?: number;
```

```
precision?: number;
```

## SpringUpdateOptions[](#SpringUpdateOptions)

```
interface SpringUpdateOptions {/*…*/}
```

```
hard?: any;
```

* deprecated Only use this for the spring store; does nothing when set on the Spring class

```
soft?: string | number | boolean;
```

* deprecated Only use this for the spring store; does nothing when set on the Spring class

```
instant?: boolean;
```

Only use this for the Spring class; does nothing when set on the spring store

```
preserveMomentum?: number;
```

Only use this for the Spring class; does nothing when set on the spring store

## TweenOptions[](#TweenOptions)

```
interface TweenOptions<T> {/*…*/}
```

```
delay?: number;
```

```
duration?: number | ((from: T, to: T) => number);
```

```
easing?: (t: number) => number;
```

```
interpolate?: (a: T, b: T) => (t: number) => T;
```

## Tweened[](#Tweened)

```
interface Tweened<T> extends Readable<T> {/*…*/}
```

```
set(value: T, opts?: TweenOptions<T>): Promise<void>;
```

```
update(updater: Updater<T>, opts?: TweenOptions<T>): Promise<void>;
```

## Updater[](#Updater)

```
type Updater<T> = (target_value: T, value: T) => T;
```

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/98-reference/21-svelte-motion.md) [llms.txt](/docs/svelte/svelte-motion/llms.txt)

previous next

[svelte/legacy](/docs/svelte/svelte-legacy) [svelte/reactivity/window](/docs/svelte/svelte-reactivity-window)

----
url: https://svelte.dev/docs/svelte/legacy-svelte-component
----

[Skip to main content](#main)

In runes mode, `<MyComponent>` will re-render if the value of `MyComponent` changes. See the [Svelte 5 migration guide](/docs/svelte/v5-migration-guide#svelte:component-is-no-longer-necessary) for an example.

In legacy mode, it won’t — we must use `<svelte:component>`, which destroys and recreates the component instance when the value of its `this` expression changes:

```
<svelte:component this={MyComponent} />
```

If `this` is falsy, no component is rendered.

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/99-legacy/30-legacy-svelte-component.md) [llms.txt](/docs/svelte/legacy-svelte-component/llms.txt)

previous next

[\<svelte:fragment>](/docs/svelte/legacy-svelte-fragment) [\<svelte:self>](/docs/svelte/legacy-svelte-self)

----
url: https://svelte.dev/docs/svelte/runtime-warnings
----

[Skip to main content](#main)

## Client warnings[](#Client-warnings)

### assignment\_value\_stale[](#Client-warnings-assignment_value_stale)

```
Assignment to `%property%` property (%location%) will evaluate to the right-hand side, not the value of `%property%` following the assignment. This may result in unexpected behaviour.
```

Given a case like this...

```
<script>
	let object = $state({ array: null });

	function add() {
		(object.array ??= []).push(object.array.length);
	}
</script>

<button onclick={add}>add</button>
<p>items: {JSON.stringify(object.items)}</p>
```

...the array being pushed to when the button is first clicked is the `[]` on the right-hand side of the assignment, but the resulting value of `object.array` is an empty state proxy. As a result, the pushed value will be discarded.

You can fix this by separating it into two statements:

```
function addfunction add(): void() {
	objectlet object: {
    array: number[];
}.array(property) array: number[] ??= [];
	objectlet object: {
    array: number[];
}.array(property) array: number[].push(method) Array<number>.push(...items: number[]): number

Appends new elements to the end of an array, and returns the new length of the array.


items 

New elements to add to the array.


(objectlet object: {
    array: number[];
}.array(property) array: number[].length(property) Array<number>.length: number

Gets or sets the length of the array. This is a number one higher than the highest index in the array.


);
}
```

### await\_reactivity\_loss[](#Client-warnings-await_reactivity_loss)

```
Detected reactivity loss when reading `%name%`. This happens when state is read in an async function after an earlier `await`
```

Svelte’s signal-based reactivity works by tracking which bits of state are read when a template or `$derived(...)` expression executes. If an expression contains an `await`, Svelte transforms it such that any state *after* the `await` is also tracked — in other words, in a case like this...

```
let totallet total: number = $derivedfunction $derived<number>(expression: number): number
namespace $derived

Declares derived state, i.e. one that depends on other state variables.
The expression inside $derived(...) should be free of side-effects.




Example:



let double = $derived(count * 2);

{@link https://svelte.dev/docs/svelte/$derived Documentation}


expression 

The derived state expression


(await alet a: Promise<number> + blet b: number);
```

...both `a` and `b` are tracked, even though `b` is only read once `a` has resolved, after the initial execution.

This does *not* apply to an `await` that is not ‘visible’ inside the expression. In a case like this...

```
async function sumfunction sum(): Promise<number>() {
	return await alet a: Promise<number> + blet b: number;
}

let totallet total: number = $derivedfunction $derived<number>(expression: number): number
namespace $derived

Declares derived state, i.e. one that depends on other state variables.
The expression inside $derived(...) should be free of side-effects.




Example:



let double = $derived(count * 2);

{@link https://svelte.dev/docs/svelte/$derived Documentation}


expression 

The derived state expression


(await sumfunction sum(): Promise<number>());
```

...`total` will depend on `a` (which is read immediately) but not `b` (which is not). The solution is to pass the values into the function:

```
/**
 * @param {Promise<number>} a
 * @param {number} b
 */
async function sumfunction sum(a: Promise<number>, b: number): Promise<number>ab(a(parameter) a: Promise<number>a, b(parameter) b: numberb) {
	return await a(parameter) a: Promise<number>a + b(parameter) b: numberb;
}

let totallet total: number = $derivedfunction $derived<number>(expression: number): number
namespace $derived

Declares derived state, i.e. one that depends on other state variables.
The expression inside $derived(...) should be free of side-effects.




Example:



let double = $derived(count * 2);

{@link https://svelte.dev/docs/svelte/$derived Documentation}


expression 

The derived state expression


(await sumfunction sum(a: Promise<number>, b: number): Promise<number>ab(alet a: Promise<number>, blet b: number));
```

### await\_waterfall[](#Client-warnings-await_waterfall)

```
An async derived, `%name%` (%location%) was not read immediately after it resolved. This often indicates an unnecessary waterfall, which can slow down your app
```

In a case like this...

```
let alet a: number = $derivedfunction $derived<number>(expression: number): number
namespace $derived

Declares derived state, i.e. one that depends on other state variables.
The expression inside $derived(...) should be free of side-effects.




Example:



let double = $derived(count * 2);

{@link https://svelte.dev/docs/svelte/$derived Documentation}


expression 

The derived state expression


(await onefunction one(): Promise<number>());
let blet b: number = $derivedfunction $derived<number>(expression: number): number
namespace $derived

Declares derived state, i.e. one that depends on other state variables.
The expression inside $derived(...) should be free of side-effects.




Example:



let double = $derived(count * 2);

{@link https://svelte.dev/docs/svelte/$derived Documentation}


expression 

The derived state expression


(await twofunction two(): Promise<number>());
```

...the second `$derived` will not be created until the first one has resolved. Since `await two()` does not depend on the value of `a`, this delay, often described as a ‘waterfall’, is unnecessary.

(Note that if the values of `await one()` and `await two()` subsequently change, they can do so concurrently — the waterfall only occurs when the deriveds are first created.)

You can solve this by creating the promises first and *then* awaiting them:

```
let aPromiselet aPromise: Promise<number> = $derivedfunction $derived<Promise<number>>(expression: Promise<number>): Promise<number>
namespace $derived

Declares derived state, i.e. one that depends on other state variables.
The expression inside $derived(...) should be free of side-effects.




Example:



let double = $derived(count * 2);

{@link https://svelte.dev/docs/svelte/$derived Documentation}


expression 

The derived state expression


(onefunction one(): Promise<number>());
let bPromiselet bPromise: Promise<number> = $derivedfunction $derived<Promise<number>>(expression: Promise<number>): Promise<number>
namespace $derived

Declares derived state, i.e. one that depends on other state variables.
The expression inside $derived(...) should be free of side-effects.




Example:



let double = $derived(count * 2);

{@link https://svelte.dev/docs/svelte/$derived Documentation}


expression 

The derived state expression


(twofunction two(): Promise<number>());

let alet a: number = $derivedfunction $derived<number>(expression: number): number
namespace $derived

Declares derived state, i.e. one that depends on other state variables.
The expression inside $derived(...) should be free of side-effects.




Example:



let double = $derived(count * 2);

{@link https://svelte.dev/docs/svelte/$derived Documentation}


expression 

The derived state expression


(await aPromiselet aPromise: Promise<number>);
let blet b: number = $derivedfunction $derived<number>(expression: number): number
namespace $derived

Declares derived state, i.e. one that depends on other state variables.
The expression inside $derived(...) should be free of side-effects.




Example:



let double = $derived(count * 2);

{@link https://svelte.dev/docs/svelte/$derived Documentation}


expression 

The derived state expression


(await bPromiselet bPromise: Promise<number>);
```

### binding\_property\_non\_reactive[](#Client-warnings-binding_property_non_reactive)

```
`%binding%` is binding to a non-reactive property
```

```
`%binding%` (%location%) is binding to a non-reactive property
```

### console\_log\_state[](#Client-warnings-console_log_state)

```
Your `console.%method%` contained `$state` proxies. Consider using `$inspect(...)` or `$state.snapshot(...)` instead
```

When logging a [proxy](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy), browser devtools will log the proxy itself rather than the value it represents. In the case of Svelte, the ‘target’ of a `$state` proxy might not resemble its current value, which can be confusing.

The easiest way to log a value as it changes over time is to use the [`$inspect`](/docs/svelte/$inspect) rune. Alternatively, to log things on a one-off basis (for example, inside an event handler) you can use [`$state.snapshot`](/docs/svelte/$state#$state.snapshot) to take a snapshot of the current value.

### derived\_inert[](#Client-warnings-derived_inert)

```
Reading a derived belonging to a now-destroyed effect may result in stale values
```

A `$derived` value created inside an effect will stop updating when the effect is destroyed. You should create the `$derived` outside the effect, or inside an `$effect.root`.

### event\_handler\_invalid[](#Client-warnings-event_handler_invalid)

```
%handler% should be a function. Did you mean to %suggestion%?
```

### hydratable\_missing\_but\_expected[](#Client-warnings-hydratable_missing_but_expected)

```
Expected to find a hydratable with key `%key%` during hydration, but did not.
```

This can happen if you render a hydratable on the client that was not rendered on the server, and means that it was forced to fall back to running its function blockingly during hydration. This is bad for performance, as it blocks hydration until the asynchronous work completes.

```
<script>
  import { hydratable } from 'svelte';

	if (BROWSER) {
		// bad! nothing can become interactive until this asynchronous work is done
		await hydratable('foo', get_slow_random_number);
	}
</script>
```

### hydration\_attribute\_changed[](#Client-warnings-hydration_attribute_changed)

```
The `%attribute%` attribute on `%html%` changed its value between server and client renders. The client value, `%value%`, will be ignored in favour of the server value
```

Certain attributes like `src` on an `<img>` element will not be repaired during hydration, i.e. the server value will be kept. That’s because updating these attributes can cause the image to be refetched (or in the case of an `<iframe>`, for the frame to be reloaded), even if they resolve to the same resource.

To fix this, either silence the warning with a [`svelte-ignore`](basic-markup#Comments) comment, or ensure that the value stays the same between server and client. If you really need the value to change on hydration, you can force an update like this:

```
<script>
	let { src } = $props();

	if (typeof window !== 'undefined') {
		// stash the value...
		const initial = src;

		// unset it...
		src = undefined;

		$effect(() => {
			// ...and reset after we've mounted
			src = initial;
		});
	}
</script>

<img {src} />
```

### hydration\_html\_changed[](#Client-warnings-hydration_html_changed)

```
The value of an `{@html ...}` block changed between server and client renders. The client value will be ignored in favour of the server value
```

```
The value of an `{@html ...}` block %location% changed between server and client renders. The client value will be ignored in favour of the server value
```

If the `{@html ...}` value changes between the server and the client, it will not be repaired during hydration, i.e. the server value will be kept. That’s because change detection during hydration is expensive and usually unnecessary.

To fix this, either silence the warning with a [`svelte-ignore`](basic-markup#Comments) comment, or ensure that the value stays the same between server and client. If you really need the value to change on hydration, you can force an update like this:

```
<script>
	let { markup } = $props();

	if (typeof window !== 'undefined') {
		// stash the value...
		const initial = markup;

		// unset it...
		markup = undefined;

		$effect(() => {
			// ...and reset after we've mounted
			markup = initial;
		});
	}
</script>

{@html markup}
```

### hydration\_mismatch[](#Client-warnings-hydration_mismatch)

```
Hydration failed because the initial UI does not match what was rendered on the server
```

```
Hydration failed because the initial UI does not match what was rendered on the server. The error occurred near %location%
```

This warning is thrown when Svelte encounters an error while hydrating the HTML from the server. During hydration, Svelte walks the DOM, expecting a certain structure. If that structure is different (for example because the HTML was repaired by the DOM because of invalid HTML), then Svelte will run into issues, resulting in this warning.

During development, this error is often preceded by a `console.error` detailing the offending HTML, which needs fixing.

### invalid\_raw\_snippet\_render[](#Client-warnings-invalid_raw_snippet_render)

```
The `render` function passed to `createRawSnippet` should return HTML for a single element
```

### legacy\_recursive\_reactive\_block[](#Client-warnings-legacy_recursive_reactive_block)

```
Detected a migrated `$:` reactive block in `%filename%` that both accesses and updates the same reactive value. This may cause recursive updates when converted to an `$effect`.
```

### lifecycle\_double\_unmount[](#Client-warnings-lifecycle_double_unmount)

```
Tried to unmount a component that was not mounted
```

### ownership\_invalid\_binding[](#Client-warnings-ownership_invalid_binding)

```
%parent% passed property `%prop%` to %child% with `bind:`, but its parent component %owner% did not declare `%prop%` as a binding. Consider creating a binding between %owner% and %parent% (e.g. `bind:%prop%={...}` instead of `%prop%={...}`)
```

Consider three components `GrandParent`, `Parent` and `Child`. If you do `<GrandParent bind:value>`, inside `GrandParent` pass on the variable via `<Parent {value} />` (note the missing `bind:`) and then do `<Child bind:value>` inside `Parent`, this warning is thrown.

To fix it, `bind:` to the value instead of just passing a property (i.e. in this example do `<Parent bind:value />`).

### ownership\_invalid\_mutation[](#Client-warnings-ownership_invalid_mutation)

```
Mutating unbound props (`%name%`, at %location%) is strongly discouraged. Consider using `bind:%prop%={...}` in %parent% (or using a callback) instead
```

Consider the following code:

App

```
<script>
	import Child from './Child.svelte';
	let person = $state({ name: 'Florida', surname: 'Man' });
</script>

<Child {person} />
```

```
<script lang="ts">
	import Child from './Child.svelte';
	let person = $state({ name: 'Florida', surname: 'Man' });
</script>

<Child {person} />
```

Child

```
<script>
	let { person } = $props();
</script>

<input bind:value={person.name}>
<input bind:value={person.surname}>
```

```
<script lang="ts">
	let { person } = $props();
</script>

<input bind:value={person.name}>
<input bind:value={person.surname}>
```

`Child` is mutating `person` which is owned by `App` without being explicitly “allowed” to do so. This is strongly discouraged since it can create code that is hard to reason about at scale (“who mutated this value?”), hence the warning.

To fix it, either create callback props to communicate changes, or mark `person` as [`$bindable`]($bindable).

### select\_multiple\_invalid\_value[](#Client-warnings-select_multiple_invalid_value)

```
The `value` property of a `<select multiple>` element should be an array, but it received a non-array value. The selection will be kept as is.
```

When using `<select multiple value={...}>`, Svelte will mark all selected `<option>` elements as selected by iterating over the array passed to `value`. If `value` is not an array, Svelte will emit this warning and keep the selected options as they are.

To silence the warning, ensure that `value`:

* is an array for an explicit selection
* is `null` or `undefined` to keep the selection as is

### state\_proxy\_equality\_mismatch[](#Client-warnings-state_proxy_equality_mismatch)

```
Reactive `$state(...)` proxies and the values they proxy have different identities. Because of this, comparisons with `%operator%` will produce unexpected results
```

`$state(...)` creates a [proxy](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy) of the value it is passed. The proxy and the value have different identities, meaning equality checks will always return `false`:

```
<script>
	let value = { foo: 'bar' };
	let proxy = $state(value);

	value === proxy; // always false
</script>
```

To resolve this, ensure you’re comparing values where both values were created with `$state(...)`, or neither were. Note that `$state.raw(...)` will *not* create a state proxy.

### svelte\_boundary\_reset\_noop[](#Client-warnings-svelte_boundary_reset_noop)

```
A `<svelte:boundary>` `reset` function only resets the boundary the first time it is called
```

When an error occurs while rendering the contents of a [`<svelte:boundary>`](/docs/svelte/svelte-boundary), the `onerror` handler is called with the error plus a `reset` function that attempts to re-render the contents.

This `reset` function should only be called once. After that, it has no effect — in a case like this, where a reference to `reset` is stored outside the boundary, clicking the button while `<Contents />` is rendered will *not* cause the contents to be rendered again.

```
<script>
	let reset;
</script>

<button onclick={reset}>reset</button>

<svelte:boundary onerror={(e, r) => (reset = r)}>
	<!-- contents -->

	{#snippet failed(e)}
		<p>oops! {e.message}</p>
	{/snippet}
</svelte:boundary>
```

### transition\_slide\_display[](#Client-warnings-transition_slide_display)

```
The `slide` transition does not work correctly for elements with `display: %value%`
```

The [slide](/docs/svelte/svelte-transition#slide) transition works by animating the `height` of the element, which requires a `display` style like `block`, `flex` or `grid`. It does not work for:

* `display: inline` (which is the default for elements like `<span>`), and its variants like `inline-block`, `inline-flex` and `inline-grid`
* `display: table` and `table-[name]`, which are the defaults for elements like `<table>` and `<tr>`
* `display: contents`

## Shared warnings[](#Shared-warnings)

### dynamic\_void\_element\_content[](#Shared-warnings-dynamic_void_element_content)

```
`<svelte:element this="%tag%">` is a void element — it cannot have content
```

Elements such as `<input>` cannot have content, any children passed to these elements will be ignored.

### state\_snapshot\_uncloneable[](#Shared-warnings-state_snapshot_uncloneable)

```
Value cannot be cloned with `$state.snapshot` — the original value was returned
```

```
The following properties cannot be cloned with `$state.snapshot` — the return value contains the originals:

%properties%
```

`$state.snapshot` tries to clone the given value in order to return a reference that no longer changes. Certain objects may not be cloneable, in which case the original value is returned. In the following example, `property` is cloned, but `window` is not, because DOM elements are uncloneable:

```
const objectconst object: {
    property: string;
    window: Window & typeof globalThis;
} = $statefunction $state<{
    property: string;
    window: Window & typeof globalThis;
}>(initial: {
    property: string;
    window: Window & typeof globalThis;
}): {
    property: string;
    window: Window & typeof globalThis;
} (+1 overload)
namespace $state

Declares reactive state.




Example:



let count = $state(0);

{@link https://svelte.dev/docs/svelte/$state Documentation}


initial 

The initial value


({ property(property) property: string: 'this is cloneable', window(property) window: Window & typeof globalThis })
const snapshotconst snapshot: {
    property: string;
    window: {
        [x: number]: {
            [x: number]: ...;
            readonly clientInformation: {
                readonly clipboard: {
                    read: {};
                    readText: {};
                    write: {};
                    writeText: {};
                    addEventListener: {};
                    dispatchEvent: {};
                    removeEventListener: {};
                };
                readonly credentials: {
                    create: {};
                    get: {};
                    preventSilentAccess: {};
                    store: {};
                };
                readonly doNotTrack: string | null;
                readonly geolocation: {
                    clearWatch: {};
                    getCurrentPosition: {};
                    watchPosition: {};
                };
                readonly login: {
                    setStatus: {};
                };
                readonly maxTouchPoints: number;
                readonly mediaCapabilities: {
                    decodingInfo: {};
                    encodingInfo: {};
                };
                readonly mediaDevices: {
                    ondevicechange: {} | null;
                    ... 6 more ...;
                    dispatchEvent: {};
                };
                ... 36 more ...;
                readonly storage: {
                    ...;
                };
            };
            ... 218 more ...;
            readonly sessionStorage: {
                ...;
            };
        };
        ... 1015 more ...;
        undefined: undefined;
    };
} = $statenamespace $state
function $state<T>(initial: T): T (+1 overload)

Declares reactive state.




Example:



let count = $state(0);

{@link https://svelte.dev/docs/svelte/$state Documentation}


initial 

The initial value


.snapshotfunction $state.snapshot<{
    property: string;
    window: Window & typeof globalThis;
}>(state: {
    property: string;
    window: Window & typeof globalThis;
}): {
    property: string;
    window: {
        [x: number]: {
            [x: number]: ...;
            readonly clientInformation: {
                readonly clipboard: {
                    read: {};
                    readText: {};
                    write: {};
                    writeText: {};
                    addEventListener: {};
                    dispatchEvent: {};
                    removeEventListener: {};
                };
                readonly credentials: {
                    create: {};
                    get: {};
                    preventSilentAccess: {};
                    store: {};
                };
                readonly doNotTrack: string | null;
                readonly geolocation: {
                    clearWatch: {};
                    getCurrentPosition: {};
                    watchPosition: {};
                };
                readonly login: {
                    setStatus: {};
                };
                ... 39 more ...;
                readonly storage: {
                    ...;
                };
            };
            ... 218 more ...;
            readonly sessionStorage: {
                ...;
            };
        };
        ... 1015 more ...;
        undefined: undefined;
    };
}

To take a static snapshot of a deeply reactive $state proxy, use $state.snapshot:




Example:



<script>
  let counter = $state({ count: 0 });

  function onclick() {
    // Will log `{ count: ... }` rather than `Proxy { ... }`
    console.log($state.snapshot(counter));
  };
</script>

If state has a toJSON method, the snapshot will clone the value returned from toJSON instead of the original object.




{@link https://svelte.dev/docs/svelte/$state#$state.snapshot Documentation}


state 

The value to snapshot


(objectconst object: {
    property: string;
    window: Window & typeof globalThis;
});
```

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/98-reference/30-runtime-warnings.md) [llms.txt](/docs/svelte/runtime-warnings/llms.txt)

previous next

[Runtime errors](/docs/svelte/runtime-errors) [Overview](/docs/svelte/legacy-overview)

----
url: https://svelte.dev/docs/svelte/compiler-warnings
----

[Skip to main content](#main)

Svelte warns you at compile time if it catches potential mistakes, such as writing inaccessible markup.

Some warnings may be incorrect in your concrete use case. You can disable such false positives by placing a `<!-- svelte-ignore <code> -->` comment above the line that causes the warning. Example:

```
<!-- svelte-ignore a11y_autofocus -->
<input autofocus />
```

You can list multiple rules in a single comment (separated by commas), and add an explanatory note (in parentheses) alongside them:

```
<!-- svelte-ignore a11y_click_events_have_key_events, a11y_no_static_element_interactions (because of reasons) -->
<div onclick>...</div>
```

### a11y\_accesskey[](#a11y_accesskey)

```
Avoid using accesskey
```

Enforce no `accesskey` on element. Access keys are HTML attributes that allow web developers to assign keyboard shortcuts to elements. Inconsistencies between keyboard shortcuts and keyboard commands used by screen reader and keyboard-only users create accessibility complications. To avoid complications, access keys should not be used.

```
<!-- A11y: Avoid using accesskey -->
<div accesskey="z"></div>
```

### a11y\_aria\_activedescendant\_has\_tabindex[](#a11y_aria_activedescendant_has_tabindex)

```
An element with an aria-activedescendant attribute should have a tabindex value
```

An element with `aria-activedescendant` must be tabbable, so it must either have an inherent `tabindex` or declare `tabindex` as an attribute.

```
<!-- A11y: Elements with attribute aria-activedescendant should have tabindex value -->
<div aria-activedescendant="some-id"></div>
```

### a11y\_aria\_attributes[](#a11y_aria_attributes)

```
`<%name%>` should not have aria-* attributes
```

Certain reserved DOM elements do not support ARIA roles, states and properties. This is often because they are not visible, for example `meta`, `html`, `script`, `style`. This rule enforces that these DOM elements do not contain the `aria-*` props.

```
<!-- A11y: <meta> should not have aria-* attributes -->
<meta aria-hidden="false" />
```

### a11y\_autocomplete\_valid[](#a11y_autocomplete_valid)

```
'%value%' is an invalid value for 'autocomplete' on `<input type="%type%">`
```

### a11y\_autofocus[](#a11y_autofocus)

```
Avoid using autofocus
```

Enforce that `autofocus` is not used on elements. Autofocusing elements can cause usability issues for sighted and non-sighted users alike.

```
<!-- A11y: Avoid using autofocus -->
<input autofocus />
```

### a11y\_click\_events\_have\_key\_events[](#a11y_click_events_have_key_events)

```
Visible, non-interactive element `<%element%>` with a click event must be accompanied by a keyboard event handler. Consider whether an interactive element such as `<button type="button">` or `<a>` might be more appropriate
```

Enforce that visible, non-interactive elements with an `onclick` event are accompanied by a keyboard event handler.

Users should first consider whether an interactive element might be more appropriate such as a `<button type="button">` element for actions or `<a>` element for navigations. These elements are more semantically meaningful and will have built-in key handling. E.g. `Space` and `Enter` will trigger a `<button>` and `Enter` will trigger an `<a>` element.

If a non-interactive element is required then `onclick` should be accompanied by an `onkeyup` or `onkeydown` handler that enables the user to perform equivalent actions via the keyboard. In order for the user to be able to trigger a key press, the element will also need to be focusable by adding a [`tabindex`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex). While an `onkeypress` handler will also silence this warning, it should be noted that the `keypress` event is deprecated.

```
<!-- A11y: visible, non-interactive elements with an onclick event must be accompanied by a keyboard event handler. -->
<div onclick={() => {}}></div>
```

Coding for the keyboard is important for users with physical disabilities who cannot use a mouse, AT compatibility, and screenreader users.

### a11y\_consider\_explicit\_label[](#a11y_consider_explicit_label)

```
Buttons and links should either contain text or have an `aria-label`, `aria-labelledby` or `title` attribute
```

### a11y\_distracting\_elements[](#a11y_distracting_elements)

```
Avoid `<%name%>` elements
```

Enforces that no distracting elements are used. Elements that can be visually distracting can cause accessibility issues with visually impaired users. Such elements are most likely deprecated, and should be avoided.

The following elements are visually distracting: `<marquee>` and `<blink>`.

```
<!-- A11y: Avoid <marquee> elements -->
<marquee></marquee>
```

### a11y\_figcaption\_index[](#a11y_figcaption_index)

```
`<figcaption>` must be first or last child of `<figure>`
```

### a11y\_figcaption\_parent[](#a11y_figcaption_parent)

```
`<figcaption>` must be an immediate child of `<figure>`
```

Enforce that certain DOM elements have the correct structure.

```
<!-- A11y: <figcaption> must be an immediate child of <figure> -->
<div>
	<figcaption>Image caption</figcaption>
</div>
```

### a11y\_hidden[](#a11y_hidden)

```
`<%name%>` element should not be hidden
```

Certain DOM elements are useful for screen reader navigation and should not be hidden.

```
<!-- A11y: <h2> element should not be hidden -->
<h2 aria-hidden="true">invisible header</h2>
```

### a11y\_img\_redundant\_alt[](#a11y_img_redundant_alt)

```
Screenreaders already announce `<img>` elements as an image
```

Enforce img alt attribute does not contain the word image, picture, or photo. Screen readers already announce `img` elements as an image. There is no need to use words such as *image*, *photo*, and/or *picture*.

```
<img src="foo" alt="Foo eating a sandwich." />

<!-- aria-hidden, won't be announced by screen reader -->
<img src="bar" aria-hidden="true" alt="Picture of me taking a photo of an image" />

<!-- A11y: Screen readers already announce <img> elements as an image. -->
<img src="foo" alt="Photo of foo being weird." />

<!-- A11y: Screen readers already announce <img> elements as an image. -->
<img src="bar" alt="Image of me at a bar!" />

<!-- A11y: Screen readers already announce <img> elements as an image. -->
<img src="foo" alt="Picture of baz fixing a bug." />
```

### a11y\_incorrect\_aria\_attribute\_type[](#a11y_incorrect_aria_attribute_type)

```
The value of '%attribute%' must be a %type%
```

Enforce that only the correct type of value is used for aria attributes. For example, `aria-hidden` should only receive a boolean.

```
<!-- A11y: The value of 'aria-hidden' must be exactly one of true or false -->
<div aria-hidden="yes"></div>
```

### a11y\_incorrect\_aria\_attribute\_type\_boolean[](#a11y_incorrect_aria_attribute_type_boolean)

```
The value of '%attribute%' must be either 'true' or 'false'. It cannot be empty
```

### a11y\_incorrect\_aria\_attribute\_type\_id[](#a11y_incorrect_aria_attribute_type_id)

```
The value of '%attribute%' must be a string that represents a DOM element ID
```

### a11y\_incorrect\_aria\_attribute\_type\_idlist[](#a11y_incorrect_aria_attribute_type_idlist)

```
The value of '%attribute%' must be a space-separated list of strings that represent DOM element IDs
```

### a11y\_incorrect\_aria\_attribute\_type\_integer[](#a11y_incorrect_aria_attribute_type_integer)

```
The value of '%attribute%' must be an integer
```

### a11y\_incorrect\_aria\_attribute\_type\_token[](#a11y_incorrect_aria_attribute_type_token)

```
The value of '%attribute%' must be exactly one of %values%
```

### a11y\_incorrect\_aria\_attribute\_type\_tokenlist[](#a11y_incorrect_aria_attribute_type_tokenlist)

```
The value of '%attribute%' must be a space-separated list of one or more of %values%
```

### a11y\_incorrect\_aria\_attribute\_type\_tristate[](#a11y_incorrect_aria_attribute_type_tristate)

```
The value of '%attribute%' must be exactly one of true, false, or mixed
```

### a11y\_interactive\_supports\_focus[](#a11y_interactive_supports_focus)

```
Elements with the '%role%' interactive role must have a tabindex value
```

Enforce that elements with an interactive role and interactive handlers (mouse or key press) must be focusable or tabbable.

```
<!-- A11y: Elements with the 'button' interactive role must have a tabindex value. -->
<div role="button" onkeypress={() => {}} />
```

### a11y\_invalid\_attribute[](#a11y_invalid_attribute)

```
'%href_value%' is not a valid %href_attribute% attribute
```

Enforce that attributes important for accessibility have a valid value. For example, `href` should not be empty, `'#'`, or `javascript:`.

```
<!-- A11y: '' is not a valid href attribute -->
<a href="">invalid</a>
```

### a11y\_label\_has\_associated\_control[](#a11y_label_has_associated_control)

```
A form label must be associated with a control
```

Enforce that a label tag has a text label and an associated control.

There are two supported ways to associate a label with a control:

* Wrapping a control in a label tag.
* Adding `for` to a label and assigning it the ID of an input on the page.

```
<label for="id">B</label>

<label>C <input type="text" /></label>

<!-- A11y: A form label must be associated with a control. -->
<label>A</label>
```

### a11y\_media\_has\_caption[](#a11y_media_has_caption)

```
`<video>` elements must have a `<track kind="captions">`
```

Providing captions for media is essential for deaf users to follow along. Captions should be a transcription or translation of the dialogue, sound effects, relevant musical cues, and other relevant audio information. Not only is this important for accessibility, but can also be useful for all users in the case that the media is unavailable (similar to `alt` text on an image when an image is unable to load).

The captions should contain all important and relevant information to understand the corresponding media. This may mean that the captions are not a 1:1 mapping of the dialogue in the media content. However, captions are not necessary for video components with the `muted` attribute.

```
<video><track kind="captions" /></video>

<audio muted></audio>

<!-- A11y: Media elements must have a <track kind=\"captions\"> -->
<video></video>

<!-- A11y: Media elements must have a <track kind=\"captions\"> -->
<video><track /></video>
```

### a11y\_misplaced\_role[](#a11y_misplaced_role)

```
`<%name%>` should not have role attribute
```

Certain reserved DOM elements do not support ARIA roles, states and properties. This is often because they are not visible, for example `meta`, `html`, `script`, `style`. This rule enforces that these DOM elements do not contain the `role` props.

```
<!-- A11y: <meta> should not have role attribute -->
<meta role="tooltip" />
```

### a11y\_misplaced\_scope[](#a11y_misplaced_scope)

```
The scope attribute should only be used with `<th>` elements
```

The scope attribute should only be used on `<th>` elements.

```
<!-- A11y: The scope attribute should only be used with <th> elements -->
<div scope="row" />
```

### a11y\_missing\_attribute[](#a11y_missing_attribute)

```
`<%name%>` element should have %article% %sequence% attribute
```

Enforce that attributes required for accessibility are present on an element. This includes the following checks:

* `<a>` should have an href (unless it’s a [fragment-defining tag](https://github.com/sveltejs/svelte/issues/4697))
* `<area>` should have alt, aria-label, or aria-labelledby
* `<html>` should have lang
* `<iframe>` should have title
* `<img>` should have alt
* `<object>` should have title, aria-label, or aria-labelledby
* `<input type="image">` should have alt, aria-label, or aria-labelledby

```
<!-- A11y: <input type=\"image\"> element should have an alt, aria-label or aria-labelledby attribute -->
<input type="image" />

<!-- A11y: <html> element should have a lang attribute -->
<html></html>

<!-- A11y: <a> element should have an href attribute -->
<a>text</a>
```

### a11y\_missing\_content[](#a11y_missing_content)

```
`<%name%>` element should contain text
```

Enforce that heading elements (`h1`, `h2`, etc.) and anchors have content and that the content is accessible to screen readers

```
<!-- A11y: <a> element should have child content -->
<a href="/foo"></a>

<!-- A11y: <h1> element should have child content -->
<h1></h1>
```

### a11y\_mouse\_events\_have\_key\_events[](#a11y_mouse_events_have_key_events)

```
'%event%' event must be accompanied by '%accompanied_by%' event
```

Enforce that `onmouseover` and `onmouseout` are accompanied by `onfocus` (or `onfocusin`) and `onblur` (or `onfocusout`), respectively. This helps to ensure that any functionality triggered by these mouse events is also accessible to keyboard users.

```
<!-- A11y: onmouseover must be accompanied by onfocus -->
<div onmouseover={handleMouseover} />

<!-- A11y: onmouseout must be accompanied by onblur -->
<div onmouseout={handleMouseout} />
```

### a11y\_no\_abstract\_role[](#a11y_no_abstract_role)

```
Abstract role '%role%' is forbidden
```

### a11y\_no\_interactive\_element\_to\_noninteractive\_role[](#a11y_no_interactive_element_to_noninteractive_role)

```
`<%element%>` cannot have role '%role%'
```

[WAI-ARIA](https://www.w3.org/TR/wai-aria-1.1/#usage_intro) roles should not be used to convert an interactive element to a non-interactive element. Non-interactive ARIA roles include `article`, `banner`, `complementary`, `img`, `listitem`, `main`, `region` and `tooltip`.

```
<!-- A11y: <textarea> cannot have role 'listitem' -->
<textarea role="listitem"></textarea>
```

### a11y\_no\_noninteractive\_element\_interactions[](#a11y_no_noninteractive_element_interactions)

```
Non-interactive element `<%element%>` should not be assigned mouse or keyboard event listeners
```

A non-interactive element does not support event handlers (mouse and key handlers). Non-interactive elements include `<main>`, `<area>`, `<h1>` (,`<h2>`, etc), `<p>`, `<img>`, `<li>`, `<ul>` and `<ol>`. Non-interactive [WAI-ARIA roles](https://www.w3.org/TR/wai-aria-1.1/#usage_intro) include `article`, `banner`, `complementary`, `img`, `listitem`, `main`, `region` and `tooltip`.

```
<!-- `A11y: Non-interactive element <li> should not be assigned mouse or keyboard event listeners.` -->
<li onclick={() => {}}></li>

<!-- `A11y: Non-interactive element <div> should not be assigned mouse or keyboard event listeners.` -->
<div role="listitem" onclick={() => {}}></div>
```

### a11y\_no\_noninteractive\_element\_to\_interactive\_role[](#a11y_no_noninteractive_element_to_interactive_role)

```
Non-interactive element `<%element%>` cannot have interactive role '%role%'
```

[WAI-ARIA](https://www.w3.org/TR/wai-aria-1.1/#usage_intro) roles should not be used to convert a non-interactive element to an interactive element. Interactive ARIA roles include `button`, `link`, `checkbox`, `menuitem`, `menuitemcheckbox`, `menuitemradio`, `option`, `radio`, `searchbox`, `switch` and `textbox`.

```
<!-- A11y: Non-interactive element <h3> cannot have interactive role 'searchbox' -->
<h3 role="searchbox">Button</h3>
```

### a11y\_no\_noninteractive\_tabindex[](#a11y_no_noninteractive_tabindex)

```
noninteractive element cannot have nonnegative tabIndex value
```

Tab key navigation should be limited to elements on the page that can be interacted with.

```
<!-- A11y: noninteractive element cannot have nonnegative tabIndex value -->
<div tabindex="0"></div>
```

### a11y\_no\_redundant\_roles[](#a11y_no_redundant_roles)

```
Redundant role '%role%'
```

Some HTML elements have default ARIA roles. Giving these elements an ARIA role that is already set by the browser [has no effect](https://www.w3.org/TR/using-aria/#aria-does-nothing) and is redundant.

```
<!-- A11y: Redundant role 'button' -->
<button role="button">...</button>

<!-- A11y: Redundant role 'img' -->
<img role="img" src="foo.jpg" />
```

### a11y\_no\_static\_element\_interactions[](#a11y_no_static_element_interactions)

```
`<%element%>` with a %handler% handler must have an ARIA role
```

Elements like `<div>` with interactive handlers like `click` must have an ARIA role.

```
<!-- A11y: <div> with click handler must have an ARIA role -->
<div onclick={() => ''}></div>
```

### a11y\_positive\_tabindex[](#a11y_positive_tabindex)

```
Avoid tabindex values above zero
```

Avoid positive `tabindex` property values. This will move elements out of the expected tab order, creating a confusing experience for keyboard users.

```
<!-- A11y: avoid tabindex values above zero -->
<div tabindex="1"></div>
```

### a11y\_role\_has\_required\_aria\_props[](#a11y_role_has_required_aria_props)

```
Elements with the ARIA role "%role%" must have the following attributes defined: %props%
```

Elements with ARIA roles must have all required attributes for that role.

```
<!-- A11y: A11y: Elements with the ARIA role "checkbox" must have the following attributes defined: "aria-checked" -->
<span role="checkbox" aria-labelledby="foo" tabindex="0"></span>
```

### a11y\_role\_supports\_aria\_props[](#a11y_role_supports_aria_props)

```
The attribute '%attribute%' is not supported by the role '%role%'
```

Elements with explicit or implicit roles defined contain only `aria-*` properties supported by that role.

```
<!-- A11y: The attribute 'aria-multiline' is not supported by the role 'link'. -->
<div role="link" aria-multiline></div>

<!-- A11y: The attribute 'aria-required' is not supported by the role 'listitem'. This role is implicit on the element <li>. -->
<li aria-required></li>
```

### a11y\_role\_supports\_aria\_props\_implicit[](#a11y_role_supports_aria_props_implicit)

```
The attribute '%attribute%' is not supported by the role '%role%'. This role is implicit on the element `<%name%>`
```

Elements with explicit or implicit roles defined contain only `aria-*` properties supported by that role.

```
<!-- A11y: The attribute 'aria-multiline' is not supported by the role 'link'. -->
<div role="link" aria-multiline></div>

<!-- A11y: The attribute 'aria-required' is not supported by the role 'listitem'. This role is implicit on the element <li>. -->
<li aria-required></li>
```

### a11y\_unknown\_aria\_attribute[](#a11y_unknown_aria_attribute)

```
Unknown aria attribute 'aria-%attribute%'
```

```
Unknown aria attribute 'aria-%attribute%'. Did you mean '%suggestion%'?
```

Enforce that only known ARIA attributes are used. This is based on the [WAI-ARIA States and Properties spec](https://www.w3.org/WAI/PF/aria-1.1/states_and_properties).

```
<!-- A11y: Unknown aria attribute 'aria-labeledby' (did you mean 'labelledby'?) -->
<input type="image" aria-labeledby="foo" />
```

### a11y\_unknown\_role[](#a11y_unknown_role)

```
Unknown role '%role%'
```

```
Unknown role '%role%'. Did you mean '%suggestion%'?
```

Elements with ARIA roles must use a valid, non-abstract ARIA role. A reference to role definitions can be found at [WAI-ARIA](https://www.w3.org/TR/wai-aria/#role_definitions) site.

```
<!-- A11y: Unknown role 'toooltip' (did you mean 'tooltip'?) -->
<div role="toooltip"></div>
```

### attribute\_avoid\_is[](#attribute_avoid_is)

```
The "is" attribute is not supported cross-browser and should be avoided
```

### attribute\_global\_event\_reference[](#attribute_global_event_reference)

```
You are referencing `globalThis.%name%`. Did you forget to declare a variable with that name?
```

### attribute\_illegal\_colon[](#attribute_illegal_colon)

```
Attributes should not contain ':' characters to prevent ambiguity with Svelte directives
```

### attribute\_invalid\_property\_name[](#attribute_invalid_property_name)

```
'%wrong%' is not a valid HTML attribute. Did you mean '%right%'?
```

### attribute\_quoted[](#attribute_quoted)

```
Quoted attributes on components and custom elements will be stringified in a future version of Svelte. If this isn't what you want, remove the quotes
```

### bidirectional\_control\_characters[](#bidirectional_control_characters)

```
A bidirectional control character was detected in your code. These characters can be used to alter the visual direction of your code and could have unintended consequences
```

Bidirectional control characters can alter the direction in which text appears to be in. For example, via control characters, you can make `defabc` look like `abcdef`. As a result, if you were to unknowingly copy and paste some code that has these control characters, they may alter the behavior of your code in ways you did not intend. See [trojansource.codes](https://trojansource.codes/) for more information.

### bind\_invalid\_each\_rest[](#bind_invalid_each_rest)

```
The rest operator (...) will create a new object and binding '%name%' with the original object will not work
```

### block\_empty[](#block_empty)

```
Empty block
```

### component\_name\_lowercase[](#component_name_lowercase)

```
`<%name%>` will be treated as an HTML element unless it begins with a capital letter
```

### css\_unused\_selector[](#css_unused_selector)

```
Unused CSS selector "%name%"
```

Svelte traverses both the template and the `<style>` tag to find out which of the CSS selectors are not used within the template, so it can remove them.

In some situations a selector may target an element that is not ‘visible’ to the compiler, for example because it is part of an `{@html ...}` tag or you’re overriding styles in a child component. In these cases, use [`:global`](/docs/svelte/global-styles) to preserve the selector as-is:

```
<div class="post">{@html content}</div>

<style>
  .post :global {
	p {...}
  }
</style>
```

### custom\_element\_props\_identifier[](#custom_element_props_identifier)

```
Using a rest element or a non-destructured declaration with `$props()` means that Svelte can't infer what properties to expose when creating a custom element. Consider destructuring all the props or explicitly specifying the `customElement.props` option.
```

### element\_implicitly\_closed[](#element_implicitly_closed)

```
This element is implicitly closed by the following `%tag%`, which can cause an unexpected DOM structure. Add an explicit `%closing%` to avoid surprises.
```

In HTML, some elements are implicitly closed by another element. For example, you cannot nest a `<p>` inside another `<p>`:

```
<!-- this HTML... -->
<p><p>hello</p>

<!-- results in this DOM structure -->
<p></p>
<p>hello</p>
```

Similarly, a parent element’s closing tag will implicitly close all child elements, even if the `</` was a typo and you meant to create a *new* element. To avoid ambiguity, it’s always a good idea to have an explicit closing tag.

### element\_invalid\_self\_closing\_tag[](#element_invalid_self_closing_tag)

```
Self-closing HTML tags for non-void elements are ambiguous — use `<%name% ...></%name%>` rather than `<%name% ... />`
```

In HTML, there’s [no such thing as a self-closing tag](https://jakearchibald.com/2023/against-self-closing-tags-in-html/). While this *looks* like a self-contained element with some text next to it...

```
<div>
	<span class="icon" /> some text!
</div>
```

...a spec-compliant HTML parser (such as a browser) will in fact parse it like this, with the text *inside* the icon:

```
<div>
	<span class="icon"> some text! </span>
</div>
```

Some templating languages (including Svelte) will ‘fix’ HTML by turning `<span />` into `<span></span>`. Others adhere to the spec. Both result in ambiguity and confusion when copy-pasting code between different contexts, so Svelte prompts you to resolve the ambiguity directly by having an explicit closing tag.

To automate this, run the dedicated migration:

```
npx sv migrate self-closing-tags
```

In a future version of Svelte, self-closing tags may be upgraded from a warning to an error.

### event\_directive\_deprecated[](#event_directive_deprecated)

```
Using `on:%name%` to listen to the %name% event is deprecated. Use the event attribute `on%name%` instead
```

See [the migration guide](v5-migration-guide#Event-changes) for more info.

### export\_let\_unused[](#export_let_unused)

```
Component has unused export property '%name%'. If it is for external reference only, please consider using `export const %name%`
```

### legacy\_code[](#legacy_code)

```
`%code%` is no longer valid — please use `%suggestion%` instead
```

### legacy\_component\_creation[](#legacy_component_creation)

```
Svelte 5 components are no longer classes. Instantiate them using `mount` or `hydrate` (imported from 'svelte') instead.
```

See the [migration guide](v5-migration-guide#Components-are-no-longer-classes) for more info.

### node\_invalid\_placement\_ssr[](#node_invalid_placement_ssr)

```
%message%. When rendering this component on the server, the resulting HTML will be modified by the browser (by moving, removing, or inserting elements), likely resulting in a `hydration_mismatch` warning
```

HTML restricts where certain elements can appear. In case of a violation the browser will ‘repair’ the HTML in a way that breaks Svelte’s assumptions about the structure of your components. Some examples:

* `<p>hello <div>world</div></p>` will result in `<p>hello </p><div>world</div><p></p>` (the `<div>` autoclosed the `<p>` because `<p>` cannot contain block-level elements)
* `<option><div>option a</div></option>` will result in `<option>option a</option>` (the `<div>` is removed)
* `<table><tr><td>cell</td></tr></table>` will result in `<table><tbody><tr><td>cell</td></tr></tbody></table>` (a `<tbody>` is auto-inserted)

This code will work when the component is rendered on the client (which is why this is a warning rather than an error), but if you use server rendering it will cause hydration to fail.

### non\_reactive\_update[](#non_reactive_update)

```
`%name%` is updated, but is not declared with `$state(...)`. Changing its value will not correctly trigger updates
```

This warning is thrown when the compiler detects the following:

* a variable was declared without `$state` or `$state.raw`
* the variable is reassigned
* the variable is read in a reactive context

In this case, changing the value will not correctly trigger updates. Example:

```
<script>
	let reactive = $state('reactive');
	let stale = 'stale';
</script>

<p>This value updates: {reactive}</p>
<p>This value does not update: {stale}</p>

<button onclick={() => {
	stale = 'updated';
	reactive = 'updated';
}}>update</button>
```

To fix this, wrap your variable declaration with `$state`.

### options\_deprecated\_accessors[](#options_deprecated_accessors)

```
The `accessors` option has been deprecated. It will have no effect in runes mode
```

### options\_deprecated\_immutable[](#options_deprecated_immutable)

```
The `immutable` option has been deprecated. It will have no effect in runes mode
```

### options\_missing\_custom\_element[](#options_missing_custom_element)

```
The `customElement` option is used when generating a custom element. Did you forget the `customElement: true` compile option?
```

### options\_removed\_enable\_sourcemap[](#options_removed_enable_sourcemap)

```
The `enableSourcemap` option has been removed. Source maps are always generated now, and tooling can choose to ignore them
```

### options\_removed\_hydratable[](#options_removed_hydratable)

```
The `hydratable` option has been removed. Svelte components are always hydratable now
```

### options\_removed\_loop\_guard\_timeout[](#options_removed_loop_guard_timeout)

```
The `loopGuardTimeout` option has been removed
```

### options\_renamed\_ssr\_dom[](#options_renamed_ssr_dom)

```
`generate: "dom"` and `generate: "ssr"` options have been renamed to "client" and "server" respectively
```

### perf\_avoid\_inline\_class[](#perf_avoid_inline_class)

```
Avoid 'new class' — instead, declare the class at the top level scope
```

### perf\_avoid\_nested\_class[](#perf_avoid_nested_class)

```
Avoid declaring classes below the top level scope
```

### reactive\_declaration\_invalid\_placement[](#reactive_declaration_invalid_placement)

```
Reactive declarations only exist at the top level of the instance script
```

### reactive\_declaration\_module\_script\_dependency[](#reactive_declaration_module_script_dependency)

```
Reassignments of module-level declarations will not cause reactive statements to update
```

### script\_context\_deprecated[](#script_context_deprecated)

```
`context="module"` is deprecated, use the `module` attribute instead
```

```
<script context="module" module>
	let foo = 'bar';
</script>
```

### script\_unknown\_attribute[](#script_unknown_attribute)

```
Unrecognised attribute — should be one of `generics`, `lang` or `module`. If this exists for a preprocessor, ensure that the preprocessor removes it
```

### slot\_element\_deprecated[](#slot_element_deprecated)

```
Using `<slot>` to render parent content is deprecated. Use `{@render ...}` tags instead
```

See [the migration guide](v5-migration-guide#Snippets-instead-of-slots) for more info.

### state\_referenced\_locally[](#state_referenced_locally)

```
This reference only captures the initial value of `%name%`. Did you mean to reference it inside a %type% instead?
```

This warning is thrown when the compiler detects the following:

* A reactive variable is declared
* ...and later reassigned...
* ...and referenced in the same scope

This ‘breaks the link’ to the original state declaration. For example, if you pass the state to a function, the function loses access to the state once it is reassigned:

Parent

```
<script>
	import { setContext } from 'svelte';

	let count = $state(0);

	// warning: state_referenced_locally
	setContext('count', count);
</script>

<button onclick={() => count++}>
	increment
</button>
```

```
<script lang="ts">
	import { setContext } from 'svelte';

	let count = $state(0);

	// warning: state_referenced_locally
	setContext('count', count);
</script>

<button onclick={() => count++}>
	increment
</button>
```

Child

```
<script>
	import { getContext } from 'svelte';

	const count = getContext('count');
</script>

<!-- This will never update -->
<p>The count is {count}</p>
```

```
<script lang="ts">
	import { getContext } from 'svelte';

	const count = getContext('count');
</script>

<!-- This will never update -->
<p>The count is {count}</p>
```

To fix this, reference the variable such that it is lazily evaluated. For the above example, this can be achieved by wrapping `count` in a function:

Parent

```
<script>
	import { setContext } from 'svelte';

	let count = $state(0);
	setContext('count', () => count);
</script>

<button onclick={() => count++}>
	increment
</button>
```

```
<script lang="ts">
	import { setContext } from 'svelte';

	let count = $state(0);
	setContext('count', () => count);
</script>

<button onclick={() => count++}>
	increment
</button>
```

Child

```
<script>
	import { getContext } from 'svelte';

	const count = getContext('count');
</script>

<!-- This will update -->
<p>The count is {count()}</p>
```

```
<script lang="ts">
	import { getContext } from 'svelte';

	const count = getContext('count');
</script>

<!-- This will update -->
<p>The count is {count()}</p>
```

For more info, see [Passing state into functions]($state#Passing-state-into-functions).

### store\_rune\_conflict[](#store_rune_conflict)

```
It looks like you're using the `$%name%` rune, but there is a local binding called `%name%`. Referencing a local variable with a `$` prefix will create a store subscription. Please rename `%name%` to avoid the ambiguity
```

### svelte\_component\_deprecated[](#svelte_component_deprecated)

```
`<svelte:component>` is deprecated in runes mode — components are dynamic by default
```

In previous versions of Svelte, the component constructor was fixed when the component was rendered. In other words, if you wanted `<X>` to re-render when `X` changed, you would either have to use `<svelte:component this={X}>` or put the component inside a `{#key X}...{/key}` block.

In Svelte 5 this is no longer true — if `X` changes, `<X>` re-renders.

In some cases `<object.property>` syntax can be used as a replacement; a lowercased variable with property access is recognized as a component in Svelte 5.

For complex component resolution logic, an intermediary, capitalized variable may be necessary. E.g. in places where `@const` can be used:

```
{#each items as item}
	<svelte:component this={item.condition ? Y : Z} />
	{@const Component = item.condition ? Y : Z}
	<Component />
{/each}
```

A derived value may be used in other contexts:

```
<script>
	// ...
	let condition = $state(false);
	const Component = $derived(condition ? Y : Z);
</script>

<svelte:component this={condition ? Y : Z} />
<Component />
```

### svelte\_element\_invalid\_this[](#svelte_element_invalid_this)

```
`this` should be an `{expression}`. Using a string attribute value will cause an error in future versions of Svelte
```

### svelte\_self\_deprecated[](#svelte_self_deprecated)

```
`<svelte:self>` is deprecated — use self-imports (e.g. `import %name% from './%basename%'`) instead
```

See [the note in the docs](legacy-svelte-self) for more info.

### unknown\_code[](#unknown_code)

```
`%code%` is not a recognised code
```

```
`%code%` is not a recognised code (did you mean `%suggestion%`?)
```

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/98-reference/30-compiler-warnings.md) [llms.txt](/docs/svelte/compiler-warnings/llms.txt)

previous next

[Compiler errors](/docs/svelte/compiler-errors) [Runtime errors](/docs/svelte/runtime-errors)

----
url: https://svelte.dev/docs/svelte/legacy-overview/llms.txt
----

```
Svelte 5 introduced some significant changes to Svelte's API, including [runes](what-are-runes), [snippets](snippet) and event attributes. As a result, some Svelte 3/4 features are deprecated (though supported for now, unless otherwise specified) and will eventually be removed. We recommend that you incrementally [migrate your existing code](v5-migration-guide).

The following pages document these features for

- people still using Svelte 3/4
- people using Svelte 5, but with components that haven't yet been migrated

Since Svelte 3/4 syntax still works in Svelte 5, we will distinguish between _legacy mode_ and _runes mode_. Once a component is in runes mode (which you can opt into by using runes, or by explicitly setting the `runes: true` compiler option), legacy mode features are no longer available.

If you're exclusively interested in the Svelte 3/4 syntax, you can browse its documentation at [v4.svelte.dev](https://v4.svelte.dev).
```

----
url: https://svelte.dev/docs/svelte/svelte-body/llms.txt
----

````
```svelte
<svelte:body onevent={handler} />
```

Similarly to `<svelte:window>`, this element allows you to add listeners to events on `document.body`, such as `mouseenter` and `mouseleave`, which don't fire on `window`. It also lets you use [actions](use) on the `<body>` element.

As with `<svelte:window>` and `<svelte:document>`, this element may only appear at the top level of your component and must never be inside a block or element.

```svelte
<svelte:body onmouseenter={handleMouseenter} onmouseleave={handleMouseleave} use:someAction />
```
````

----
url: https://svelte.dev/docs/svelte/class
----

[Skip to main content](#main)

There are two ways to set classes on elements: the `class` attribute, and the `class:` directive.

## Attributes[](#Attributes)

Primitive values are treated like any other attribute:

```
<div class={large ? 'large' : 'small'}>...</div>
```

> For historical reasons, falsy values (like `false` and `NaN`) are stringified (`class="false"`), though `class={undefined}` (or `null`) cause the attribute to be omitted altogether. In a future version of Svelte, all falsy values will cause `class` to be omitted.

### Objects and arrays[](#Attributes-Objects-and-arrays)

Since Svelte 5.16, `class` can be an object or array, and is converted to a string using [clsx](https://github.com/lukeed/clsx).

If the value is an object, the truthy keys are added:

```
<script>
	let { cool } = $props();
</script>

<!-- results in `class="cool"` if `cool` is truthy,
	 `class="lame"` otherwise -->
<div class={{ cool, lame: !cool }}>...</div>
```

If the value is an array, the truthy values are combined:

```
<!-- if `faded` and `large` are both truthy, results in
	 `class="saturate-0 opacity-50 scale-200"` -->
<div class={[faded && 'saturate-0 opacity-50', large && 'scale-200']}>...</div>
```

Note that whether we’re using the array or object form, we can set multiple classes simultaneously with a single condition, which is particularly useful if you’re using things like Tailwind.

Arrays can contain arrays and objects, and clsx will flatten them. This is useful for combining local classes with props, for example:

Button

```
<script>
	let props = $props();
</script>

<button {...props} class={['cool-button', props.class]}>
	{@render props.children?.()}
</button>
```

```
<script lang="ts">
	let props = $props();
</script>

<button {...props} class={['cool-button', props.class]}>
	{@render props.children?.()}
</button>
```

The user of this component has the same flexibility to use a mixture of objects, arrays and strings:

App

```
<script>
	import Button from './Button.svelte';
	let useTailwind = $state(false);
</script>

<Button
	onclick={() => useTailwind = true}
	class={{ 'bg-blue-700 sm:w-1/2': useTailwind }}
>
	Accept the inevitability of Tailwind
</Button>
```

```
<script lang="ts">
	import Button from './Button.svelte';
	let useTailwind = $state(false);
</script>

<Button
	onclick={() => useTailwind = true}
	class={{ 'bg-blue-700 sm:w-1/2': useTailwind }}
>
	Accept the inevitability of Tailwind
</Button>
```

Since Svelte 5.19, Svelte also exposes the `ClassValue` type, which is the type of value that the `class` attribute on elements accept. This is useful if you want to use a type-safe class name in component props:

```
<script lang="ts">
	import type { ClassValue } from 'svelte/elements';

	const props: { class: ClassValue } = $props();
</script>

<div class={['original', props.class]}>...</div>
```

## The class: directive[](#The-class:-directive)

Prior to Svelte 5.16, the `class:` directive was the most convenient way to set classes on elements conditionally.

```
<!-- These are equivalent -->
<div class={{ cool, lame: !cool }}>...</div>
<div class:cool={cool} class:lame={!cool}>...</div>
```

As with other directives, we can use a shorthand when the name of the class coincides with the value:

```
<div class:cool class:lame={!cool}>...</div>
```

> Unless you’re using an older version of Svelte, consider avoiding `class:`, since the attribute is more powerful and composable.

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/03-template-syntax/18-class.md) [llms.txt](/docs/svelte/class/llms.txt)

previous next

[style:](/docs/svelte/style) [await](/docs/svelte/await-expressions)

----
url: https://svelte.dev/docs/svelte/declaration-tags/llms.txt
----

````
Declaration tags define local variables inside markup with `const` or `let`:

<!-- codeblock:start {"title":"Declaration tags"} -->
```svelte
<!--- file: App.svelte --->
<script>
	let boxes = [{ width: 10, height: 10 }, { width: 15, height: 15 }];
</script>

{#each boxes as box}
	{const area = box.width * box.height}
	{const label = `${box.width} × ${box.height} = ${area}`}

	<p>{label}</p>
{/each}
```
<!-- codeblock:end -->

> [!NOTE] Declaration tags are available since Svelte 5.56.

> [!NOTE] The [`{@const ...}`](@const) syntax is considered legacy — use declaration tags instead.

When values should be reactive, you can use `$state` and `$derived`:

<!-- codeblock:start {"title":"Reactive declaration tags"} -->
```svelte
<!--- file: App.svelte --->
<script>
	let user = $state({ name: 'Svelte' });
	let editing = $state(false);
</script>

<p>Hello {user.name}</p>
<button onclick={() => editing = true}>edit name</button>

{#if editing}
	{let name = $state(user.name)}
	{const greeting = $derived(`Hello ${name}`)}

	<hr>
	<input bind:value={name} />
	<p>{greeting}</p>

	<button onclick={() => {
		user.name = name;
		editing = false;
	}}>save</button>
{/if}
```
<!-- codeblock:end -->

Declaration tags can be used anywhere inside the component. They can reference values declared outside themselves (for example in the `<script>` tag or in `{#each ...}` blocks) and are 'visible' to everything in the same lexical scope (i.e. siblings, and children of those siblings):

<!-- codeblock:start {"title":"Declaration tag scope"} -->
```svelte
<!--- file: App.svelte --->
{const hello = 'hello'}
{hello} <!-- 'hello' -->
<div>
	{const hello = 'hi'}
	{hello} <!-- 'hi' -->
	<div>
		{hello} <!-- 'hi' -->
	</div>
</div>
{hello} <!-- 'hello' -->
```
<!-- codeblock:end -->
````

----
url: https://svelte.dev/docs/svelte/legacy-slots/llms.txt
----

````
In Svelte 5, content can be passed to components in the form of [snippets](snippet) and rendered using [render tags](@render).

In legacy mode, content inside component tags is considered _slotted content_, which can be rendered by the component using a `<slot>` element:

```svelte
<!--- file: App.svelte --->
<script>
	import Modal from './Modal.svelte';
</script>

<Modal>This is some slotted content</Modal>
```

```svelte
<!--- file: Modal.svelte --->
<div class="modal">
	<slot></slot>
</div>
```

> [!NOTE] If you want to render a regular `<slot>` element, you can use `<svelte:element this={'slot'} />`.

## Named slots

A component can have _named_ slots in addition to the default slot. On the parent side, add a `slot="..."` attribute to an element, component or [`<svelte:fragment>`](legacy-svelte-fragment) directly inside the component tags.

```svelte
<!--- file: App.svelte --->
<script>
	import Modal from './Modal.svelte';

	let open = true;
</script>

{#if open}
	<Modal>
		This is some slotted content

		+++<div slot="buttons">+++
			<button on:click={() => open = false}>
				close
			</button>
		+++</div>+++
	</Modal>
{/if}
```

On the child side, add a corresponding `<slot name="...">` element:

```svelte
<!--- file: Modal.svelte --->
<div class="modal">
	<slot></slot>
	<hr>
	+++<slot name="buttons"></slot>+++
</div>
```

## Fallback content

If no slotted content is provided, a component can define fallback content by putting it inside the `<slot>` element:

```svelte
<slot>
	This will be rendered if no slotted content is provided
</slot>
```

## Passing data to slotted content

Slots can be rendered zero or more times and can pass values _back_ to the parent using props. The parent exposes the values to the slot template using the `let:` directive.

```svelte
<!--- file: FancyList.svelte --->
<ul>
	{#each items as data}
		<li class="fancy">
			<!-- 'item' here... -->
			<slot item={process(data)} />
		</li>
	{/each}
</ul>
```

```svelte
<!--- file: App.svelte --->
<!-- ...corresponds to 'item' here: -->
<FancyList {items} let:item={processed}>
	<div>{processed.text}</div>
</FancyList>
```

The usual shorthand rules apply — `let:item` is equivalent to `let:item={item}`, and `<slot {item}>` is equivalent to `<slot item={item}>`.

Named slots can also expose values. The `let:` directive goes on the element with the `slot` attribute.

```svelte
<!--- file: FancyList.svelte --->
<ul>
	{#each items as item}
		<li class="fancy">
			<slot name="item" item={process(data)} />
		</li>
	{/each}
</ul>

<slot name="footer" />
```

```svelte
<!--- file: App.svelte --->
<FancyList {items}>
	<div slot="item" let:item>{item.text}</div>
	<p slot="footer">Copyright (c) 2019 Svelte Industries</p>
</FancyList>
```
````

----
url: https://svelte.dev/docs/svelte/each/llms.txt
----

````
```svelte
<!--- copy: false  --->
{#each expression as name}...{/each}
```

```svelte
<!--- copy: false  --->
{#each expression as name, index}...{/each}
```

Iterating over values can be done with an each block. The values in question can be arrays, array-like objects (i.e. anything with a `length` property), or iterables like `Map` and `Set`. (Internally, they are converted to arrays with [`Array.from`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from).)

If the value is `null` or `undefined`, it is treated the same as an empty array (which will cause [else blocks](#Else-blocks) to be rendered, where applicable).

```svelte
<h1>Shopping list</h1>
<ul>
	{#each items as item}
		<li>{item.name} x {item.qty}</li>
	{/each}
</ul>
```

An each block can also specify an _index_, equivalent to the second argument in an `array.map(...)` callback:

```svelte
{#each items as item, i}
	<li>{i + 1}: {item.name} x {item.qty}</li>
{/each}
```

## Keyed each blocks

```svelte
<!--- copy: false  --->
{#each expression as name (key)}...{/each}
```

```svelte
<!--- copy: false  --->
{#each expression as name, index (key)}...{/each}
```

If a _key_ expression is provided — which must uniquely identify each list item — Svelte will use it to intelligently update the list when data changes by inserting, moving and deleting items, rather than adding or removing items at the end and updating the state in the middle.

The key can be any object, but strings and numbers are recommended since they allow identity to persist when the objects themselves change.

```svelte
{#each items as item (item.id)}
	<li>{item.name} x {item.qty}</li>
{/each}

<!-- or with additional index value -->
{#each items as item, i (item.id)}
	<li>{i + 1}: {item.name} x {item.qty}</li>
{/each}
```

You can freely use destructuring and rest patterns in each blocks.

```svelte
{#each items as { id, name, qty }, i (id)}
	<li>{i + 1}: {name} x {qty}</li>
{/each}

{#each objects as { id, ...rest }}
	<li><span>{id}</span><MyComponent {...rest} /></li>
{/each}

{#each items as [id, ...rest]}
	<li><span>{id}</span><MyComponent values={rest} /></li>
{/each}
```

## Each blocks without an item

```svelte
<!--- copy: false  --->
{#each expression}...{/each}
```

```svelte
<!--- copy: false  --->
{#each expression, index}...{/each}
```

In case you just want to render something `n` times, you can omit the `as` part:

<!-- codeblock:start {"title":"Chess board"} -->
```svelte
<!--- file: App.svelte --->
<div class="chess-board">
	{#each { length: 8 }, rank}
		{#each { length: 8 }, file}
			<div class:black={(rank + file) % 2 === 1}></div>
		{/each}
	{/each}
</div>

<style>
	.chess-board {
		display: grid;
		grid-template-columns: repeat(8, 1fr);
		grid-template-rows: repeat(8, 1fr);
		border: 1px solid black;
		aspect-ratio: 1;

		.black {
			background: black;
		}
	}
</style>
```
<!-- codeblock:end -->

## Else blocks

```svelte
<!--- copy: false  --->
{#each expression as name}...{:else}...{/each}
```

An each block can also have an `{:else}` clause, which is rendered if the list is empty.

```svelte
{#each todos as todo}
	<p>{todo.text}</p>
{:else}
	<p>No tasks today!</p>
{/each}
```
````

----
url: https://svelte.dev/docs/svelte/$effect
----

[Skip to main content](#main)

Effects are functions that run when state updates, and can be used for things like calling third-party libraries, drawing on `<canvas>` elements, or making network requests. They only run in the browser, not during server-side rendering.

Generally speaking, you should *not* update state inside effects, as it will make code more convoluted and will often lead to never-ending update cycles. If you find yourself doing so, see [when not to use `$effect`](#When-not-to-use-$effect) to learn about alternative approaches.

You can create an effect with the `$effect` rune ([demo](/playground/untitled#H4sIAAAAAAAAE31S246bMBD9lZF3pSRSAqTVvrCAVPUP2sdSKY4ZwJJjkD0hSVH-vbINuWxXfQH5zMyZc2ZmZLVUaFn6a2R06ZGlHmBrpvnBvb71fWQHVOSwPbf4GS46TajJspRlVhjZU1HqkhQSWPkHIYdXS5xw-Zas3ueI6FRn7qHFS11_xSRZhIxbFtcDtw7SJb1iXaOg5XIFeQGjzyPRaevYNOGZIJ8qogbpe8CWiy_VzEpTXiQUcvPDkSVrSNZz1UlW1N5eLcqmpdXUvaQ4BmqlhZNUCgxuzFHDqUWNAxrYeUM76AzsnOsdiJbrBp_71lKpn3RRbii-4P3f-IMsRxS-wcDV_bL4PmSdBa2wl7pKnbp8DMgVvJm8ZNskKRkEM_OzyOKQFkgqOYBQ3Nq89Ns0nbIl81vMFN-jKoLMTOr-SOBOJS-Z8f5Y6D1wdcR8dFqvEBdetK-PHwj-z-cH8oHPY54wRJ8Ys7iSQ3Bg3VA9azQbmC9k35kKzYa6PoVtfwbbKVnBixBiGn7Pq0rqJoUtHiCZwAM3jdTPWCVtr_glhVrhecIa3vuksJ_b7TqFs4DPyriSjd5IwoNNQaAmNI-ESfR2p8zimzvN1swdCkvJHPH6-_oX8o1SgcIDAAA=)):

```
<script>
	let size = $state(50);
	let color = $state('#ff3e00');

	let canvas;

	$effect(() => {
		const context = canvas.getContext('2d');
		context.clearRect(0, 0, canvas.width, canvas.height);

		// this will re-run whenever `color` or `size` change
		context.fillStyle = color;
		context.fillRect(0, 0, size, size);
	});
</script>

<canvas bind:this={canvas} width="100" height="100"></canvas>
```

When Svelte runs an effect function, it tracks which pieces of state (and derived state) are accessed (unless accessed inside [`untrack`](svelte#untrack)), and re-runs the function when that state later changes.

> If you’re having difficulty understanding why your `$effect` is rerunning or is not running see [understanding dependencies](#Understanding-dependencies). Effects are triggered differently than the `$:` blocks you may be used to if coming from Svelte 4.

### Understanding lifecycle[](#Understanding-lifecycle)

Your effects run after the component has been mounted to the DOM, and in a [microtask](https://developer.mozilla.org/en-US/docs/Web/API/HTML_DOM_API/Microtask_guide) after state changes. Re-runs are batched (i.e. changing `color` and `size` in the same moment won’t cause two separate runs), and happen after any DOM updates have been applied.

You can use `$effect` anywhere, not just at the top level of a component, as long as it is called while a parent effect is running.

> Svelte uses effects internally to represent logic and expressions in your template — this is how `<h1>hello {name}!</h1>` updates when `name` changes.

An effect can return a *teardown function* which will run immediately before the effect re-runs:

[Open in playground](/playground/untitled#H4sIAAAAAAAAA41Swa6bMBD8lZX1DqGlJemRB5F66KH33kqlZ8xQrDprZC-hEeLfK-AlL6l66Mna3Rnv7OxOivUJKldf2hZGSKBD40dWqWqtQ1T590nVOuIV9rnvP8YznEClyngWsESVqyKaYHs5VlyJg5DxAwuV9BRFC3b75PlaOVnnbITx3MQ3wGG_3zBcyRNWLbtdQuWRpiVVSZbRt85GGq1zVIMCTIAWNDR2YJwR6OX-6xcyneafiBvdeI5ClgXhrB2VFCFfX6PHRgt20f6-pMPzlprTB9VXnZUEyBCY_uJnGdmW9M1Lagc2Yj2TjdQHf7YNmpSsbMOEge-YOiF7OqGxWuAuVKP1ASQdaHOFAj6EgeMdpU5WD1aQ8afeM1iWXg2iBH9Bc5vMQYfb2Fc3kuuY6zsvYZG97ZOL7nCcVlPmIusOW64eRDyTZ-Os-VVOmwe7h-2-K-lTMh-j8yNCkW2U43-Ss43c6ih3ZJWqf12i4LeoXMKAVMmlX-rL-ar5R6pEWzdablTeahcx_wH9Im6v8wIAAA)

```
<script>
	let count = $state(0);
	let milliseconds = $state(1000);

	$effect(() => {
		// This will be recreated whenever `milliseconds` changes
		const interval = setInterval(() => {
			count += 1;
		}, milliseconds);

		return () => {
			// if a teardown function is provided, it will run
			// a) immediately before the effect re-runs
			// b) when the component is destroyed
			clearInterval(interval);
		};
	});
</script>

<h1>{count}</h1>

<button onclick={() => (milliseconds *= 2)}>slower</button>
<button onclick={() => (milliseconds /= 2)}>faster</button>
```

```
<script lang="ts">
	let count = $state(0);
	let milliseconds = $state(1000);

	$effect(() => {
		// This will be recreated whenever `milliseconds` changes
		const interval = setInterval(() => {
			count += 1;
		}, milliseconds);

		return () => {
			// if a teardown function is provided, it will run
			// a) immediately before the effect re-runs
			// b) when the component is destroyed
			clearInterval(interval);
		};
	});
</script>

<h1>{count}</h1>

<button onclick={() => (milliseconds *= 2)}>slower</button>
<button onclick={() => (milliseconds /= 2)}>faster</button>
```

Teardown functions also run when the effect is destroyed, which happens when its parent is destroyed (for example, a component is unmounted) or the parent effect re-runs.

### Understanding dependencies[](#Understanding-dependencies)

`$effect` automatically picks up any reactive values (`$state`, `$derived`, `$props`) that are *synchronously* read inside its function body (including indirectly, via function calls) and registers them as dependencies. When those dependencies change, the `$effect` schedules a re-run.

If `$state` and `$derived` are used directly inside the `$effect` (for example, during creation of a [reactive class](/docs/svelte/$state#Classes)), those values will *not* be treated as dependencies.

Values that are read *asynchronously* — after an `await` or inside a `setTimeout`, for example — will not be tracked. Here, the canvas will be repainted when `color` changes, but not when `size` changes ([demo](/playground/untitled#H4sIAAAAAAAAE31T246bMBD9lZF3pWSlBEirfaEQqdo_2PatVIpjBrDkGGQPJGnEv1e2IZfVal-wfHzmzJyZ4cIqqdCy9M-F0blDlnqArZjmB3f72XWRHVCRw_bc4me4aDWhJstSlllhZEfbQhekkMDKfwg5PFvihMvX5OXH_CJa1Zrb0-Kpqr5jkiwC48rieuDWQbqgZ6wqFLRcvkC-hYvnkWi1dWqa8ESQTxFRjfQWsOXiWzmr0sSLhEJu3p1YsoJkNUcdZUnN9dagrBu6FVRQHAM10sJRKgUG16bXcGxQ44AGdt7SDkTDdY02iqLHnJVU6hedlWuIp94JW6Tf8oBt_8GdTxlF0b4n0C35ZLBzXb3mmYn3ae6cOW74zj0YVzDNYXRHFt9mprNgHfZSl6mzml8CMoLvTV6wTZIUDEJv5us2iwMtiJRyAKG4tXnhl8O0yhbML0Wm-B7VNlSSSd31BG7z8oIZZ6dgIffAVY_5xdU9Qrz1Bnx8fCfwtZ7v8Qc9j3nB8PqgmMWlHIID6-bkVaPZwDySfWtKNGtquxQ23Qlsq2QJT0KIqb8dL0up6xQ2eIBkAg_c1FI_YqW0neLnFCqFpwmreedJYT7XX8FVOBfwWRhXstZrSXiwKQjUhOZeMIleb5JZfHWn2Yq5pWEpmR7Hv-N_wEqT8hEEAAA=)):

```
$effectfunction $effect(fn: () => void | (() => void)): void
namespace $effect

Runs code when a component is mounted to the DOM, and then whenever its dependencies change, i.e. $state or $derived values.
The timing of the execution is after the DOM has been updated.




Example:



$effect(() => console.log('The count is now ' + count));

If you return a function from the effect, it will be called right before the effect is run again, or when the component is unmounted.




Does not run during server-side rendering.




{@link https://svelte.dev/docs/svelte/$effect Documentation}


fn 

The function to execute


(() => {
	const contextconst context: CanvasRenderingContext2D = canvaslet canvas: {
    width: number;
    height: number;
    getContext(type: "2d", options?: CanvasRenderingContext2DSettings): CanvasRenderingContext2D;
}.getContext(method) getContext(type: "2d", options?: CanvasRenderingContext2DSettings): CanvasRenderingContext2D('2d');
	contextconst context: CanvasRenderingContext2D.clearRect(method) CanvasRect.clearRect(x: number, y: number, w: number, h: number): void

MDN Reference


(0, 0, canvaslet canvas: {
    width: number;
    height: number;
    getContext(type: "2d", options?: CanvasRenderingContext2DSettings): CanvasRenderingContext2D;
}.width(property) width: number, canvaslet canvas: {
    width: number;
    height: number;
    getContext(type: "2d", options?: CanvasRenderingContext2DSettings): CanvasRenderingContext2D;
}.height(property) height: number);

	// this will re-run whenever `color` changes...
	contextconst context: CanvasRenderingContext2D.fillStyle(property) CanvasFillStrokeStyles.fillStyle: string | CanvasGradient | CanvasPattern

MDN Reference


 = colorlet color: string;

	setTimeoutfunction setTimeout<[]>(callback: () => void, delay?: number): NodeJS.Timeout (+3 overloads)
namespace setTimeout

MDN Reference


(() => {
		// ...but not when `size` changes
		contextconst context: CanvasRenderingContext2D.fillRect(method) CanvasRect.fillRect(x: number, y: number, w: number, h: number): void

MDN Reference


(0, 0, sizelet size: number, sizelet size: number);
	}, 0);
});
```

An effect only reruns when the object it reads changes, not when a property inside it changes. (If you want to observe changes *inside* an object at dev time, you can use [`$inspect`]($inspect).)

```
<script>
	let state = $state({ value: 0 });
	let derived = $derived({ value: state.value * 2 });

	// this will run once, because `state` is never reassigned (only mutated)
	$effect(() => {
		state;
	});

	// this will run whenever `state.value` changes...
	$effect(() => {
		state.value;
	});

	// ...and so will this, because `derived` is a new object each time
	$effect(() => {
		derived;
	});
</script>

<button onclick={() => (state.value += 1)}>
	{state.value}
</button>

<p>{state.value} doubled is {derived.value}</p>
```

An effect only depends on the values that it read the last time it ran. This has interesting implications for effects that have conditional code.

For instance, if `condition` is `true` in the code snippet below, the code inside the `if` block will run and `color` will be evaluated. This means that changes to either `condition` or `color` [will cause the effect to re-run](/playground/untitled#H4sIAAAAAAAAE21RQW6DMBD8ytaNBJHaJFLViwNIVZ8RcnBgXVk1xsILTYT4e20TQg89IOPZ2fHM7siMaJBx9tmaWpFqjQNlAKXEihx7YVJpdIyfRkY3G4gB8Pi97cPanRtQU8AuwuF_eNUaQuPlOMtc1SlLRWlKUo1tOwJflUikQHZtA0klzCDc64Imx0ANn8bInV1CDhtHgjClrsftcSXotluLybOUb3g4JJHhOZs5WZpuIS9gjNqkJKQP5e2ClrR4SMdZ13E4xZ8zTPOTJU2A2uE_PQ9COCI926_hTVarIU4hu_REPlBrKq2q73ycrf1N-vS4TMUsulaVg3EtR8H9rFgsg8uUsT1B2F9eshigZHBRpuaD0D3mY8Qm2BfB5N2YyRzdNEYVDy0Ja-WsFjcOUuP1HvFLWA6H3XuHTUSmmDV2--0TXonxsKbp7G9C6R__NONS-MFNvxj_d6mBAgAA).

Conversely, if `condition` is `false`, `color` will not be evaluated, and the effect will *only* re-run again when `condition` changes.

```
import confetti(alias) function confetti(opts?: ConfettiOptions): void
import confetti from 'canvas-confetti';

let conditionlet condition: boolean = $statefunction $state<true>(initial: true): true (+1 overload)
namespace $state

Declares reactive state.




Example:



let count = $state(0);

{@link https://svelte.dev/docs/svelte/$state Documentation}


initial 

The initial value


(true);
let colorlet color: string = $statefunction $state<"#ff3e00">(initial: "#ff3e00"): "#ff3e00" (+1 overload)
namespace $state

Declares reactive state.




Example:



let count = $state(0);

{@link https://svelte.dev/docs/svelte/$state Documentation}


initial 

The initial value


('#ff3e00');

$effectfunction $effect(fn: () => void | (() => void)): void
namespace $effect

Runs code when a component is mounted to the DOM, and then whenever its dependencies change, i.e. $state or $derived values.
The timing of the execution is after the DOM has been updated.




Example:



$effect(() => console.log('The count is now ' + count));

If you return a function from the effect, it will be called right before the effect is run again, or when the component is unmounted.




Does not run during server-side rendering.




{@link https://svelte.dev/docs/svelte/$effect Documentation}


fn 

The function to execute


(() => {
	if (conditionlet condition: true) {
		confetti(alias) confetti(opts?: ConfettiOptions): void
import confetti({ colors(property) ConfettiOptions.colors: string[]: [colorlet color: string] });
	} else {
		confetti(alias) confetti(opts?: ConfettiOptions): void
import confetti();
	}
});
```

## $effect.pre[](#$effect.pre)

In rare cases, you may need to run code *before* the DOM updates. For this we can use the `$effect.pre` rune:

```
<script>
	import { tick } from 'svelte';

	let div = $state();
	let messages = $state([]);

	// ...

	$effect.pre(() => {
		if (!div) return; // not yet mounted

		// reference `messages` array length so that this code re-runs whenever it changes
		messages.length;

		// autoscroll when new messages are added
		if (div.offsetHeight + div.scrollTop > div.scrollHeight - 20) {
			tick().then(() => {
				div.scrollTo(0, div.scrollHeight);
			});
		}
	});
</script>

<div bind:this={div}>
	{#each messages as message}
		<p>{message}</p>
	{/each}
</div>
```

`$effect.pre` runs before DOM updates that are scheduled after it, not before every DOM mutation in the flush - DOM of parent components may already be updated. When using [await expressions](await-expressions), block updates like `{#if ...}` and `{#each ...}` in the same component also run before `$effect.pre`.

Apart from the timing, `$effect.pre` works exactly like `$effect`.

## $effect.tracking[](#$effect.tracking)

The `$effect.tracking` rune is an advanced feature that tells you whether or not the code is running inside a tracking context, such as an effect or inside your template:

[Open in playground](/playground/untitled#H4sIAAAAAAAAA32Q0WrDMAxFf0UTgybgJO-uZ9h3LHvwPKWYObKJ1bUj5N-Hu8IeMvYqHc6V7orsZkKNjzRN5KWXxfmPwKemRYVTiFRQv6z45grdyeec-_JJUQgV-sRCLAU1muKXkMWOPIpPXFKkPqZTcwgMPs05MbFAITlnfVCwD2yPMAwwuVho5Gq5I03TwpOFtY726h_mP6Ms5yqUrT2ObIbfM9lkGxiE5hydkIZ1r9jMkC2Yh667eaDrLCr8qwqhq6CukEL5ynVf-8PtVaG4EC-B31Hf3tu-AQVqZkt3AQAA)

```
<script>
	console.log('in component setup:', $effect.tracking()); // false

	$effect(() => {
		console.log('in effect:', $effect.tracking()); // true
	});
</script>

<p>in template: {$effect.tracking()}</p> <!-- true -->
```

```
<script lang="ts">
	console.log('in component setup:', $effect.tracking()); // false

	$effect(() => {
		console.log('in effect:', $effect.tracking()); // true
	});
</script>

<p>in template: {$effect.tracking()}</p> <!-- true -->
```

It is used to implement abstractions like [`createSubscriber`](/docs/svelte/svelte-reactivity#createSubscriber), which will create listeners to update reactive values but *only* if those values are being tracked (rather than, for example, read inside an event handler).

## $effect.pending[](#$effect.pending)

When using [`await`](await-expressions) in components, the `$effect.pending()` rune tells you how many promises are pending in the current [boundary](svelte-boundary), not including child boundaries:

[Open in playground](/playground/untitled#H4sIAAAAAAAAA3WRT0-EQAzFv0pTPUAgspp4YVkSv4EHb-KhQMdMZMuEKa6byXx3w7Jq_Hd975f2tS-g0J6xxEs2hju9ciy9lWfM0diBPZaPAVvyfMbunLvyrzwoY47dKMqiHkusfDdZp3UjjQ6sQLCDS6-knFyn2w-1_VJvTqo0Sv4oHZhZOrWjAPV9Qjm0KYTFbZQOZBWED3A_jXvrOUlMCrsaPOuD3fM4a2JyuN1s0nQLRQE0qTW2szRAzwMd1zET6zwJEGTQnvLERqriK7VU7aw6CozSDbZ72YXktIWyLNaUZVWx-vW_ZLuQ7TeykcrVgSJkENoIOwjrNZ9HxqpwJy5cWAM_OkjSuAStXH0WwK0f8CWE3-w6KhTWRMzxr76U3xRLnWbOUY9u8ZeSMT7lqGSHg5UeS0OD5_gO8IuoEhkCAAA)

```
<script>
	let a = $state(1);
	let b = $state(2);

	async function add(a, b) {
		await new Promise((f) => setTimeout(f, 500)); // artificial delay
		return a + b;
	}
</script>

<button onclick={() => a++}>a++</button>
<button onclick={() => b++}>b++</button>

<p>{a} + {b} = {await add(a, b)}</p>

{#if $effect.pending()}
	<p>pending promises: {$effect.pending()}</p>
{/if}
```

```
<script lang="ts">
	let a = $state(1);
	let b = $state(2);

	async function add(a, b) {
		await new Promise((f) => setTimeout(f, 500)); // artificial delay
		return a + b;
	}
</script>

<button onclick={() => a++}>a++</button>
<button onclick={() => b++}>b++</button>

<p>{a} + {b} = {await add(a, b)}</p>

{#if $effect.pending()}
	<p>pending promises: {$effect.pending()}</p>
{/if}
```

## $effect.root[](#$effect.root)

The `$effect.root` rune is an advanced feature that creates a non-tracked scope that doesn’t auto-cleanup. This is useful for nested effects that you want to manually control. This rune also allows for the creation of effects outside of the component initialisation phase.

```
const destroyconst destroy: () => void = $effectnamespace $effect
function $effect(fn: () => void | (() => void)): void

Runs code when a component is mounted to the DOM, and then whenever its dependencies change, i.e. $state or $derived values.
The timing of the execution is after the DOM has been updated.




Example:



$effect(() => console.log('The count is now ' + count));

If you return a function from the effect, it will be called right before the effect is run again, or when the component is unmounted.




Does not run during server-side rendering.




{@link https://svelte.dev/docs/svelte/$effect Documentation}


fn 

The function to execute


.rootfunction $effect.root(fn: () => void | (() => void)): () => void

The $effect.root rune is an advanced feature that creates a non-tracked scope that doesn't auto-cleanup. This is useful for
nested effects that you want to manually control. This rune also allows for creation of effects outside of the component
initialisation phase.




Example:



<script>
  let count = $state(0);

  const cleanup = $effect.root(() => {
    $effect(() => {
      console.log(count);
    })

    return () => {
      console.log('effect root cleanup');
    }
  });
</script>

<button onclick={() => cleanup()}>cleanup</button>

{@link https://svelte.dev/docs/svelte/$effect#$effect.root Documentation}


(() => {
	$effectfunction $effect(fn: () => void | (() => void)): void
namespace $effect

Runs code when a component is mounted to the DOM, and then whenever its dependencies change, i.e. $state or $derived values.
The timing of the execution is after the DOM has been updated.




Example:



$effect(() => console.log('The count is now ' + count));

If you return a function from the effect, it will be called right before the effect is run again, or when the component is unmounted.




Does not run during server-side rendering.




{@link https://svelte.dev/docs/svelte/$effect Documentation}


fn 

The function to execute


(() => {
		// setup
	});

	return () => {
		// cleanup
	};
});

// later...
destroyconst destroy: () => void();
```

## When not to use $effect[](#When-not-to-use-$effect)

In general, `$effect` is best considered something of an escape hatch — useful for things like analytics and direct DOM manipulation — rather than a tool you should use frequently. In particular, avoid using it to synchronise state. Instead of this...

```
<script>
	let count = $state(0);
	let doubled = $state();

	// don't do this!
	$effect(() => {
		doubled = count * 2;
	});
</script>
```

...do this:

```
<script>
	let count = $state(0);
	let doubled = $derived(count * 2);
</script>
```

> For things that are more complicated than a simple expression like `count * 2`, you can also use `$derived.by`.

If you’re using an effect because you want to be able to reassign the derived value (to build an optimistic UI, for example) note that [deriveds can be directly overridden]($derived#Overriding-derived-values) as of Svelte 5.25.

You might be tempted to do something convoluted with effects to link one value to another. The following example shows two inputs for “money spent” and “money left” that are connected to each other. If you update one, the other should update accordingly. Instead of using effects for this...

[Open in playground](/playground/untitled#H4sIAAAAAAAAA5VSQWrDQAz8iioCdcBN3EMvGzvQN_RY97Cx5XRhIy9ZJU0w_nuxHCelhEKPmtHMSEIdst0RGnwjEcdbiGKFwDFQ01AlEZK65UeBugX5dPFhjik2zlNE897hxka6GLyGsIhH8kKYYtWyEEtEg3ms9i7IuuRSqpajgLRiPRTwnGWrAfUkEAOxQAEzzU-y-ZXx1PwgVKsklzIbZ0ySORRr6AZo0Gj_GPI0GqtZ_6dsGmDSDTY3Wb68bcG5txvyulDuOBwE5ByoKHFveUslwsZxbY7WH6jo1LeHnT0VnXr3sFTphVlOqJZD0tX9f0HDwHdzlLjGDNWvlChnT9qr4HSR2sXg7dlA4-m0GrGtDQayxQvtxtvoZVSOKd57BKGToJH9gVIchkej34P9R4pinf9yXKNprI_UfwOoIBNKjAIAAA)

```
<script>
	const total = 100;
	let spent = $state(0);
	let left = $state(total);

	$effect(() => {
		left = total - spent;
	});

	$effect(() => {
		spent = total - left;
	});
</script>

<label>
	<input type="range" bind:value={spent} max={total} />
	{spent}/{total} spent
</label>

<label>
	<input type="range" bind:value={left} max={total} />
	{left}/{total} left
</label>

<style>
	label {
		display: flex;
		gap: 0.5em;
	}
</style>
```

```
<script lang="ts">
	const total = 100;
	let spent = $state(0);
	let left = $state(total);

	$effect(() => {
		left = total - spent;
	});

	$effect(() => {
		spent = total - left;
	});
</script>

<label>
	<input type="range" bind:value={spent} max={total} />
	{spent}/{total} spent
</label>

<label>
	<input type="range" bind:value={left} max={total} />
	{left}/{total} left
</label>

<style>
	label {
		display: flex;
		gap: 0.5em;
	}
</style>
```

...use `oninput` callbacks or — better still — [function bindings](bind#Function-bindings) where possible:

[Open in playground](/playground/untitled#H4sIAAAAAAAAA5VSu27DMAz8FYLo4ABu4g5dFDtA9m4d6w6KTbsCFFqw6Dxg-N8LKXESFFk68o7HO1IakfWeUOEniRhuwYsWgqORH2gGrsR0DDvDteHWY4qNseRRfY24056u2q1zS38gK4QpVh0LsXhUmPuqN042JZdSdewFpBNtoYC3LFsH1JKAd8QCBbxE6yRb3BhLTSRq6s2B6uSifr0oYhuXcks5uFoLfVAjSRAuYAx0KfP8WR3IaDGVnK_uETm3ekc2ps0Nu0FAzo6KEnvNLZUY76AO2g5UjHHqBHt9KsY4eYJVlF6Z1YzGMjjdpv_PKFlAsYmh04cVnzqHprtxqP74ejlbir0RnC9UG--sPitoLJ3WF6zVTkG2fKf9w62iHFN89u5CJ0El_UAphnVQxc-C03eKoo09Gq5RNdp6mn4B47i_z3YCAAA)

```
<script>
	const total = 100;
	let spent = $state(0);
	let left = $derived(total - spent);

	function updateLeft(left) {
		spent = total - left;
	}
</script>

<label>
	<input type="range" bind:value={spent} max={total} />
	{spent}/{total} spent
</label>

<label>
	<input type="range" bind:value={() => left, updateLeft} max={total} />
	{left}/{total} left
</label>

<style>
	label {
		display: flex;
		gap: 0.5em;
	}
</style>
```

```
<script lang="ts">
	const total = 100;
	let spent = $state(0);
	let left = $derived(total - spent);

	function updateLeft(left) {
		spent = total - left;
	}
</script>

<label>
	<input type="range" bind:value={spent} max={total} />
	{spent}/{total} spent
</label>

<label>
	<input type="range" bind:value={() => left, updateLeft} max={total} />
	{left}/{total} left
</label>

<style>
	label {
		display: flex;
		gap: 0.5em;
	}
</style>
```

If you absolutely have to update `$state` within an effect and run into an infinite loop because you read and write to the same `$state`, use [untrack](svelte#untrack).

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/02-runes/04-$effect.md) [llms.txt](/docs/svelte/$effect/llms.txt)

previous next

[$derived](/docs/svelte/$derived) [$props](/docs/svelte/$props)

----
url: https://svelte.dev/docs/svelte/$inspect
----

[Skip to main content](#main)

> `$inspect` only works during development. In a production build it becomes a noop.

The `$inspect` rune is roughly equivalent to `console.log`, with the exception that it will re-run whenever its argument changes. `$inspect` tracks reactive state deeply, meaning that updating something inside an object or array using fine-grained reactivity will cause it to re-fire:

[Open in playground](/playground/untitled#H4sIAAAAAAAAA22Q0W6CQBBFf2UyMVHiBvqMQNLHfkNpwrqOuHGYJeygbQj_3ohaX_p8TmZO7oRiO8IcV15iT043aZomaPDomSLmnxPubaSH9N73abwQK6FBF0RJNGKORXSD77WqpVYmBRdGUShhFdUqbd6S3ZN0FKNt6cXWJ2IO68WQWv8ylhPm6Sc7yDK4emZwQWJgSjm0cD2RQLOoDYQBmofegDtZaamWInulSbEfVYNAEMfenctpk0BZ3Wu327n6EDdQR6JFdjerWgov_aiw93LIL5ZHKqfHkxmyCg3-N43St2Kuw0gG9ae_8dueOH8ZVOv56uWA-dFypPkX_VwbIYIBAAA)

```
<script>
	let count = $state(0);
	let message = $state('hello');

	$inspect(count, message); // will console.log when `count` or `message` change
</script>

<button onclick={() => count++}>Increment</button>
<input bind:value={message} />
```

```
<script lang="ts">
	let count = $state(0);
	let message = $state('hello');

	$inspect(count, message); // will console.log when `count` or `message` change
</script>

<button onclick={() => count++}>Increment</button>
<input bind:value={message} />
```

On updates, a stack trace will be printed, making it easy to find the origin of a state change (unless you’re in the playground, due to technical limitations).

## $inspect(...).with[](#$inspect\(\).with)

`$inspect(...)` returns an object with a `with` method, which you can invoke with a callback that will then be invoked instead of `console.log`. The first argument to the callback is either `"init"` or `"update"`; subsequent arguments are the values passed to `$inspect`:

[Open in playground](/playground/untitled#H4sIAAAAAAAAA21Q0W6DMAz8FcuqVFAj2DMFpD3uG8akhuC20VIHJaasQvz7BHTby55s-e5055uQ9Y2wwJ3l2JORJMuyNButXNcNFZ6to4jF-4StjvSkv_Z9Fu_khFCh8SzEErHAMppge6kbbsSRgPEDC1Swi6KFkpf02PCC_dqthKdhIo-e1KZJoaphWqiN2DOsEFRVBfuh77TQPv1BG-moHS4XCkfIc_ABTsZz9I4yCdrQSS238aqF7hTg4QcYNcsmnpcxL6nK_C86l-0g4hk8G2fNZzUla5412eEw129sAt2Ipcw3Zo0K_6tG6EuwkDCQwuUFLNY-cf5QKNq60XKHxVm7SPM3eESCl4wBAAA)

```
<script>
	let count = $state(0);

	$inspect(count).with((type, count) => {
		if (type === 'update') {
			debugger; // or `console.trace`, or whatever you want
		}
	});
</script>

<button onclick={() => count++}>Increment</button>
```

```
<script lang="ts">
	let count = $state(0);

	$inspect(count).with((type, count) => {
		if (type === 'update') {
			debugger; // or `console.trace`, or whatever you want
		}
	});
</script>

<button onclick={() => count++}>Increment</button>
```

## $inspect.trace(...)[](#$inspect.trace\(\))

This rune, added in 5.14, causes the surrounding function to be *traced* in development. Any time the function re-runs as part of an [effect]($effect) or a [derived]($derived), information will be printed to the console about which pieces of reactive state caused the effect to fire.

```
<script>
	import { doSomeWork } from './elsewhere';

	$effect(() => {
		// $inspect.trace must be the first statement of a function body
		$inspect.trace();
		doSomeWork();
	});
</script>
```

`$inspect.trace` takes an optional first argument which will be used as the label.

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/02-runes/07-$inspect.md) [llms.txt](/docs/svelte/$inspect/llms.txt)

previous next

[$bindable](/docs/svelte/$bindable) [$host](/docs/svelte/$host)

----
url: https://svelte.dev/docs/svelte/hydratable/llms.txt
----

````
In Svelte, when you want to render asynchronous content data on the server, you can simply `await` it. This is great! However, it comes with a pitfall: when hydrating that content on the client, Svelte has to redo the asynchronous work, which blocks hydration for however long it takes:

```svelte
<script>
  import { getUser } from 'my-database-library';

  // This will get the user on the server, render the user's name into the h1,
  // and then, during hydration on the client, it will get the user _again_,
  // blocking hydration until it's done.
  const user = await getUser();
</script>

<h1>{user.name}</h1>
```

That's silly, though. If we've already done the hard work of getting the data on the server, we don't want to get it again during hydration on the client. `hydratable` is a low-level API built to solve this problem. You probably won't need this very often — it will be used behind the scenes by whatever datafetching library you use. For example, it powers [remote functions in SvelteKit](/docs/kit/remote-functions).

To fix the example above:

```svelte
<script>
  import { hydratable } from 'svelte';
  import { getUser } from 'my-database-library';

  // During server rendering, this will serialize and stash the result of `getUser`, associating
  // it with the provided key and baking it into the `head` content. During hydration, it will
  // look for the serialized version, returning it instead of running `getUser`. After hydration
  // is done, if it's called again, it'll simply invoke `getUser`.
  const user = await hydratable('user', () => getUser());
</script>

<h1>{user.name}</h1>
```

This API can also be used to provide access to random or time-based values that are stable between server rendering and hydration. For example, to get a random number that doesn't update on hydration:

```ts
import { hydratable } from 'svelte';
const rand = hydratable('random', () => Math.random());
```

If you're a library author, be sure to prefix the keys of your `hydratable` values with the name of your library so that your keys don't conflict with other libraries.

## Serialization

All data returned from a `hydratable` function must be serializable. But this doesn't mean you're limited to JSON — Svelte uses [`devalue`](https://npmjs.com/package/devalue), which can serialize all sorts of things including `Map`, `Set`, `URL`, and `BigInt`. Check the documentation page for a full list. In addition to these, thanks to some Svelte magic, you can also fearlessly use promises:

```svelte
<script>
  import { hydratable } from 'svelte';
  const promises = hydratable('random', () => {
    return {
      one: Promise.resolve(1),
      two: Promise.resolve(2)
    }
  });
</script>

{await promises.one}
{await promises.two}
```

## CSP

`hydratable` adds an inline `<script>` block to the `head` returned from `render`. If you're using [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP) (CSP), this script will likely fail to run. You can provide a `nonce` to `render`:

```js
/// file: server.js
import { render } from 'svelte/server';
import App from './App.svelte';
// ---cut---
const nonce = crypto.randomUUID();

const { head, body } = await render(App, {
	csp: { nonce }
});
```

This will add the `nonce` to the script block, on the assumption that you will later add the same nonce to the CSP header of the document that contains it:

```js
/// file: server.js
let response = new Response();
let nonce = 'xyz123';
// ---cut---
response.headers.set(
  'Content-Security-Policy',
  `script-src 'nonce-${nonce}'`
 );
```

It's essential that a `nonce` — which, British slang definition aside, means 'number used once' — is only used when dynamically server rendering an individual response.

If instead you are generating static HTML ahead of time, you must use hashes instead:

```js
/// file: server.js
import { render } from 'svelte/server';
import App from './App.svelte';
// ---cut---
const { head, body, hashes } = await render(App, {
	csp: { hash: true }
});
```

`hashes.script` will be an array of strings like `["sha256-abcd123"]`. As with `nonce`, the hashes should be used in your CSP header:

```js
/// file: server.js
let response = new Response();
let hashes = { script: ['sha256-xyz123'] };
// ---cut---
response.headers.set(
  'Content-Security-Policy',
  `script-src ${hashes.script.map((hash) => `'${hash}'`).join(' ')}`
 );
```

We recommend using `nonce` over hash if you can, as `hash` will interfere with streaming SSR in the future.
````

----
url: https://svelte.dev/docs/svelte/svelte-attachments/llms.txt
----

````
```js
// @noErrors
import { createAttachmentKey, fromAction } from 'svelte/attachments';
```

## createAttachmentKey

<blockquote class="since note">

Available since 5.29

</blockquote>

Creates an object key that will be recognised as an attachment when the object is spread onto an element,
as a programmatic alternative to using `{@attach ...}`. This can be useful for library authors, though
is generally not needed when building an app.

```svelte
<script>
	import { createAttachmentKey } from 'svelte/attachments';

	const props = {
		class: 'cool',
		onclick: () => alert('clicked'),
		[createAttachmentKey()]: (node) => {
			node.textContent = 'attached!';
		}
	};
</script>

<button {...props}>click me</button>
```

<div class="ts-block">

```dts
function createAttachmentKey(): symbol;
```

</div>



## fromAction

Converts an [action](/docs/svelte/use) into an [attachment](/docs/svelte/@attach) keeping the same behavior.
It's useful if you want to start using attachments on components but you have actions provided by a library.

Note that the second argument, if provided, must be a function that _returns_ the argument to the
action function, not the argument itself.

```svelte
<!-- with an action -->
<div use:foo={bar}>...</div>

<!-- with an attachment -->
<div {@attach fromAction(foo, () => bar)}>...</div>
```

<div class="ts-block">

```dts
function fromAction<
	E extends EventTarget,
	T extends unknown
>(
	action:
		| Action<E, T>
		| ((element: E, arg: T) => void | ActionReturn<T>),
	fn: () => T
): Attachment<E>;
```

</div>

<div class="ts-block">

```dts
function fromAction<E extends EventTarget>(
	action:
		| Action<E, void>
		| ((element: E) => void | ActionReturn<void>)
): Attachment<E>;
```

</div>



## Attachment

An [attachment](/docs/svelte/@attach) is a function that runs when an element is mounted
to the DOM, and optionally returns a function that is called when the element is later removed.

It can be attached to an element with an `{@attach ...}` tag, or by spreading an object containing
a property created with [`createAttachmentKey`](/docs/svelte/svelte-attachments#createAttachmentKey).

<div class="ts-block">

```dts
interface Attachment<T extends EventTarget = Element> {/*…*/}
```

<div class="ts-block-property">

```dts
(element: T): void | (() => void);
```

<div class="ts-block-property-details"></div>
</div></div>
````

----
url: https://svelte.dev/docs/svelte/declaration-tags
----

[Skip to main content](#main)

Declaration tags define local variables inside markup with `const` or `let`:

[Open in playground](/playground/untitled#H4sIAAAAAAAAA22QQWrDMBBFrzJMsyoibhfZqLah0FvEgYyVSSxQZWFNmxShc_RAvViRY5osuvsz__8nMQk9vTNqfGPjaCKxowehU0SFR-s4ot4m7CnyknsNYR0_2QmjQjN6YS8RNdbRTDZI2_lOHAv044UjNLBNcLYHGTQ8PykY2J4GKRqygpu1ubM2kHcvna-rG9GnByYzLFCKReTyUjKjjwI0MUFTtuuZCI-zviLvg456dtDAfpX-whl-vuE6LwVoYJUKM-9L2XdShzbN3VxXoe18qsp_Mir87yzCF0Et0wcrlK9Q_HJLzDuFQtadrT-gPpKLnH8BMGymL4EBAAA)

```
<script>
	let boxes = [{ width: 10, height: 10 }, { width: 15, height: 15 }];
</script>

{#each boxes as box}
	{const area = box.width * box.height}
	{const label = `${box.width} × ${box.height} = ${area}`}

	<p>{label}</p>
{/each}
```

```
<script lang="ts">
	let boxes = [{ width: 10, height: 10 }, { width: 15, height: 15 }];
</script>

{#each boxes as box}
	{const area = box.width * box.height}
	{const label = `${box.width} × ${box.height} = ${area}`}

	<p>{label}</p>
{/each}
```

> Declaration tags are available since Svelte 5.56.

> The [`{@const ...}`](@const) syntax is considered legacy — use declaration tags instead.

When values should be reactive, you can use `$state` and `$derived`:

[Open in playground](/playground/untitled#H4sIAAAAAAAAA22SQW-DMAyF_0rkVWoroXKnAWm3nbfjmNQUTBctMxExbFOU_z4llNJDj7GfX77nxAOpb4QCXlE1rCcULTZGDYp1T4LVxUEGnTbooHj3cFYOrwPP1h7chIYRMmh6YiR2UIB0zaAtVzXVbJDF6HAQpdg4Vow7L-J4IbZvaXQrwv64KLHVrOmyijtlHMa-zFdTkrZ6QWN64aP1IfoFmduqJnkemXsSPTVGN1-l3-1FWd358jBiqOI5Ych8Hki2_kl3izREJB-ZomwFul24nxVNT47FZUBcwFsc9ITt7jQjbnzCOyU91Sw_h7QYqcmOLM6a2mJSZsRyFop8btvKL67XbKn8OJ-PvZpvcKJM2Me5vKZP60zVECqnpvv8PtddgAwePS7jL0MRd5cB_9nYjz8CwkcGrLT50dRCkdzDP-uNSAxQAgAA)

```
<script>
	let user = $state({ name: 'Svelte' });
	let editing = $state(false);
</script>

<p>Hello {user.name}</p>
<button onclick={() => editing = true}>edit name</button>

{#if editing}
	{let name = $state(user.name)}
	{const greeting = $derived(`Hello ${name}`)}

	<hr>
	<input bind:value={name} />
	<p>{greeting}</p>

	<button onclick={() => {
		user.name = name;
		editing = false;
	}}>save</button>
{/if}
```

```
<script lang="ts">
	let user = $state({ name: 'Svelte' });
	let editing = $state(false);
</script>

<p>Hello {user.name}</p>
<button onclick={() => editing = true}>edit name</button>

{#if editing}
	{let name = $state(user.name)}
	{const greeting = $derived(`Hello ${name}`)}

	<hr>
	<input bind:value={name} />
	<p>{greeting}</p>

	<button onclick={() => {
		user.name = name;
		editing = false;
	}}>save</button>
{/if}
```

Declaration tags can be used anywhere inside the component. They can reference values declared outside themselves (for example in the `<script>` tag or in `{#each ...}` blocks) and are ‘visible’ to everything in the same lexical scope (i.e. siblings, and children of those siblings):

[Open in playground](/playground/untitled#H4sIAAAAAAAAA32Qzw6CMAyHX2X2wgX0viCJiW_hPEwoumR2hFXULHt3MwQP_jv1l_b7krYBSJ8RJGyxtrrXbBwJ1kfha9ch5NAaix7kLsBBe5zgTdct_YCWE1E7YiT2ICHUjjyLE1rrxFpkY8iiojCmKMpFUcxtURSVorIxQ6VI8Ydrkqj4TTWTp_hl_mNWT2iuv_aAHL6dxnhjkNxfMAe-d2me_gFxnwNrY6-GGpCtth7jA54oSZ1KAQAA)

```
{const hello = 'hello'}
{hello} <!-- 'hello' -->
<div>
	{const hello = 'hi'}
	{hello} <!-- 'hi' -->
	<div>
		{hello} <!-- 'hi' -->
	</div>
</div>
{hello} <!-- 'hello' -->
```

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/03-template-syntax/11-declaration-tags.md) [llms.txt](/docs/svelte/declaration-tags/llms.txt)

previous next

[{@debug ...}](/docs/svelte/@debug) [bind:](/docs/svelte/bind)

----
url: https://svelte.dev/docs/svelte/svelte-options/llms.txt
----

````
```svelte
<svelte:options option={value} />
```

The `<svelte:options>` element provides a place to specify per-component compiler options, which are detailed in the [compiler section](svelte-compiler#compile). The possible options are:

- `runes={true}` — forces a component into _runes mode_ (see the [Legacy APIs](legacy-overview) section)
- `runes={false}` — forces a component into _legacy mode_
- `namespace="..."` — the namespace where this component will be used, can be "html" (the default), "svg" or "mathml"
- `customElement={...}` — the [options](custom-elements#Component-options) to use when compiling this component as a custom element. If a string is passed, it is used as the `tag` option
- `css="injected"` — the component will inject its styles inline: During server-side rendering, it's injected as a `<style>` tag in the `head`, during client side rendering, it's loaded via JavaScript

> [!LEGACY] Deprecated options
> Svelte 4 also included the following options. They are deprecated in Svelte 5 and non-functional in runes mode.
>
> - `immutable={true}` — you never use mutable data, so the compiler can do simple referential equality checks to determine if values have changed
> - `immutable={false}` — the default. Svelte will be more conservative about whether or not mutable objects have changed
> - `accessors={true}` — adds getters and setters for the component's props
> - `accessors={false}` — the default

```svelte
<svelte:options customElement="my-custom-element" />
```
````

----
url: https://svelte.dev/docs/svelte/legacy-overview
----

[Skip to main content](#main)

Svelte 5 introduced some significant changes to Svelte’s API, including [runes](what-are-runes), [snippets](snippet) and event attributes. As a result, some Svelte 3/4 features are deprecated (though supported for now, unless otherwise specified) and will eventually be removed. We recommend that you incrementally [migrate your existing code](v5-migration-guide).

The following pages document these features for

* people still using Svelte 3/4
* people using Svelte 5, but with components that haven’t yet been migrated

Since Svelte 3/4 syntax still works in Svelte 5, we will distinguish between *legacy mode* and *runes mode*. Once a component is in runes mode (which you can opt into by using runes, or by explicitly setting the `runes: true` compiler option), legacy mode features are no longer available.

If you’re exclusively interested in the Svelte 3/4 syntax, you can browse its documentation at [v4.svelte.dev](https://v4.svelte.dev).

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/99-legacy/00-legacy-overview.md) [llms.txt](/docs/svelte/legacy-overview/llms.txt)

previous next

[Runtime warnings](/docs/svelte/runtime-warnings) [Reactive let/var declarations](/docs/svelte/legacy-let)

----
url: https://svelte.dev/docs/svelte/custom-properties
----

[Skip to main content](#main)

You can pass CSS custom properties — both static and dynamic — to components:

```
<Slider
	bind:value
	min={0}
	max={100}
	--track-color="black"
	--thumb-color="rgb({r} {g} {b})"
/>
```

The above code essentially desugars to this:

```
<svelte-css-wrapper style="display: contents; --track-color: black; --thumb-color: rgb({r} {g} {b})">
	<Slider
		bind:value
		min={0}
		max={100}
	/>
</svelte-css-wrapper>
```

For an SVG element, it would use `<g>` instead:

```
<g style="--track-color: black; --thumb-color: rgb({r} {g} {b})">
	<Slider
		bind:value
		min={0}
		max={100}
	/>
</g>
```

Inside the component, we can read these custom properties (and provide fallback values) using [`var(...)`](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties):

```
<style>
	.track {
		background: var(--track-color, #aaa);
	}

	.thumb {
		background: var(--thumb-color, blue);
	}
</style>
```

You don’t *have* to specify the values directly on the component; as long as the custom properties are defined on a parent element, the component can use them. It’s common to define custom properties on the `:root` element in a global stylesheet so that they apply to your entire application.

> While the extra element will not affect layout, it *will* affect any CSS selectors that (for example) use the `>` combinator to target an element directly inside the component’s container.

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/04-styling/03-custom-properties.md) [llms.txt](/docs/svelte/custom-properties/llms.txt)

previous next

[Global styles](/docs/svelte/global-styles) [Nested \<style> elements](/docs/svelte/nested-style-elements)

----
url: https://svelte.dev/docs/svelte/svelte-document/llms.txt
----

````
```svelte
<svelte:document onevent={handler} />
```

```svelte
<svelte:document bind:prop={value} />
```

Similarly to `<svelte:window>`, this element allows you to add listeners to events on `document`, such as `visibilitychange`, which don't fire on `window`. It also lets you use [attachments](@attach) on `document`.

As with `<svelte:window>`, this element may only appear the top level of your component and must never be inside a block or element.

```svelte
<svelte:document onvisibilitychange={handleVisibilityChange} {@attach someAttachment} />
```

You can also bind to the following properties:

- `activeElement`
- `fullscreenElement`
- `pointerLockElement`
- `visibilityState`

All are readonly.
````

----
url: https://svelte.dev/docs/svelte/v4-migration-guide/llms.txt
----

````
This migration guide provides an overview of how to migrate from Svelte version 3 to 4. See the linked PRs for more details about each change. Use the migration script to migrate some of these automatically: `npx svelte-migrate@latest svelte-4`

If you're a library author, consider whether to only support Svelte 4 or if it's possible to support Svelte 3 too. Since most of the breaking changes don't affect many people, this may be easily possible. Also remember to update the version range in your `peerDependencies`.

## Minimum version requirements

- Upgrade to Node 16 or higher. Earlier versions are no longer supported. ([#8566](https://github.com/sveltejs/svelte/issues/8566))
- If you are using SvelteKit, upgrade to 1.20.4 or newer ([sveltejs/kit#10172](https://github.com/sveltejs/kit/pull/10172))
- If you are using Vite without SvelteKit, upgrade to `vite-plugin-svelte` 2.4.1 or newer ([#8516](https://github.com/sveltejs/svelte/issues/8516))
- If you are using webpack, upgrade to webpack 5 or higher and `svelte-loader` 3.1.8 or higher. Earlier versions are no longer supported. ([#8515](https://github.com/sveltejs/svelte/issues/8515), [198dbcf](https://github.com/sveltejs/svelte/commit/198dbcf))
- If you are using Rollup, upgrade to `rollup-plugin-svelte` 7.1.5 or higher ([198dbcf](https://github.com/sveltejs/svelte/commit/198dbcf))
- If you are using TypeScript, upgrade to TypeScript 5 or higher. Lower versions might still work, but no guarantees are made about that. ([#8488](https://github.com/sveltejs/svelte/issues/8488))

## Browser conditions for bundlers

Bundlers must now specify the `browser` condition when building a frontend bundle for the browser. SvelteKit and Vite will handle this automatically for you. If you're using any others, you may observe lifecycle callbacks such as `onMount` not get called and you'll need to update the module resolution configuration.
- For Rollup this is done within the `@rollup/plugin-node-resolve` plugin by setting `browser: true` in its options. See the [`rollup-plugin-svelte`](https://github.com/sveltejs/rollup-plugin-svelte/#usage) documentation for more details
- For webpack this is done by adding `"browser"` to the `conditionNames` array. You may also have to update your `alias` config, if you have set it. See the [`svelte-loader`](https://github.com/sveltejs/svelte-loader#usage) documentation for more details

([#8516](https://github.com/sveltejs/svelte/issues/8516))

## Removal of CJS related output

Svelte no longer supports the CommonJS (CJS) format for compiler output and has also removed the `svelte/register` hook and the CJS runtime version. If you need to stay on the CJS output format, consider using a bundler to convert Svelte's ESM output to CJS in a post-build step. ([#8613](https://github.com/sveltejs/svelte/issues/8613))

## Stricter types for Svelte functions

There are now stricter types for `createEventDispatcher`, `Action`, `ActionReturn`, and `onMount`:

- `createEventDispatcher` now supports specifying that a payload is optional, required, or non-existent, and the call sites are checked accordingly ([#7224](https://github.com/sveltejs/svelte/issues/7224))

```ts
// @errors: 2554 2345
import { createEventDispatcher } from 'svelte';

const dispatch = createEventDispatcher<{
	optional: number | null;
	required: string;
	noArgument: null;
}>();

// Svelte version 3:
dispatch('optional');
dispatch('required'); // I can still omit the detail argument
dispatch('noArgument', 'surprise'); // I can still add a detail argument

// Svelte version 4 using TypeScript strict mode:
dispatch('optional');
dispatch('required'); // error, missing argument
dispatch('noArgument', 'surprise'); // error, cannot pass an argument
```

- `Action` and `ActionReturn` have a default parameter type of `undefined` now, which means you need to type the generic if you want to specify that this action receives a parameter. The migration script will migrate this automatically ([#7442](https://github.com/sveltejs/svelte/pull/7442))

```ts
// @noErrors
---const action: Action = (node, params) => { ... } // this is now an error if you use params in any way---
+++const action: Action<HTMLElement, string> = (node, params) => { ... } // params is of type string+++
```

- `onMount` now shows a type error if you return a function asynchronously from it, because this is likely a bug in your code where you expect the callback to be called on destroy, which it will only do for synchronously returned functions ([#8136](https://github.com/sveltejs/svelte/issues/8136))

```js
// @noErrors
// Example where this change reveals an actual bug
onMount(
---	// someCleanup() not called because function handed to onMount is async
	async () => {
		const something = await foo();---
+++	// someCleanup() is called because function handed to onMount is sync
	() => {
		foo().then(something => {...});
		// ...
		return () => someCleanup();
	}
);
```

## Custom Elements with Svelte

The creation of custom elements with Svelte has been overhauled and significantly improved. The `tag` option is deprecated in favor of the new `customElement` option:

```svelte
---<svelte:options tag="my-component" />---
+++<svelte:options customElement="my-component" />+++
```

This change was made to allow [more configurability](custom-elements#Component-options) for advanced use cases. The migration script will adjust your code automatically. The update timing of properties has changed slightly as well. ([#8457](https://github.com/sveltejs/svelte/issues/8457))

## SvelteComponentTyped is deprecated

`SvelteComponentTyped` is deprecated, as `SvelteComponent` now has all its typing capabilities. Replace all instances of `SvelteComponentTyped` with `SvelteComponent`.

```js
---import { SvelteComponentTyped } from 'svelte';---
+++import { SvelteComponent } from 'svelte';+++

---export class Foo extends SvelteComponentTyped<{ aProp: string }> {}---
+++export class Foo extends SvelteComponent<{ aProp: string }> {}+++
```

If you have used `SvelteComponent` as the component instance type previously, you may see a somewhat opaque type error now, which is solved by changing `: typeof SvelteComponent` to `: typeof SvelteComponent<any>`.

```svelte
<script>
	import ComponentA from './ComponentA.svelte';
	import ComponentB from './ComponentB.svelte';
	import { SvelteComponent } from 'svelte';

	let component: typeof SvelteComponent+++<any>+++;

	function choseRandomly() {
		component = Math.random() > 0.5 ? ComponentA : ComponentB;
	}
</script>

<button on:click={choseRandomly}>random</button>
<svelte:element this={component} />
```

The migration script will do both automatically for you. ([#8512](https://github.com/sveltejs/svelte/issues/8512))

## Transitions are local by default

Transitions are now local by default to prevent confusion around page navigations. "local" means that a transition will not play if it's within a nested control flow block (`each/if/await/key`) and not the direct parent block but a block above it is created/destroyed. In the following example, the `slide` intro animation will only play when `success` goes from `false` to `true`, but it will _not_ play when `show` goes from `false` to `true`:

```svelte
{#if show}
	...
	{#if success}
		<p in:slide>Success</p>
	{/each}
{/if}
```

To make transitions global, add the `|global` modifier — then they will play when _any_ control flow block above is created/destroyed. The migration script will do this automatically for you. ([#6686](https://github.com/sveltejs/svelte/issues/6686))

## Default slot bindings

Default slot bindings are no longer exposed to named slots and vice versa:

```svelte
<script>
	import Nested from './Nested.svelte';
</script>

<Nested let:count>
	<p>
		count in default slot — is available: {count}
	</p>
	<p slot="bar">
		count in bar slot — is not available: {count}
	</p>
</Nested>
```

This makes slot bindings more consistent as the behavior is undefined when for example the default slot is from a list and the named slot is not. ([#6049](https://github.com/sveltejs/svelte/issues/6049))

## Preprocessors

The order in which preprocessors are applied has changed. Now, preprocessors are executed in order, and within one group, the order is markup, script, style.

```js
// @errors: 2304
import { preprocess } from 'svelte/compiler';

const { code } = await preprocess(
	source,
	[
		{
			markup: () => {
				console.log('markup-1');
			},
			script: () => {
				console.log('script-1');
			},
			style: () => {
				console.log('style-1');
			}
		},
		{
			markup: () => {
				console.log('markup-2');
			},
			script: () => {
				console.log('script-2');
			},
			style: () => {
				console.log('style-2');
			}
		}
	],
	{
		filename: 'App.svelte'
	}
);

// Svelte 3 logs:
// markup-1
// markup-2
// script-1
// script-2
// style-1
// style-2

// Svelte 4 logs:
// markup-1
// script-1
// style-1
// markup-2
// script-2
// style-2
```

This could affect you for example if you are using `MDsveX` - in which case you should make sure it comes before any script or style preprocessor.

```js
// @noErrors
preprocess: [
---	vitePreprocess(),
	mdsvex(mdsvexConfig)---
+++	mdsvex(mdsvexConfig),
	vitePreprocess()+++
]
```

Each preprocessor must also have a name. ([#8618](https://github.com/sveltejs/svelte/issues/8618))

## New eslint package

`eslint-plugin-svelte3` is deprecated. It may still work with Svelte 4 but we make no guarantees about that. We recommend switching to our new package [eslint-plugin-svelte](https://github.com/sveltejs/eslint-plugin-svelte). See [this Github post](https://github.com/sveltejs/kit/issues/10242#issuecomment-1610798405) for an instruction how to migrate. Alternatively, you can create a new project using `npm create svelte@latest`, select the eslint (and possibly TypeScript) option and then copy over the related files into your existing project.

## Other breaking changes

- the `inert` attribute is now applied to outroing elements to make them invisible to assistive technology and prevent interaction. ([#8628](https://github.com/sveltejs/svelte/pull/8628))
- the runtime now uses `classList.toggle(name, boolean)` which may not work in very old browsers. Consider using a [polyfill](https://github.com/eligrey/classList.js) if you need to support these browsers. ([#8629](https://github.com/sveltejs/svelte/issues/8629))
- the runtime now uses the `CustomEvent` constructor which may not work in very old browsers. Consider using a [polyfill](https://github.com/theftprevention/event-constructor-polyfill/tree/master) if you need to support these browsers. ([#8775](https://github.com/sveltejs/svelte/pull/8775))
- people implementing their own stores from scratch using the `StartStopNotifier` interface (which is passed to the create function of `writable` etc) from `svelte/store` now need to pass an update function in addition to the set function. This has no effect on people using stores or creating stores using the existing Svelte stores. ([#6750](https://github.com/sveltejs/svelte/issues/6750))
- `derived` will now throw an error on falsy values instead of stores passed to it. ([#7947](https://github.com/sveltejs/svelte/issues/7947))
- type definitions for `svelte/internal` were removed to further discourage usage of those internal methods which are not public API. Most of these will likely change for Svelte 5
- Removal of DOM nodes is now batched which slightly changes its order, which might affect the order of events fired if you're using a `MutationObserver` on these elements ([#8763](https://github.com/sveltejs/svelte/pull/8763))
- if you enhanced the global typings through the `svelte.JSX` namespace before, you need to migrate this to use the `svelteHTML` namespace. Similarly if you used the `svelte.JSX` namespace to use type definitions from it, you need to migrate those to use the types from `svelte/elements` instead. You can find more information about what to do [here](https://github.com/sveltejs/language-tools/blob/master/docs/preprocessors/typescript.md#im-getting-deprecation-warnings-for-sveltejsx--i-want-to-migrate-to-the-new-typings)
````

----
url: https://svelte.dev/docs/svelte/$props/llms.txt
----

````
The inputs to a component are referred to as _props_, which is short for _properties_. You pass props to components just like you pass attributes to elements:

```svelte
<!--- file: App.svelte --->
<script>
	import MyComponent from './MyComponent.svelte';
</script>

<MyComponent adjective="cool" />
```

On the other side, inside `MyComponent.svelte`, we can receive props with the `$props` rune...

```svelte
<!--- file: MyComponent.svelte --->
<script>
	let props = $props();
</script>

<p>this component is {props.adjective}</p>
```

...though more commonly, you'll [_destructure_](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment) your props:

```svelte
<!--- file: MyComponent.svelte --->
<script>
	let +++{ adjective }+++ = $props();
</script>

<p>this component is {+++adjective+++}</p>
```

## Fallback values

Destructuring allows us to declare fallback values, which are used if the parent component does not set a given prop (or the value is `undefined`):

```js
let { adjective = 'happy' } = $props();
```

> [!NOTE] Fallback values are not turned into reactive state proxies (see [Updating props](#Updating-props) for more info)

## Renaming props

We can also use the destructuring assignment to rename props, which is necessary if they're invalid identifiers, or a JavaScript keyword like `super`:

```js
let { super: trouper = 'lights are gonna find me' } = $props();
```

## Rest props

Finally, we can use a _rest property_ to get, well, the rest of the props:

```js
let { a, b, c, ...others } = $props();
```

## Updating props

References to a prop inside a component update when the prop itself updates — when `count` changes in `App.svelte`, it will also change inside `Child.svelte`. But the child component is able to temporarily override the prop value, which can be useful for unsaved ephemeral state:

<!-- codeblock:start {"title":"Temporarily updating props","selected":"Child.svelte"} -->
```svelte
<!--- file: App.svelte --->
<script>
	import Child from './Child.svelte';

	let count = $state(0);
</script>

<button onclick={() => (count += 1)}>
	clicks (parent): {count}
</button>

<Child {count} />
```

```svelte
<!--- file: Child.svelte --->
<script>
	let { count } = $props();
</script>

<button onclick={() => (count += 1)}>
	clicks (child): {count}
</button>
```
<!-- codeblock:end -->

While you can temporarily _reassign_ props, you should not _mutate_ props unless they are [bindable]($bindable).

If the prop is a regular object, the mutation will have no effect:

<!-- codeblock:start {"title":"Non-reactive props","selected":"Child.svelte"} -->
```svelte
<!--- file: App.svelte --->
<script>
	import Child from './Child.svelte';
</script>

<Child object={{ count: 0 }} />
```

```svelte
<!--- file: Child.svelte --->
<script>
	let { object } = $props();
</script>

<button onclick={() => {
	// has no effect
	object.count += 1
}}>
	clicks: {object.count}
</button>
```
<!-- codeblock:end -->

If the prop is a reactive state proxy, however, then mutations _will_ have an effect but you will see an [`ownership_invalid_mutation`](runtime-warnings#Client-warnings-ownership_invalid_mutation) warning, because the component is mutating state that does not 'belong' to it:

<!-- codeblock:start {"title":"Invalid mutation","selected":"Child.svelte"} -->
```svelte
<!--- file: App.svelte --->
<script>
	import Child from './Child.svelte';

	let object = $state({count: 0});
</script>

<Child {object} />
```

```svelte
<!--- file: Child.svelte --->
<script>
	let { object } = $props();
</script>

<button onclick={() => {
	// will cause the count below to update,
	// but with a warning. Don't mutate
	// objects you don't own!
	object.count += 1
}}>
	clicks: {object.count}
</button>
```
<!-- codeblock:end -->

The fallback value of a prop not declared with `$bindable` is left untouched — it is not turned into a reactive state proxy — meaning mutations will not cause updates:

<!-- codeblock:start {"title":"Non-reactive fallback props","selected":"Child.svelte"} -->
```svelte
<!--- file: App.svelte --->
<script>
	import Child from './Child.svelte';
</script>

<Child />
```

```svelte
<!--- file: Child.svelte --->
<script>
	let { object = { count: 0 } } = $props();
</script>

<button onclick={() => {
	// has no effect if the fallback value is used
	object.count += 1
}}>
	clicks: {object.count}
</button>
```
<!-- codeblock:end -->

In summary: don't mutate props. Either use callback props to communicate changes, or — if parent and child should share the same object — use the [`$bindable`]($bindable) rune.

## Type safety

You can add type safety to your components by annotating your props, as you would with any other variable declaration. In TypeScript that might look like this...

```svelte
<script lang="ts">
	let { adjective }: { adjective: string } = $props();
</script>
```

...while in JSDoc you can do this:

```svelte
<script>
	/** @type {{ adjective: string }} */
	let { adjective } = $props();
</script>
```

You can, of course, separate the type declaration from the annotation:

```svelte
<script lang="ts">
	interface Props {
		adjective: string;
	}

	let { adjective }: Props = $props();
</script>
```

> [!NOTE] Interfaces for native DOM elements are provided in the `svelte/elements` module (see [Typing wrapper components](typescript#Typing-wrapper-components))

If your component exposes [snippet](snippet) props like `children`, these should be typed using the `Snippet` interface imported from `'svelte'` — see [Typing snippets](snippet#Typing-snippets) for examples.

Adding types is recommended, as it ensures that people using your component can easily discover which props they should provide.


## `$props.id()`

This rune, added in version 5.20.0, generates an ID that is unique to the current component instance. When hydrating a server-rendered component, the value will be consistent between server and client.

This is useful for linking elements via attributes like `for` and `aria-labelledby`.

```svelte
<script>
	const uid = $props.id();
</script>

<form>
	<label for="{uid}-firstname">First Name: </label>
	<input id="{uid}-firstname" type="text" />

	<label for="{uid}-lastname">Last Name: </label>
	<input id="{uid}-lastname" type="text" />
</form>
```
````

----
url: https://svelte.dev/docs/svelte/lifecycle-hooks/llms.txt
----

````
<!-- - onMount/onDestroy
- mention that `$effect` might be better for your use case
- beforeUpdate/afterUpdate with deprecation notice?
- or skip this entirely and only have it in the reference docs? -->

In Svelte 5, the component lifecycle consists of only two parts: Its creation and its destruction. Everything in-between — when certain state is updated — is not related to the component as a whole; only the parts that need to react to the state change are notified. This is because under the hood the smallest unit of change is actually not a component, it's the (render) effects that the component sets up upon component initialization. Consequently, there's no such thing as a "before update"/"after update" hook.

## `onMount`

The `onMount` function schedules a callback to run as soon as the component has been mounted to the DOM. It must be called during the component's initialisation (but doesn't need to live _inside_ the component; it can be called from an external module).

`onMount` does not run inside a component that is rendered on the server.

```svelte
<script>
	import { onMount } from 'svelte';

	onMount(() => {
		console.log('the component has mounted');
	});
</script>
```

If a function is returned from `onMount`, it will be called when the component is unmounted.

```svelte
<script>
	import { onMount } from 'svelte';

	onMount(() => {
		const interval = setInterval(() => {
			console.log('beep');
		}, 1000);

		return () => clearInterval(interval);
	});
</script>
```

> [!NOTE] This behaviour will only work when the function passed to `onMount` is _synchronous_. `async` functions always return a `Promise`.

## `onDestroy`

Schedules a callback to run immediately before the component is unmounted.

Out of `onMount`, `beforeUpdate`, `afterUpdate` and `onDestroy`, this is the only one that runs inside a server-side component.

```svelte
<script>
	import { onDestroy } from 'svelte';

	onDestroy(() => {
		console.log('the component is being destroyed');
	});
</script>
```

## `tick`

While there's no "after update" hook, you can use `tick` to ensure that the UI is updated before continuing. `tick` returns a promise that resolves once any pending state changes have been applied, or in the next microtask if there are none.

```svelte
<script>
	import { tick } from 'svelte';

	$effect.pre(() => {
		console.log('the component is about to update');
		tick().then(() => {
				console.log('the component just updated');
		});
	});
</script>
```

## Deprecated: `beforeUpdate` / `afterUpdate`

Svelte 4 contained hooks that ran before and after the component as a whole was updated. For backwards compatibility, these hooks were shimmed in Svelte 5 but not available inside components that use runes.

```svelte
<script>
	import { beforeUpdate, afterUpdate } from 'svelte';

	beforeUpdate(() => {
		console.log('the component is about to update');
	});

	afterUpdate(() => {
		console.log('the component just updated');
	});
</script>
```

Instead of `beforeUpdate` use `$effect.pre` and instead of `afterUpdate` use `$effect` instead — these runes offer more granular control and only react to the changes you're actually interested in.

### Chat window example

To implement a chat window that autoscrolls to the bottom when new messages appear (but only if you were _already_ scrolled to the bottom), we need to measure the DOM before we update it.

In Svelte 4, we do this with `beforeUpdate`, but this is a flawed approach — it fires before _every_ update, whether it's relevant or not. In the example below, we need to introduce checks like `updatingMessages` to make sure we don't mess with the scroll position when someone toggles dark mode.

With runes, we can use `$effect.pre`, which behaves the same as `$effect` but runs before DOM updates scheduled after it (see [$effect.pre]($effect#$effect.pre) for the exact ordering). As long as we explicitly reference `messages` inside the effect body, it will run whenever `messages` changes, but _not_ when `theme` changes.

`beforeUpdate`, and its equally troublesome counterpart `afterUpdate`, are therefore deprecated in Svelte 5.

- Before
- After

<!-- prettier-ignore -->
```svelte
<script>
	import { ---beforeUpdate, afterUpdate,--- tick } from 'svelte';

	---let updatingMessages = false;---
	let theme = +++$state('dark')+++;
	let messages = +++$state([])+++;

	let viewport;

	---beforeUpdate(() => {---
	+++$effect.pre(() => {+++
		---if (!updatingMessages) return;---
		+++messages;+++
		const autoscroll = viewport && viewport.offsetHeight + viewport.scrollTop > viewport.scrollHeight - 50;

		if (autoscroll) {
			tick().then(() => {
				viewport.scrollTo(0, viewport.scrollHeight);
			});
		}

		---updatingMessages = false;---
	});

	function handleKeydown(event) {
		if (event.key === 'Enter') {
			const text = event.target.value;
			if (!text) return;

			---updatingMessages = true;---
			messages = [...messages, text];
			event.target.value = '';
		}
	}

	function toggle() {
		theme = theme === 'dark' ? 'light' : 'dark';
	}
</script>

<div class:dark={theme === 'dark'}>
	<div bind:this={viewport}>
		{#each messages as message}
			<p>{message}</p>
		{/each}
	</div>

	<input +++onkeydown+++={handleKeydown} />

	<button +++onclick+++={toggle}> Toggle dark mode </button>
</div>
```
````

----
url: https://svelte.dev/docs/svelte/compiler-warnings/llms.txt
----

````
Svelte warns you at compile time if it catches potential mistakes, such as writing inaccessible markup.

Some warnings may be incorrect in your concrete use case. You can disable such false positives by placing a `<!-- svelte-ignore <code> -->` comment above the line that causes the warning. Example:

```svelte
<!-- svelte-ignore a11y_autofocus -->
<input autofocus />
```

You can list multiple rules in a single comment (separated by commas), and add an explanatory note (in parentheses) alongside them:

```svelte
<!-- svelte-ignore a11y_click_events_have_key_events, a11y_no_static_element_interactions (because of reasons) -->
<div onclick>...</div>
```

<!-- This file is generated by scripts/process-messages/index.js. Do not edit! -->

### a11y_accesskey

```
Avoid using accesskey
```

Enforce no `accesskey` on element. Access keys are HTML attributes that allow web developers to assign keyboard shortcuts to elements. Inconsistencies between keyboard shortcuts and keyboard commands used by screen reader and keyboard-only users create accessibility complications. To avoid complications, access keys should not be used.

<!-- prettier-ignore -->
```svelte
<!-- A11y: Avoid using accesskey -->
<div accesskey="z"></div>
```

### a11y_aria_activedescendant_has_tabindex

```
An element with an aria-activedescendant attribute should have a tabindex value
```

An element with `aria-activedescendant` must be tabbable, so it must either have an inherent `tabindex` or declare `tabindex` as an attribute.

```svelte
<!-- A11y: Elements with attribute aria-activedescendant should have tabindex value -->
<div aria-activedescendant="some-id"></div>
```

### a11y_aria_attributes

```
`<%name%>` should not have aria-* attributes
```

Certain reserved DOM elements do not support ARIA roles, states and properties. This is often because they are not visible, for example `meta`, `html`, `script`, `style`. This rule enforces that these DOM elements do not contain the `aria-*` props.

```svelte
<!-- A11y: <meta> should not have aria-* attributes -->
<meta aria-hidden="false" />
```

### a11y_autocomplete_valid

```
'%value%' is an invalid value for 'autocomplete' on `<input type="%type%">`
```

### a11y_autofocus

```
Avoid using autofocus
```

Enforce that `autofocus` is not used on elements. Autofocusing elements can cause usability issues for sighted and non-sighted users alike.

```svelte
<!-- A11y: Avoid using autofocus -->
<input autofocus />
```

### a11y_click_events_have_key_events

```
Visible, non-interactive element `<%element%>` with a click event must be accompanied by a keyboard event handler. Consider whether an interactive element such as `<button type="button">` or `<a>` might be more appropriate
```

Enforce that visible, non-interactive elements with an `onclick` event are accompanied by a keyboard event handler.

Users should first consider whether an interactive element might be more appropriate such as a `<button type="button">` element for actions or `<a>` element for navigations. These elements are more semantically meaningful and will have built-in key handling. E.g. `Space` and `Enter` will trigger a `<button>` and `Enter` will trigger an `<a>` element.

If a non-interactive element is required then `onclick` should be accompanied by an `onkeyup` or `onkeydown` handler that enables the user to perform equivalent actions via the keyboard. In order for the user to be able to trigger a key press, the element will also need to be focusable by adding a [`tabindex`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex). While an `onkeypress` handler will also silence this warning, it should be noted that the `keypress` event is deprecated.

```svelte
<!-- A11y: visible, non-interactive elements with an onclick event must be accompanied by a keyboard event handler. -->
<div onclick={() => {}}></div>
```

Coding for the keyboard is important for users with physical disabilities who cannot use a mouse, AT compatibility, and screenreader users.

### a11y_consider_explicit_label

```
Buttons and links should either contain text or have an `aria-label`, `aria-labelledby` or `title` attribute
```

### a11y_distracting_elements

```
Avoid `<%name%>` elements
```

Enforces that no distracting elements are used. Elements that can be visually distracting can cause accessibility issues with visually impaired users. Such elements are most likely deprecated, and should be avoided.

The following elements are visually distracting: `<marquee>` and `<blink>`.

```svelte
<!-- A11y: Avoid <marquee> elements -->
<marquee></marquee>
```

### a11y_figcaption_index

```
`<figcaption>` must be first or last child of `<figure>`
```

### a11y_figcaption_parent

```
`<figcaption>` must be an immediate child of `<figure>`
```

Enforce that certain DOM elements have the correct structure.

```svelte
<!-- A11y: <figcaption> must be an immediate child of <figure> -->
<div>
	<figcaption>Image caption</figcaption>
</div>
```

### a11y_hidden

```
`<%name%>` element should not be hidden
```

Certain DOM elements are useful for screen reader navigation and should not be hidden.

<!-- prettier-ignore -->
```svelte
<!-- A11y: <h2> element should not be hidden -->
<h2 aria-hidden="true">invisible header</h2>
```

### a11y_img_redundant_alt

```
Screenreaders already announce `<img>` elements as an image
```

Enforce img alt attribute does not contain the word image, picture, or photo. Screen readers already announce `img` elements as an image. There is no need to use words such as _image_, _photo_, and/or _picture_.

```svelte
<img src="foo" alt="Foo eating a sandwich." />

<!-- aria-hidden, won't be announced by screen reader -->
<img src="bar" aria-hidden="true" alt="Picture of me taking a photo of an image" />

<!-- A11y: Screen readers already announce <img> elements as an image. -->
<img src="foo" alt="Photo of foo being weird." />

<!-- A11y: Screen readers already announce <img> elements as an image. -->
<img src="bar" alt="Image of me at a bar!" />

<!-- A11y: Screen readers already announce <img> elements as an image. -->
<img src="foo" alt="Picture of baz fixing a bug." />
```

### a11y_incorrect_aria_attribute_type

```
The value of '%attribute%' must be a %type%
```

Enforce that only the correct type of value is used for aria attributes. For example, `aria-hidden`
should only receive a boolean.

```svelte
<!-- A11y: The value of 'aria-hidden' must be exactly one of true or false -->
<div aria-hidden="yes"></div>
```

### a11y_incorrect_aria_attribute_type_boolean

```
The value of '%attribute%' must be either 'true' or 'false'. It cannot be empty
```

### a11y_incorrect_aria_attribute_type_id

```
The value of '%attribute%' must be a string that represents a DOM element ID
```

### a11y_incorrect_aria_attribute_type_idlist

```
The value of '%attribute%' must be a space-separated list of strings that represent DOM element IDs
```

### a11y_incorrect_aria_attribute_type_integer

```
The value of '%attribute%' must be an integer
```

### a11y_incorrect_aria_attribute_type_token

```
The value of '%attribute%' must be exactly one of %values%
```

### a11y_incorrect_aria_attribute_type_tokenlist

```
The value of '%attribute%' must be a space-separated list of one or more of %values%
```

### a11y_incorrect_aria_attribute_type_tristate

```
The value of '%attribute%' must be exactly one of true, false, or mixed
```

### a11y_interactive_supports_focus

```
Elements with the '%role%' interactive role must have a tabindex value
```

Enforce that elements with an interactive role and interactive handlers (mouse or key press) must be focusable or tabbable.

```svelte
<!-- A11y: Elements with the 'button' interactive role must have a tabindex value. -->
<div role="button" onkeypress={() => {}} />
```

### a11y_invalid_attribute

```
'%href_value%' is not a valid %href_attribute% attribute
```

Enforce that attributes important for accessibility have a valid value. For example, `href` should not be empty, `'#'`, or `javascript:`.

```svelte
<!-- A11y: '' is not a valid href attribute -->
<a href="">invalid</a>
```

### a11y_label_has_associated_control

```
A form label must be associated with a control
```

Enforce that a label tag has a text label and an associated control.

There are two supported ways to associate a label with a control:

- Wrapping a control in a label tag.
- Adding `for` to a label and assigning it the ID of an input on the page.

```svelte
<label for="id">B</label>

<label>C <input type="text" /></label>

<!-- A11y: A form label must be associated with a control. -->
<label>A</label>
```

### a11y_media_has_caption

```
`<video>` elements must have a `<track kind="captions">`
```

Providing captions for media is essential for deaf users to follow along. Captions should be a transcription or translation of the dialogue, sound effects, relevant musical cues, and other relevant audio information. Not only is this important for accessibility, but can also be useful for all users in the case that the media is unavailable (similar to `alt` text on an image when an image is unable to load).

The captions should contain all important and relevant information to understand the corresponding media. This may mean that the captions are not a 1:1 mapping of the dialogue in the media content. However, captions are not necessary for video components with the `muted` attribute.

```svelte
<video><track kind="captions" /></video>

<audio muted></audio>

<!-- A11y: Media elements must have a <track kind=\"captions\"> -->
<video></video>

<!-- A11y: Media elements must have a <track kind=\"captions\"> -->
<video><track /></video>
```

### a11y_misplaced_role

```
`<%name%>` should not have role attribute
```

Certain reserved DOM elements do not support ARIA roles, states and properties. This is often because they are not visible, for example `meta`, `html`, `script`, `style`. This rule enforces that these DOM elements do not contain the `role` props.

```svelte
<!-- A11y: <meta> should not have role attribute -->
<meta role="tooltip" />
```

### a11y_misplaced_scope

```
The scope attribute should only be used with `<th>` elements
```

The scope attribute should only be used on `<th>` elements.

<!-- prettier-ignore -->
```svelte
<!-- A11y: The scope attribute should only be used with <th> elements -->
<div scope="row" />
```

### a11y_missing_attribute

```
`<%name%>` element should have %article% %sequence% attribute
```

Enforce that attributes required for accessibility are present on an element. This includes the following checks:

- `<a>` should have an href (unless it's a [fragment-defining tag](https://github.com/sveltejs/svelte/issues/4697))
- `<area>` should have alt, aria-label, or aria-labelledby
- `<html>` should have lang
- `<iframe>` should have title
- `<img>` should have alt
- `<object>` should have title, aria-label, or aria-labelledby
- `<input type="image">` should have alt, aria-label, or aria-labelledby

```svelte
<!-- A11y: <input type=\"image\"> element should have an alt, aria-label or aria-labelledby attribute -->
<input type="image" />

<!-- A11y: <html> element should have a lang attribute -->
<html></html>

<!-- A11y: <a> element should have an href attribute -->
<a>text</a>
```

### a11y_missing_content

```
`<%name%>` element should contain text
```

Enforce that heading elements (`h1`, `h2`, etc.) and anchors have content and that the content is accessible to screen readers

```svelte
<!-- A11y: <a> element should have child content -->
<a href="/foo"></a>

<!-- A11y: <h1> element should have child content -->
<h1></h1>
```

### a11y_mouse_events_have_key_events

```
'%event%' event must be accompanied by '%accompanied_by%' event
```

Enforce that `onmouseover` and `onmouseout` are accompanied by `onfocus` (or `onfocusin`) and `onblur` (or `onfocusout`), respectively. This helps to ensure that any functionality triggered by these mouse events is also accessible to keyboard users.

```svelte
<!-- A11y: onmouseover must be accompanied by onfocus -->
<div onmouseover={handleMouseover} />

<!-- A11y: onmouseout must be accompanied by onblur -->
<div onmouseout={handleMouseout} />
```

### a11y_no_abstract_role

```
Abstract role '%role%' is forbidden
```

### a11y_no_interactive_element_to_noninteractive_role

```
`<%element%>` cannot have role '%role%'
```

[WAI-ARIA](https://www.w3.org/TR/wai-aria-1.1/#usage_intro) roles should not be used to convert an interactive element to a non-interactive element. Non-interactive ARIA roles include `article`, `banner`, `complementary`, `img`, `listitem`, `main`, `region` and `tooltip`.

```svelte
<!-- A11y: <textarea> cannot have role 'listitem' -->
<textarea role="listitem"></textarea>
```

### a11y_no_noninteractive_element_interactions

```
Non-interactive element `<%element%>` should not be assigned mouse or keyboard event listeners
```

A non-interactive element does not support event handlers (mouse and key handlers). Non-interactive elements include `<main>`, `<area>`, `<h1>` (,`<h2>`, etc), `<p>`, `<img>`, `<li>`, `<ul>` and `<ol>`. Non-interactive [WAI-ARIA roles](https://www.w3.org/TR/wai-aria-1.1/#usage_intro) include `article`, `banner`, `complementary`, `img`, `listitem`, `main`, `region` and `tooltip`.

```sv
<!-- `A11y: Non-interactive element <li> should not be assigned mouse or keyboard event listeners.` -->
<li onclick={() => {}}></li>

<!-- `A11y: Non-interactive element <div> should not be assigned mouse or keyboard event listeners.` -->
<div role="listitem" onclick={() => {}}></div>
```

### a11y_no_noninteractive_element_to_interactive_role

```
Non-interactive element `<%element%>` cannot have interactive role '%role%'
```

[WAI-ARIA](https://www.w3.org/TR/wai-aria-1.1/#usage_intro) roles should not be used to convert a non-interactive element to an interactive element. Interactive ARIA roles include `button`, `link`, `checkbox`, `menuitem`, `menuitemcheckbox`, `menuitemradio`, `option`, `radio`, `searchbox`, `switch` and `textbox`.

```svelte
<!-- A11y: Non-interactive element <h3> cannot have interactive role 'searchbox' -->
<h3 role="searchbox">Button</h3>
```

### a11y_no_noninteractive_tabindex

```
noninteractive element cannot have nonnegative tabIndex value
```

Tab key navigation should be limited to elements on the page that can be interacted with.

<!-- prettier-ignore -->
```svelte
<!-- A11y: noninteractive element cannot have nonnegative tabIndex value -->
<div tabindex="0"></div>
```

### a11y_no_redundant_roles

```
Redundant role '%role%'
```

Some HTML elements have default ARIA roles. Giving these elements an ARIA role that is already set by the browser [has no effect](https://www.w3.org/TR/using-aria/#aria-does-nothing) and is redundant.

```svelte
<!-- A11y: Redundant role 'button' -->
<button role="button">...</button>

<!-- A11y: Redundant role 'img' -->
<img role="img" src="foo.jpg" />
```

### a11y_no_static_element_interactions

```
`<%element%>` with a %handler% handler must have an ARIA role
```

Elements like `<div>` with interactive handlers like `click` must have an ARIA role.

<!-- prettier-ignore -->
```svelte
<!-- A11y: <div> with click handler must have an ARIA role -->
<div onclick={() => ''}></div>
```

### a11y_positive_tabindex

```
Avoid tabindex values above zero
```

Avoid positive `tabindex` property values. This will move elements out of the expected tab order, creating a confusing experience for keyboard users.

<!-- prettier-ignore -->
```svelte
<!-- A11y: avoid tabindex values above zero -->
<div tabindex="1"></div>
```

### a11y_role_has_required_aria_props

```
Elements with the ARIA role "%role%" must have the following attributes defined: %props%
```

Elements with ARIA roles must have all required attributes for that role.

```svelte
<!-- A11y: A11y: Elements with the ARIA role "checkbox" must have the following attributes defined: "aria-checked" -->
<span role="checkbox" aria-labelledby="foo" tabindex="0"></span>
```

### a11y_role_supports_aria_props

```
The attribute '%attribute%' is not supported by the role '%role%'
```

Elements with explicit or implicit roles defined contain only `aria-*` properties supported by that role.

```svelte
<!-- A11y: The attribute 'aria-multiline' is not supported by the role 'link'. -->
<div role="link" aria-multiline></div>

<!-- A11y: The attribute 'aria-required' is not supported by the role 'listitem'. This role is implicit on the element <li>. -->
<li aria-required></li>
```

### a11y_role_supports_aria_props_implicit

```
The attribute '%attribute%' is not supported by the role '%role%'. This role is implicit on the element `<%name%>`
```

Elements with explicit or implicit roles defined contain only `aria-*` properties supported by that role.

```svelte
<!-- A11y: The attribute 'aria-multiline' is not supported by the role 'link'. -->
<div role="link" aria-multiline></div>

<!-- A11y: The attribute 'aria-required' is not supported by the role 'listitem'. This role is implicit on the element <li>. -->
<li aria-required></li>
```

### a11y_unknown_aria_attribute

```
Unknown aria attribute 'aria-%attribute%'
```

```
Unknown aria attribute 'aria-%attribute%'. Did you mean '%suggestion%'?
```

Enforce that only known ARIA attributes are used. This is based on the [WAI-ARIA States and Properties spec](https://www.w3.org/WAI/PF/aria-1.1/states_and_properties).

```svelte
<!-- A11y: Unknown aria attribute 'aria-labeledby' (did you mean 'labelledby'?) -->
<input type="image" aria-labeledby="foo" />
```

### a11y_unknown_role

```
Unknown role '%role%'
```

```
Unknown role '%role%'. Did you mean '%suggestion%'?
```

Elements with ARIA roles must use a valid, non-abstract ARIA role. A reference to role definitions can be found at [WAI-ARIA](https://www.w3.org/TR/wai-aria/#role_definitions) site.

<!-- prettier-ignore -->
```svelte
<!-- A11y: Unknown role 'toooltip' (did you mean 'tooltip'?) -->
<div role="toooltip"></div>
```

### attribute_avoid_is

```
The "is" attribute is not supported cross-browser and should be avoided
```

### attribute_global_event_reference

```
You are referencing `globalThis.%name%`. Did you forget to declare a variable with that name?
```

### attribute_illegal_colon

```
Attributes should not contain ':' characters to prevent ambiguity with Svelte directives
```

### attribute_invalid_property_name

```
'%wrong%' is not a valid HTML attribute. Did you mean '%right%'?
```

### attribute_quoted

```
Quoted attributes on components and custom elements will be stringified in a future version of Svelte. If this isn't what you want, remove the quotes
```

### bidirectional_control_characters

```
A bidirectional control character was detected in your code. These characters can be used to alter the visual direction of your code and could have unintended consequences
```

Bidirectional control characters can alter the direction in which text appears to be in. For example, via control characters, you can make `defabc` look like `abcdef`. As a result, if you were to unknowingly copy and paste some code that has these control characters, they may alter the behavior of your code in ways you did not intend. See [trojansource.codes](https://trojansource.codes/) for more information.

### bind_invalid_each_rest

```
The rest operator (...) will create a new object and binding '%name%' with the original object will not work
```

### block_empty

```
Empty block
```

### component_name_lowercase

```
`<%name%>` will be treated as an HTML element unless it begins with a capital letter
```

### css_unused_selector

```
Unused CSS selector "%name%"
```

Svelte traverses both the template and the `<style>` tag to find out which of the CSS selectors are not used within the template, so it can remove them.

In some situations a selector may target an element that is not 'visible' to the compiler, for example because it is part of an `{@html ...}` tag or you're overriding styles in a child component. In these cases, use [`:global`](/docs/svelte/global-styles) to preserve the selector as-is:

```svelte
<div class="post">{@html content}</div>

<style>
  .post :global {
    p {...}
  }
</style>
```

### custom_element_props_identifier

```
Using a rest element or a non-destructured declaration with `$props()` means that Svelte can't infer what properties to expose when creating a custom element. Consider destructuring all the props or explicitly specifying the `customElement.props` option.
```

### element_implicitly_closed

```
This element is implicitly closed by the following `%tag%`, which can cause an unexpected DOM structure. Add an explicit `%closing%` to avoid surprises.
```

In HTML, some elements are implicitly closed by another element. For example, you cannot nest a `<p>` inside another `<p>`:

```html
<!-- this HTML... -->
<p><p>hello</p>

<!-- results in this DOM structure -->
<p></p>
<p>hello</p>
```

Similarly, a parent element's closing tag will implicitly close all child elements, even if the `</` was a typo and you meant to create a _new_ element. To avoid ambiguity, it's always a good idea to have an explicit closing tag.

### element_invalid_self_closing_tag

```
Self-closing HTML tags for non-void elements are ambiguous — use `<%name% ...></%name%>` rather than `<%name% ... />`
```

In HTML, there's [no such thing as a self-closing tag](https://jakearchibald.com/2023/against-self-closing-tags-in-html/). While this _looks_ like a self-contained element with some text next to it...

```html
<div>
	<span class="icon" /> some text!
</div>
```

...a spec-compliant HTML parser (such as a browser) will in fact parse it like this, with the text _inside_ the icon:

```html
<div>
	<span class="icon"> some text! </span>
</div>
```

Some templating languages (including Svelte) will 'fix' HTML by turning `<span />` into `<span></span>`. Others adhere to the spec. Both result in ambiguity and confusion when copy-pasting code between different contexts, so Svelte prompts you to resolve the ambiguity directly by having an explicit closing tag.

To automate this, run the dedicated migration:

```sh
npx sv migrate self-closing-tags
```

In a future version of Svelte, self-closing tags may be upgraded from a warning to an error.

### event_directive_deprecated

```
Using `on:%name%` to listen to the %name% event is deprecated. Use the event attribute `on%name%` instead
```

See [the migration guide](v5-migration-guide#Event-changes) for more info.

### export_let_unused

```
Component has unused export property '%name%'. If it is for external reference only, please consider using `export const %name%`
```

### legacy_code

```
`%code%` is no longer valid — please use `%suggestion%` instead
```

### legacy_component_creation

```
Svelte 5 components are no longer classes. Instantiate them using `mount` or `hydrate` (imported from 'svelte') instead.
```

See the [migration guide](v5-migration-guide#Components-are-no-longer-classes) for more info.

### node_invalid_placement_ssr

```
%message%. When rendering this component on the server, the resulting HTML will be modified by the browser (by moving, removing, or inserting elements), likely resulting in a `hydration_mismatch` warning
```

HTML restricts where certain elements can appear. In case of a violation the browser will 'repair' the HTML in a way that breaks Svelte's assumptions about the structure of your components. Some examples:

- `<p>hello <div>world</div></p>` will result in `<p>hello </p><div>world</div><p></p>` (the `<div>` autoclosed the `<p>` because `<p>` cannot contain block-level elements)
- `<option><div>option a</div></option>` will result in `<option>option a</option>` (the `<div>` is removed)
- `<table><tr><td>cell</td></tr></table>` will result in `<table><tbody><tr><td>cell</td></tr></tbody></table>` (a `<tbody>` is auto-inserted)

This code will work when the component is rendered on the client (which is why this is a warning rather than an error), but if you use server rendering it will cause hydration to fail.

### non_reactive_update

```
`%name%` is updated, but is not declared with `$state(...)`. Changing its value will not correctly trigger updates
```

This warning is thrown when the compiler detects the following:
- a variable was declared without `$state` or `$state.raw`
- the variable is reassigned
- the variable is read in a reactive context

In this case, changing the value will not correctly trigger updates. Example:

```svelte
<script>
	let reactive = $state('reactive');
	let stale = 'stale';
</script>

<p>This value updates: {reactive}</p>
<p>This value does not update: {stale}</p>

<button onclick={() => {
	stale = 'updated';
	reactive = 'updated';
}}>update</button>
```

To fix this, wrap your variable declaration with `$state`.

### options_deprecated_accessors

```
The `accessors` option has been deprecated. It will have no effect in runes mode
```

### options_deprecated_immutable

```
The `immutable` option has been deprecated. It will have no effect in runes mode
```

### options_missing_custom_element

```
The `customElement` option is used when generating a custom element. Did you forget the `customElement: true` compile option?
```

### options_removed_enable_sourcemap

```
The `enableSourcemap` option has been removed. Source maps are always generated now, and tooling can choose to ignore them
```

### options_removed_hydratable

```
The `hydratable` option has been removed. Svelte components are always hydratable now
```

### options_removed_loop_guard_timeout

```
The `loopGuardTimeout` option has been removed
```

### options_renamed_ssr_dom

```
`generate: "dom"` and `generate: "ssr"` options have been renamed to "client" and "server" respectively
```

### perf_avoid_inline_class

```
Avoid 'new class' — instead, declare the class at the top level scope
```

### perf_avoid_nested_class

```
Avoid declaring classes below the top level scope
```

### reactive_declaration_invalid_placement

```
Reactive declarations only exist at the top level of the instance script
```

### reactive_declaration_module_script_dependency

```
Reassignments of module-level declarations will not cause reactive statements to update
```

### script_context_deprecated

```
`context="module"` is deprecated, use the `module` attribute instead
```

```svelte
<script ---context="module"--- +++module+++>
	let foo = 'bar';
</script>
```

### script_unknown_attribute

```
Unrecognised attribute — should be one of `generics`, `lang` or `module`. If this exists for a preprocessor, ensure that the preprocessor removes it
```

### slot_element_deprecated

```
Using `<slot>` to render parent content is deprecated. Use `{@render ...}` tags instead
```

See [the migration guide](v5-migration-guide#Snippets-instead-of-slots) for more info.

### state_referenced_locally

```
This reference only captures the initial value of `%name%`. Did you mean to reference it inside a %type% instead?
```

This warning is thrown when the compiler detects the following:

- A reactive variable is declared
- ...and later reassigned...
- ...and referenced in the same scope

This 'breaks the link' to the original state declaration. For example, if you pass the state to a function, the function loses access to the state once it is reassigned:

```svelte
<!--- file: Parent.svelte --->
<script>
	import { setContext } from 'svelte';

	let count = $state(0);

	// warning: state_referenced_locally
	setContext('count', count);
</script>

<button onclick={() => count++}>
	increment
</button>
```

```svelte
<!--- file: Child.svelte --->
<script>
	import { getContext } from 'svelte';

	const count = getContext('count');
</script>

<!-- This will never update -->
<p>The count is {count}</p>
```

To fix this, reference the variable such that it is lazily evaluated. For the above example, this can be achieved by wrapping `count` in a function:

```svelte
<!--- file: Parent.svelte --->
<script>
	import { setContext } from 'svelte';

	let count = $state(0);
	setContext('count', +++() => count+++);
</script>

<button onclick={() => count++}>
	increment
</button>
```

```svelte
<!--- file: Child.svelte --->
<script>
	import { getContext } from 'svelte';

	const count = getContext('count');
</script>

<!-- This will update -->
<p>The count is {+++count()+++}</p>
```

For more info, see [Passing state into functions]($state#Passing-state-into-functions).

### store_rune_conflict

```
It looks like you're using the `$%name%` rune, but there is a local binding called `%name%`. Referencing a local variable with a `$` prefix will create a store subscription. Please rename `%name%` to avoid the ambiguity
```

### svelte_component_deprecated

```
`<svelte:component>` is deprecated in runes mode — components are dynamic by default
```

In previous versions of Svelte, the component constructor was fixed when the component was rendered. In other words, if you wanted `<X>` to re-render when `X` changed, you would either have to use `<svelte:component this={X}>` or put the component inside a `{#key X}...{/key}` block.

In Svelte 5 this is no longer true — if `X` changes, `<X>` re-renders.

In some cases `<object.property>` syntax can be used as a replacement; a lowercased variable with property access is recognized as a component in Svelte 5.

For complex component resolution logic, an intermediary, capitalized variable may be necessary. E.g. in places where `@const` can be used:

<!-- prettier-ignore -->
```svelte
{#each items as item}
	---<svelte:component this={item.condition ? Y : Z} />---
	+++{@const Component = item.condition ? Y : Z}+++
	+++<Component />+++
{/each}
```

A derived value may be used in other contexts:

<!-- prettier-ignore -->
```svelte
<script>
	// ...
	let condition = $state(false);
	+++const Component = $derived(condition ? Y : Z);+++
</script>

---<svelte:component this={condition ? Y : Z} />---
+++<Component />+++
```

### svelte_element_invalid_this

```
`this` should be an `{expression}`. Using a string attribute value will cause an error in future versions of Svelte
```

### svelte_self_deprecated

```
`<svelte:self>` is deprecated — use self-imports (e.g. `import %name% from './%basename%'`) instead
```

See [the note in the docs](legacy-svelte-self) for more info.

### unknown_code

```
`%code%` is not a recognised code
```

```
`%code%` is not a recognised code (did you mean `%suggestion%`?)
```
````

----
url: https://svelte.dev/docs/svelte/overview/llms.txt
----

````
Svelte is a framework for building user interfaces on the web. It uses a compiler to turn declarative components written in HTML, CSS and JavaScript...

```svelte
<!--- file: App.svelte --->
<script>
	function greet() {
		alert('Welcome to Svelte!');
	}
</script>

<button onclick={greet}>click me</button>

<style>
	button {
		font-size: 2em;
	}
</style>
```

...into lean, tightly optimized JavaScript.

You can use it to build anything on the web, from standalone components to ambitious full stack apps (using Svelte's companion application framework, [SvelteKit](../kit)) and everything in between.

These pages serve as reference documentation. If you're new to Svelte, we recommend starting with the [interactive tutorial](/tutorial) and coming back here when you have questions.

You can also try Svelte online in the playground.
````

----
url: https://svelte.dev/docs/svelte/await/llms.txt
----

````
```svelte
<!--- copy: false  --->
{#await expression}...{:then name}...{:catch name}...{/await}
```

```svelte
<!--- copy: false  --->
{#await expression}...{:then name}...{/await}
```

```svelte
<!--- copy: false  --->
{#await expression then name}...{/await}
```

```svelte
<!--- copy: false  --->
{#await expression catch name}...{/await}
```

Await blocks allow you to branch on the three possible states of a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) — pending, fulfilled or rejected.

```svelte
{#await promise}
	<!-- promise is pending -->
	<p>waiting for the promise to resolve...</p>
{:then value}
	<!-- promise was fulfilled or not a Promise -->
	<p>The value is {value}</p>
{:catch error}
	<!-- promise was rejected -->
	<p>Something went wrong: {error.message}</p>
{/await}
```

> [!NOTE] During server-side rendering, only the pending branch will be rendered.
>
> If the provided expression is not a `Promise`, only the `:then` branch will be rendered, including during server-side rendering.

The `catch` block can be omitted if you don't need to render anything when the promise rejects (or no error is possible).

```svelte
{#await promise}
	<!-- promise is pending -->
	<p>waiting for the promise to resolve...</p>
{:then value}
	<!-- promise was fulfilled -->
	<p>The value is {value}</p>
{/await}
```

If you don't care about the pending state, you can also omit the initial block.

```svelte
{#await promise then value}
	<p>The value is {value}</p>
{/await}
```

Similarly, if you only want to show the error state, you can omit the `then` block.

```svelte
{#await promise catch error}
	<p>The error is {error}</p>
{/await}
```

> [!NOTE] You can use `#await` with [`import(...)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import) to render components lazily:
>
> ```svelte
> {#await import('./Component.svelte') then { default: Component }}
> 	<Component />
> {/await}
> ```
````

----
url: https://svelte.dev/docs/svelte/in-and-out/llms.txt
----

````
The `in:` and `out:` directives are identical to [`transition:`](transition), except that the resulting transitions are not bidirectional — an `in` transition will continue to 'play' alongside the `out` transition, rather than reversing, if the block is outroed while the transition is in progress. If an out transition is aborted, transitions will restart from scratch.

```svelte
<script>
  import { fade, fly } from 'svelte/transition';

  let visible = $state(false);
</script>

<label>
  <input type="checkbox" bind:checked={visible}>
  visible
</label>

{#if visible}
	<div in:fly={{ y: 200 }} out:fade>flies in, fades out</div>
{/if}
```
````

----
url: https://svelte.dev/docs/svelte/stores
----

[Skip to main content](#main)

A *store* is an object that allows reactive access to a value via a simple *store contract*. The [`svelte/store` module](../svelte-store) contains minimal store implementations which fulfil this contract.

Any time you have a reference to a store, you can access its value inside a component by prefixing it with the `$` character. This causes Svelte to declare the prefixed variable, subscribe to the store at component initialisation and unsubscribe when appropriate.

Assignments to `$`-prefixed variables require that the variable be a writable store, and will result in a call to the store’s `.set` method.

Note that the store must be declared at the top level of the component — not inside an `if` block or a function, for example.

Local variables (that do not represent store values) must *not* have a `$` prefix.

```
<script>
	import { writable } from 'svelte/store';

	const count = writable(0);
	console.log($count); // logs 0

	count.set(1);
	console.log($count); // logs 1

	$count = 2;
	console.log($count); // logs 2
</script>
```

## When to use stores[](#When-to-use-stores)

Prior to Svelte 5, stores were the go-to solution for creating cross-component reactive states or extracting logic. With runes, these use cases have greatly diminished.

* when extracting logic, it’s better to take advantage of runes’ universal reactivity: You can use runes outside the top level of components and even place them into JavaScript or TypeScript files (using a `.svelte.js` or `.svelte.ts` file ending)
* when creating shared state, you can create a `$state` object containing the values you need and then manipulate said state

state.svelte

```
export const userStateconst userState: {
    name: string;
} = $statefunction $state<{
    name: string;
}>(initial: {
    name: string;
}): {
    name: string;
} (+1 overload)
namespace $state

Declares reactive state.




Example:



let count = $state(0);

{@link https://svelte.dev/docs/svelte/$state Documentation}


initial 

The initial value


({
	name(property) name: string: 'name',
	/* ... */
});
```

App

```
<script>
	import { userState } from './state.svelte.js';
</script>

<p>User name: {userState.name}</p>
<button onclick={() => {
	userState.name = 'new name';
}}>
	change name
</button>
```

```
<script lang="ts">
	import { userState } from './state.svelte.js';
</script>

<p>User name: {userState.name}</p>
<button onclick={() => {
	userState.name = 'new name';
}}>
	change name
</button>
```

Stores are still a good solution when you have complex asynchronous data streams or it’s important to have more manual control over updating values or listening to changes. If you’re familiar with RxJs and want to reuse that knowledge, the `$` also comes in handy for you.

## svelte/store[](#svelte-store)

The `svelte/store` module contains a minimal store implementation which fulfil the store contract. It provides methods for creating stores that you can update from the outside, stores you can only update from the inside, and for combining and deriving stores.

### writable[](#svelte-store-writable)

Function that creates a store which has values that can be set from ‘outside’ components. It gets created as an object with additional `set` and `update` methods.

`set` is a method that takes one argument which is the value to be set. The store value gets set to the value of the argument if the store value is not already equal to it.

`update` is a method that takes one argument which is a callback. The callback takes the existing store value as its argument and returns the new value to be set to the store.

store

```
import { writable(alias) function writable<T>(value?: T | undefined, start?: StartStopNotifier<T> | undefined): Writable<T>
import writable

Create a Writable store that allows both updating and reading by subscription.


value 

initial value


reference } from 'svelte/store';

const countconst count: Writable<number> = writable(alias) writable<number>(value?: number | undefined, start?: StartStopNotifier<number> | undefined): Writable<number>
import writable

Create a Writable store that allows both updating and reading by subscription.


value 

initial value


reference(0);

countconst count: Writable<number>.subscribe(method) Readable<number>.subscribe(this: void, run: Subscriber<number>, invalidate?: () => void): Unsubscriber

Subscribe on value changes.


run 

subscription callback


invalidate 

cleanup callback


((value(parameter) value: number) => {
	consolenamespace console
var console: Console

The console module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.




The module exports two specific components:





A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.


A global console instance configured to write to process.stdout and
process.stderr. The global console can be used without importing the node:console module.





Warning: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the note on process I/O for
more information.




Example using the global console:



console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
//   Error: Whoops, something bad happened
//     at [eval]:5:15
//     at Script.runInThisContext (node:vm:132:18)
//     at Object.runInThisContext (node:vm:309:38)
//     at node:internal/process/execution:77:19
//     at [eval]-wrapper:6:22
//     at evalScript (node:internal/process/execution:76:60)
//     at node:internal/main/eval_string:23:3

const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:



const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);

myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err

const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

source


.log(method) Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to printf(3)
(the arguments are all passed to util.format()).



const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.




v0.1.100


(value(parameter) value: number);
}); // logs '0'

countconst count: Writable<number>.set(method) Writable<number>.set(this: void, value: number): void

Set value and inform subscribers.


value 

to set


(1); // logs '1'

countconst count: Writable<number>.update(method) Writable<number>.update(this: void, updater: Updater<number>): void

Update value using callback and inform subscribers.


updater 

callback


((n(parameter) n: number) => n(parameter) n: number + 1); // logs '2'
```

If a function is passed as the second argument, it will be called when the number of subscribers goes from zero to one (but not from one to two, etc). That function will be passed a `set` function which changes the value of the store, and an `update` function which works like the `update` method on the store, taking a callback to calculate the store’s new value from its old value. It must return a `stop` function that is called when the subscriber count goes from one to zero.

store

```
import { writable(alias) function writable<T>(value?: T | undefined, start?: StartStopNotifier<T> | undefined): Writable<T>
import writable

Create a Writable store that allows both updating and reading by subscription.


value 

initial value


reference } from 'svelte/store';

const countconst count: Writable<number> = writable(alias) writable<number>(value?: number | undefined, start?: StartStopNotifier<number> | undefined): Writable<number>
import writable

Create a Writable store that allows both updating and reading by subscription.


value 

initial value


reference(0, () => {
	consolenamespace console
var console: Console

The console module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.




The module exports two specific components:





A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.


A global console instance configured to write to process.stdout and
process.stderr. The global console can be used without importing the node:console module.





Warning: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the note on process I/O for
more information.




Example using the global console:



console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
//   Error: Whoops, something bad happened
//     at [eval]:5:15
//     at Script.runInThisContext (node:vm:132:18)
//     at Object.runInThisContext (node:vm:309:38)
//     at node:internal/process/execution:77:19
//     at [eval]-wrapper:6:22
//     at evalScript (node:internal/process/execution:76:60)
//     at node:internal/main/eval_string:23:3

const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:



const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);

myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err

const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

source


.log(method) Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to printf(3)
(the arguments are all passed to util.format()).



const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.




v0.1.100


('got a subscriber');
	return () => consolenamespace console
var console: Console

The console module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.




The module exports two specific components:





A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.


A global console instance configured to write to process.stdout and
process.stderr. The global console can be used without importing the node:console module.





Warning: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the note on process I/O for
more information.




Example using the global console:



console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
//   Error: Whoops, something bad happened
//     at [eval]:5:15
//     at Script.runInThisContext (node:vm:132:18)
//     at Object.runInThisContext (node:vm:309:38)
//     at node:internal/process/execution:77:19
//     at [eval]-wrapper:6:22
//     at evalScript (node:internal/process/execution:76:60)
//     at node:internal/main/eval_string:23:3

const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:



const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);

myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err

const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

source


.log(method) Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to printf(3)
(the arguments are all passed to util.format()).



const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.




v0.1.100


('no more subscribers');
});

countconst count: Writable<number>.set(method) Writable<number>.set(this: void, value: number): void

Set value and inform subscribers.


value 

to set


(1); // does nothing

const unsubscribeconst unsubscribe: Unsubscriber = countconst count: Writable<number>.subscribe(method) Readable<number>.subscribe(this: void, run: Subscriber<number>, invalidate?: () => void): Unsubscriber

Subscribe on value changes.


run 

subscription callback


invalidate 

cleanup callback


((value(parameter) value: number) => {
	consolenamespace console
var console: Console

The console module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.




The module exports two specific components:





A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.


A global console instance configured to write to process.stdout and
process.stderr. The global console can be used without importing the node:console module.





Warning: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the note on process I/O for
more information.




Example using the global console:



console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
//   Error: Whoops, something bad happened
//     at [eval]:5:15
//     at Script.runInThisContext (node:vm:132:18)
//     at Object.runInThisContext (node:vm:309:38)
//     at node:internal/process/execution:77:19
//     at [eval]-wrapper:6:22
//     at evalScript (node:internal/process/execution:76:60)
//     at node:internal/main/eval_string:23:3

const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:



const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);

myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err

const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

source


.log(method) Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to printf(3)
(the arguments are all passed to util.format()).



const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.




v0.1.100


(value(parameter) value: number);
}); // logs 'got a subscriber', then '1'

unsubscribeconst unsubscribe: () => void(); // logs 'no more subscribers'
```

Note that the value of a `writable` is lost when it is destroyed, for example when the page is refreshed. However, you can write your own logic to sync the value to for example the `localStorage`.

### readable[](#svelte-store-readable)

Creates a store whose value cannot be set from ‘outside’, the first argument is the store’s initial value, and the second argument to `readable` is the same as the second argument to `writable`.

```
import { readable(alias) function readable<T>(value?: T | undefined, start?: StartStopNotifier<T> | undefined): Readable<T>
import readable

Creates a Readable store that allows reading by subscription.


value 

initial value


reference } from 'svelte/store';

const timeconst time: Readable<Date> = readable(alias) readable<Date>(value?: Date | undefined, start?: StartStopNotifier<Date> | undefined): Readable<Date>
import readable

Creates a Readable store that allows reading by subscription.


value 

initial value


reference(new Datevar Date: DateConstructor
new () => Date (+4 overloads)(), (set(parameter) set: (value: Date) => void) => {
	set(parameter) set: (value: Date) => void(new Datevar Date: DateConstructor
new () => Date (+4 overloads)());

	const intervalconst interval: NodeJS.Timeout = setIntervalfunction setInterval<[]>(callback: () => void, delay?: number): NodeJS.Timeout (+3 overloads)

MDN Reference


(() => {
		set(parameter) set: (value: Date) => void(new Datevar Date: DateConstructor
new () => Date (+4 overloads)());
	}, 1000);

	return () => clearIntervalfunction clearInterval(timeout: NodeJS.Timeout | string | number | undefined): void (+2 overloads)

MDN Reference


(intervalconst interval: NodeJS.Timeout);
});

const ticktockconst ticktock: Readable<string> = readable(alias) readable<string>(value?: string | undefined, start?: StartStopNotifier<string> | undefined): Readable<string>
import readable

Creates a Readable store that allows reading by subscription.


value 

initial value


reference('tick', (set(parameter) set: (value: string) => void, update(parameter) update: (fn: Updater<string>) => void) => {
	const intervalconst interval: NodeJS.Timeout = setIntervalfunction setInterval<[]>(callback: () => void, delay?: number): NodeJS.Timeout (+3 overloads)

MDN Reference


(() => {
		update(parameter) update: (fn: Updater<string>) => void((sound(parameter) sound: string) => (sound(parameter) sound: string === 'tick' ? 'tock' : 'tick'));
	}, 1000);

	return () => clearIntervalfunction clearInterval(timeout: NodeJS.Timeout | string | number | undefined): void (+2 overloads)

MDN Reference


(intervalconst interval: NodeJS.Timeout);
});
```

### derived[](#svelte-store-derived)

Derives a store from one or more other stores. The callback runs initially when the first subscriber subscribes and then whenever the store dependencies change.

In the simplest version, `derived` takes a single store, and the callback returns a derived value.

```
import { derived(alias) function derived<S extends Stores, T>(stores: S, fn: (values: StoresValues<S>, set: (value: T) => void, update: (fn: Updater<T>) => void) => Unsubscriber | void, initial_value?: T | undefined): Readable<T> (+1 overload)
import derived

Derived value store by synchronizing one or more readable stores and
applying an aggregation function over its input values.


reference } from 'svelte/store';

const doubledconst doubled: Readable<number> = derived(alias) derived<Writable<number>, number>(stores: Writable<number>, fn: (values: number) => number, initial_value?: number | undefined): Readable<number> (+1 overload)
import derived

Derived value store by synchronizing one or more readable stores and
applying an aggregation function over its input values.


reference(aconst a: Writable<number>, ($a(parameter) $a: number) => $a(parameter) $a: number * 2);
```

The callback can set a value asynchronously by accepting a second argument, `set`, and an optional third argument, `update`, calling either or both of them when appropriate.

In this case, you can also pass a third argument to `derived` — the initial value of the derived store before `set` or `update` is first called. If no initial value is specified, the store’s initial value will be `undefined`.

```
import { derived(alias) function derived<S extends Stores, T>(stores: S, fn: (values: StoresValues<S>, set: (value: T) => void, update: (fn: Updater<T>) => void) => Unsubscriber | void, initial_value?: T | undefined): Readable<T> (+1 overload)
import derived

Derived value store by synchronizing one or more readable stores and
applying an aggregation function over its input values.


reference } from 'svelte/store';

const delayedconst delayed: Readable<number> = derived(alias) derived<Writable<number>, number>(stores: Writable<number>, fn: (values: number, set: (value: number) => void, update: (fn: Updater<number>) => void) => Unsubscriber | void, initial_value?: number | undefined): Readable<number> (+1 overload)
import derived

Derived value store by synchronizing one or more readable stores and
applying an aggregation function over its input values.


reference(
	aconst a: Writable<number>,
	($a(parameter) $a: number, set(parameter) set: (value: number) => void) => {
		setTimeoutfunction setTimeout<[]>(callback: () => void, delay?: number): NodeJS.Timeout (+3 overloads)
namespace setTimeout

MDN Reference


(() => set(parameter) set: (value: number) => void($a(parameter) $a: number), 1000);
	},
	2000
);

const delayedIncrementconst delayedIncrement: Readable<unknown> = derived(alias) derived<Writable<number>, unknown>(stores: Writable<number>, fn: (values: number, set: (value: unknown) => void, update: (fn: Updater<unknown>) => void) => Unsubscriber | void, initial_value?: unknown): Readable<unknown> (+1 overload)
import derived

Derived value store by synchronizing one or more readable stores and
applying an aggregation function over its input values.


reference(aconst a: Writable<number>, ($a(parameter) $a: number, set(parameter) set: (value: unknown) => void, update(parameter) update: (fn: Updater<unknown>) => void) => {
	set(parameter) set: (value: unknown) => void($a(parameter) $a: number);
	setTimeoutfunction setTimeout<[]>(callback: () => void, delay?: number): NodeJS.Timeout (+3 overloads)
namespace setTimeout

MDN Reference


(() => update(parameter) update: (fn: Updater<unknown>) => void((x(parameter) x: unknown) => x(parameter) x: unknown + 1), 1000);
	// every time $a produces a value, this produces two
	// values, $a immediately and then $a + 1 a second later
});
```

If you return a function from the callback, it will be called when a) the callback runs again, or b) the last subscriber unsubscribes.

```
import { derived(alias) function derived<S extends Stores, T>(stores: S, fn: (values: StoresValues<S>, set: (value: T) => void, update: (fn: Updater<T>) => void) => Unsubscriber | void, initial_value?: T | undefined): Readable<T> (+1 overload)
import derived

Derived value store by synchronizing one or more readable stores and
applying an aggregation function over its input values.


reference } from 'svelte/store';

const tickconst tick: Readable<number> = derived(alias) derived<Writable<number>, number>(stores: Writable<number>, fn: (values: number, set: (value: number) => void, update: (fn: Updater<number>) => void) => Unsubscriber | void, initial_value?: number | undefined): Readable<number> (+1 overload)
import derived

Derived value store by synchronizing one or more readable stores and
applying an aggregation function over its input values.


reference(
	frequencyconst frequency: Writable<number>,
	($frequency(parameter) $frequency: number, set(parameter) set: (value: number) => void) => {
		const intervalconst interval: NodeJS.Timeout = setIntervalfunction setInterval<[]>(callback: () => void, delay?: number): NodeJS.Timeout (+3 overloads)

MDN Reference


(() => {
			set(parameter) set: (value: number) => void(Datevar Date: DateConstructor

Enables basic storage and retrieval of dates and times.


.now(method) DateConstructor.now(): number

Returns the number of milliseconds elapsed since midnight, January 1, 1970 Universal Coordinated Time (UTC).


());
		}, 1000 / $frequency(parameter) $frequency: number);

		return () => {
			clearIntervalfunction clearInterval(timeout: NodeJS.Timeout | string | number | undefined): void (+2 overloads)

MDN Reference


(intervalconst interval: NodeJS.Timeout);
		};
	},
	2000
);
```

In both cases, an array of arguments can be passed as the first argument instead of a single store.

```
import { derived(alias) function derived<S extends Stores, T>(stores: S, fn: (values: StoresValues<S>, set: (value: T) => void, update: (fn: Updater<T>) => void) => Unsubscriber | void, initial_value?: T | undefined): Readable<T> (+1 overload)
import derived

Derived value store by synchronizing one or more readable stores and
applying an aggregation function over its input values.


reference } from 'svelte/store';

const summedconst summed: Readable<number> = derived(alias) derived<[Writable<number>, Writable<number>], number>(stores: [Writable<number>, Writable<number>], fn: (values: [number, number]) => number, initial_value?: number | undefined): Readable<number> (+1 overload)
import derived

Derived value store by synchronizing one or more readable stores and
applying an aggregation function over its input values.


reference([aconst a: Writable<number>, bconst b: Writable<number>], ([$a(parameter) $a: number, $b(parameter) $b: number]) => $a(parameter) $a: number + $b(parameter) $b: number);

const delayedconst delayed: Readable<unknown> = derived(alias) derived<[Writable<number>, Writable<number>], unknown>(stores: [Writable<number>, Writable<number>], fn: (values: [number, number], set: (value: unknown) => void, update: (fn: Updater<unknown>) => void) => Unsubscriber | void, initial_value?: unknown): Readable<unknown> (+1 overload)
import derived

Derived value store by synchronizing one or more readable stores and
applying an aggregation function over its input values.


reference([aconst a: Writable<number>, bconst b: Writable<number>], ([$a(parameter) $a: number, $b(parameter) $b: number], set(parameter) set: (value: unknown) => void) => {
	setTimeoutfunction setTimeout<[]>(callback: () => void, delay?: number): NodeJS.Timeout (+3 overloads)
namespace setTimeout

MDN Reference


(() => set(parameter) set: (value: unknown) => void($a(parameter) $a: number + $b(parameter) $b: number), 1000);
});
```

### readonly[](#svelte-store-readonly)

This simple helper function makes a store readonly. You can still subscribe to the changes from the original one using this new readable store.

```
import { readonly(alias) function readonly<T>(store: Readable<T>): Readable<T>
import readonly

Takes a store and returns a new one derived from the old one that is readable.


store 


store to make readonly



reference, writable(alias) function writable<T>(value?: T | undefined, start?: StartStopNotifier<T> | undefined): Writable<T>
import writable

Create a Writable store that allows both updating and reading by subscription.


value 

initial value


reference } from 'svelte/store';

const writableStoreconst writableStore: Writable<number> = writable(alias) writable<number>(value?: number | undefined, start?: StartStopNotifier<number> | undefined): Writable<number>
import writable

Create a Writable store that allows both updating and reading by subscription.


value 

initial value


reference(1);
const readableStoreconst readableStore: Readable<number> = readonly(alias) readonly<number>(store: Readable<number>): Readable<number>
import readonly

Takes a store and returns a new one derived from the old one that is readable.


store 


store to make readonly



reference(writableStoreconst writableStore: Writable<number>);

readableStoreconst readableStore: Readable<number>.subscribe(method) Readable<number>.subscribe(this: void, run: Subscriber<number>, invalidate?: () => void): Unsubscriber

Subscribe on value changes.


run 

subscription callback


invalidate 

cleanup callback


(consolenamespace console
var console: Console

The console module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.




The module exports two specific components:





A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.


A global console instance configured to write to process.stdout and
process.stderr. The global console can be used without importing the node:console module.





Warning: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the note on process I/O for
more information.




Example using the global console:



console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
//   Error: Whoops, something bad happened
//     at [eval]:5:15
//     at Script.runInThisContext (node:vm:132:18)
//     at Object.runInThisContext (node:vm:309:38)
//     at node:internal/process/execution:77:19
//     at [eval]-wrapper:6:22
//     at evalScript (node:internal/process/execution:76:60)
//     at node:internal/main/eval_string:23:3

const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:



const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);

myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err

const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

source


.log(method) Console.log(...data: any[]): void (+1 overload)

The console.log() static method outputs a message to the console.




MDN Reference


);

writableStoreconst writableStore: Writable<number>.set(method) Writable<number>.set(this: void, value: number): void

Set value and inform subscribers.


value 

to set


(2); // console: 2
readableStoreconst readableStore: Readable<number>.setany(2); // ERROR
```

### get[](#svelte-store-get)

Generally, you should read the value of a store by subscribing to it and using the value as it changes over time. Occasionally, you may need to retrieve the value of a store to which you’re not subscribed. `get` allows you to do so.

> This works by creating a subscription, reading the value, then unsubscribing. It’s therefore not recommended in hot code paths.

```
import { get(alias) function get<T>(store: Readable<T>): T
import get

Get the current value from a store by subscribing and immediately unsubscribing.


reference } from 'svelte/store';

const valueconst value: string = get(alias) get<string>(store: Readable<string>): string
import get

Get the current value from a store by subscribing and immediately unsubscribing.


reference(storeconst store: Writable<string>);
```

## Store contract[](#Store-contract)

```
storeany = { subscribe(property) subscribe: (subscription: (value: any) => void) => () => undefined: (subscription(parameter) subscription: (value: any) => void: (value(parameter) value: any: any) => void) => (() => void), set(property) set: (value: any) => undefined?: (value(parameter) value: any: any) => void }
```

You can create your own stores without relying on [`svelte/store`](../svelte-store), by implementing the *store contract*:

1. A store must contain a `.subscribe` method, which must accept as its argument a subscription function. This subscription function must be immediately and synchronously called with the store’s current value upon calling `.subscribe`. All of a store’s active subscription functions must later be synchronously called whenever the store’s value changes.
2. The `.subscribe` method must return an unsubscribe function. Calling an unsubscribe function must stop its subscription, and its corresponding subscription function must not be called again by the store.
3. A store may *optionally* contain a `.set` method, which must accept as its argument a new value for the store, and which synchronously calls all of the store’s active subscription functions. Such a store is called a *writable store*.

For interoperability with RxJS Observables, the `.subscribe` method is also allowed to return an object with an `.unsubscribe` method, rather than return the unsubscription function directly. Note however that unless `.subscribe` synchronously calls the subscription (which is not required by the Observable spec), Svelte will see the value of the store as `undefined` until it does.

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/06-runtime/01-stores.md) [llms.txt](/docs/svelte/stores/llms.txt)

previous next

[\<svelte:options>](/docs/svelte/svelte-options) [Context](/docs/svelte/context)

----
url: https://svelte.dev/docs/svelte/custom-properties/llms.txt
----

````
You can pass CSS custom properties — both static and dynamic — to components:

```svelte
<Slider
	bind:value
	min={0}
	max={100}
	--track-color="black"
	--thumb-color="rgb({r} {g} {b})"
/>
```

The above code essentially desugars to this:

```svelte
<svelte-css-wrapper style="display: contents; --track-color: black; --thumb-color: rgb({r} {g} {b})">
	<Slider
		bind:value
		min={0}
		max={100}
	/>
</svelte-css-wrapper>
```

For an SVG element, it would use `<g>` instead:

```svelte
<g style="--track-color: black; --thumb-color: rgb({r} {g} {b})">
	<Slider
		bind:value
		min={0}
		max={100}
	/>
</g>
```

Inside the component, we can read these custom properties (and provide fallback values) using [`var(...)`](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties):

```svelte
<style>
	.track {
		background: var(--track-color, #aaa);
	}

	.thumb {
		background: var(--thumb-color, blue);
	}
</style>
```

You don't _have_ to specify the values directly on the component; as long as the custom properties are defined on a parent element, the component can use them. It's common to define custom properties on the `:root` element in a global stylesheet so that they apply to your entire application.

> [!NOTE] While the extra element will not affect layout, it _will_ affect any CSS selectors that (for example) use the `>` combinator to target an element directly inside the component's container.
````

----
url: https://svelte.dev/docs/svelte/svelte-files/llms.txt
----

````
Components are the building blocks of Svelte applications. They are written into `.svelte` files, using a superset of HTML.

All three sections — script, styles and markup — are optional.

<!-- prettier-ignore -->
```svelte
/// file: MyComponent.svelte
<script module>
	// module-level logic goes here
	// (you will rarely use this)
</script>

<script>
	// instance-level logic goes here
</script>

<!-- markup (zero or more items) goes here -->

<style>
	/* styles go here */
</style>
```

## `<script>`

A `<script>` block contains JavaScript (or TypeScript, when adding the `lang="ts"` attribute) that runs when a component instance is created. Variables declared (or imported) at the top level can be referenced in the component's markup.

In addition to normal JavaScript, you can use _runes_ to declare [component props]($props) and add reactivity to your component. Runes are covered in the next section.

<!-- TODO describe behaviour of `export` -->

## `<script module>`

A `<script>` tag with a `module` attribute runs once when the module first evaluates, rather than for each component instance. Variables declared in this block can be referenced elsewhere in the component, but not vice versa.

```svelte
<script module>
	let total = 0;
</script>

<script>
	total += 1;
	console.log(`instantiated ${total} times`);
</script>
```

You can `export` bindings from this block, and they will become exports of the compiled module. You cannot `export default`, since the default export is the component itself.

> [!NOTE] If you are using TypeScript and import such exports from a `module` block into a `.ts` file, make sure to have your editor setup so that TypeScript knows about them. This is the case for our VS Code extension and the IntelliJ plugin, but in other cases you might need to setup our [TypeScript editor plugin](https://www.npmjs.com/package/typescript-svelte-plugin).

> [!LEGACY]
> In Svelte 4, this script tag was created using `<script context="module">`

## `<style>`

CSS inside a `<style>` block will be scoped to that component.

```svelte
<style>
	p {
		/* this will only affect <p> elements in this component */
		color: burlywood;
	}
</style>
```

For more information, head to the section on [styling](scoped-styles).
````

----
url: https://svelte.dev/docs/svelte/svelte-transition/llms.txt
----

````
This module provides built-in transition functions for use with the [`transition:`](transition) directive.



```js
// @noErrors
import {
	blur,
	crossfade,
	draw,
	fade,
	fly,
	scale,
	slide
} from 'svelte/transition';
```

## blur

Animates a `blur` filter alongside an element's opacity.

<div class="ts-block">

```dts
function blur(
	node: Element,
	{
		delay,
		duration,
		easing,
		amount,
		opacity
	}?: BlurParams | undefined
): TransitionConfig;
```

</div>



## crossfade

The `crossfade` function creates a pair of [transitions](/docs/svelte/transition) called `send` and `receive`. When an element is 'sent', it looks for a corresponding element being 'received', and generates a transition that transforms the element to its counterpart's position and fades it out. When an element is 'received', the reverse happens. If there is no counterpart, the `fallback` transition is used.

<div class="ts-block">

```dts
function crossfade({
	fallback,
	...defaults
}: CrossfadeParams & {
	fallback?: (
		node: Element,
		params: CrossfadeParams,
		intro: boolean
	) => TransitionConfig;
}): [
	(
		node: any,
		params: CrossfadeParams & {
			key: any;
		}
	) => () => TransitionConfig,
	(
		node: any,
		params: CrossfadeParams & {
			key: any;
		}
	) => () => TransitionConfig
];
```

</div>



## draw

Animates the stroke of an SVG element, like a snake in a tube. `in` transitions begin with the path invisible and draw the path to the screen over time. `out` transitions start in a visible state and gradually erase the path. `draw` only works with elements that have a `getTotalLength` method, like `<path>` and `<polyline>`.

<div class="ts-block">

```dts
function draw(
	node: SVGElement & {
		getTotalLength(): number;
	},
	{
		delay,
		speed,
		duration,
		easing
	}?: DrawParams | undefined
): TransitionConfig;
```

</div>



## fade

Animates the opacity of an element from 0 to the current opacity for `in` transitions and from the current opacity to 0 for `out` transitions.

<div class="ts-block">

```dts
function fade(
	node: Element,
	{ delay, duration, easing }?: FadeParams | undefined
): TransitionConfig;
```

</div>



## fly

Animates the x and y positions and the opacity of an element. `in` transitions animate from the provided values, passed as parameters to the element's default values. `out` transitions animate from the element's default values to the provided values.

<div class="ts-block">

```dts
function fly(
	node: Element,
	{
		delay,
		duration,
		easing,
		x,
		y,
		opacity
	}?: FlyParams | undefined
): TransitionConfig;
```

</div>



## scale

Animates the opacity and scale of an element. `in` transitions animate from the provided values, passed as parameters, to an element's current (default) values. `out` transitions animate from an element's default values to the provided values.

<div class="ts-block">

```dts
function scale(
	node: Element,
	{
		delay,
		duration,
		easing,
		start,
		opacity
	}?: ScaleParams | undefined
): TransitionConfig;
```

</div>



## slide

Slides an element in and out.

<div class="ts-block">

```dts
function slide(
	node: Element,
	{
		delay,
		duration,
		easing,
		axis
	}?: SlideParams | undefined
): TransitionConfig;
```

</div>



## BlurParams

<div class="ts-block">

```dts
interface BlurParams {/*…*/}
```

<div class="ts-block-property">

```dts
delay?: number;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
duration?: number;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
easing?: EasingFunction;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
amount?: number | string;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
opacity?: number;
```

<div class="ts-block-property-details"></div>
</div></div>

## CrossfadeParams

<div class="ts-block">

```dts
interface CrossfadeParams {/*…*/}
```

<div class="ts-block-property">

```dts
delay?: number;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
duration?: number | ((len: number) => number);
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
easing?: EasingFunction;
```

<div class="ts-block-property-details"></div>
</div></div>

## DrawParams

<div class="ts-block">

```dts
interface DrawParams {/*…*/}
```

<div class="ts-block-property">

```dts
delay?: number;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
speed?: number;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
duration?: number | ((len: number) => number);
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
easing?: EasingFunction;
```

<div class="ts-block-property-details"></div>
</div></div>

## EasingFunction

<div class="ts-block">

```dts
type EasingFunction = (t: number) => number;
```

</div>

## FadeParams

<div class="ts-block">

```dts
interface FadeParams {/*…*/}
```

<div class="ts-block-property">

```dts
delay?: number;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
duration?: number;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
easing?: EasingFunction;
```

<div class="ts-block-property-details"></div>
</div></div>

## FlyParams

<div class="ts-block">

```dts
interface FlyParams {/*…*/}
```

<div class="ts-block-property">

```dts
delay?: number;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
duration?: number;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
easing?: EasingFunction;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
x?: number | string;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
y?: number | string;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
opacity?: number;
```

<div class="ts-block-property-details"></div>
</div></div>

## ScaleParams

<div class="ts-block">

```dts
interface ScaleParams {/*…*/}
```

<div class="ts-block-property">

```dts
delay?: number;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
duration?: number;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
easing?: EasingFunction;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
start?: number;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
opacity?: number;
```

<div class="ts-block-property-details"></div>
</div></div>

## SlideParams

<div class="ts-block">

```dts
interface SlideParams {/*…*/}
```

<div class="ts-block-property">

```dts
delay?: number;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
duration?: number;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
easing?: EasingFunction;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
axis?: 'x' | 'y';
```

<div class="ts-block-property-details"></div>
</div></div>

## TransitionConfig

<div class="ts-block">

```dts
interface TransitionConfig {/*…*/}
```

<div class="ts-block-property">

```dts
delay?: number;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
duration?: number;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
easing?: EasingFunction;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
css?: (t: number, u: number) => string;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
tick?: (t: number, u: number) => void;
```

<div class="ts-block-property-details"></div>
</div></div>
````

----
url: https://svelte.dev/docs/svelte/legacy-reactive-assignments
----

[Skip to main content](#main)

In runes mode, reactions to state updates are handled with the [`$derived`]($derived) and [`$effect`]($effect) runes.

In legacy mode, any top-level statement (i.e. not inside a block or a function) can be made reactive by prefixing it with a `$:` [label](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/label). These statements run after other code in the `<script>` and before the component markup is rendered, then whenever the values that they depend on change.

```
<script>
	let a = 1;
	let b = 2;

	// this is a 'reactive statement', and it will re-run
	// when `a`, `b` or `sum` change
	$: console.log(`${a} + ${b} = ${sum}`);

	// this is a 'reactive assignment' — `sum` will be
	// recalculated when `a` or `b` change. It is
	// not necessary to declare `sum` separately
	$: sum = a + b;
</script>
```

Statements are ordered *topologically* by their dependencies and their assignments: since the `console.log` statement depends on `sum`, `sum` is calculated first even though it appears later in the source.

Multiple statements can be combined by putting them in a block:

```
$: {
	// recalculate `total` when `items` changes
	totalany = 0;

	for (const itemconst item: any of itemsany) {
		totalany += itemconst item: any.valueany;
	}
}
```

The left-hand side of a reactive assignments can be an identifier, or it can be a destructuring assignment:

```
$: ({ larry(property) larry: any, moe(property) moe: any, curly(property) curly: any } = stoogesany);
```

## Understanding dependencies[](#Understanding-dependencies)

The dependencies of a `$:` statement are determined at compile time — they are whichever variables are referenced (but not assigned to) inside the statement.

In other words, a statement like this will *not* re-run when `count` changes, because the compiler cannot ‘see’ the dependency:

```
let countlet count: number = 0;
let doublelet double: () => number = () => countlet count: number * 2;

$: doubledany = doublelet double: () => number();
```

Similarly, topological ordering will fail if dependencies are referenced indirectly: `z` will never update, because `y` is not considered ‘dirty’ when the update occurs. Moving `$: z = y` below `$: setY(x)` will fix it:

```
<script>
	let x = 0;
	let y = 0;

	$: z = y;
	$: setY(x);

	function setY(value) {
		y = value;
	}
</script>
```

## Browser-only code[](#Browser-only-code)

Reactive statements run during server-side rendering as well as in the browser. This means that any code that should only run in the browser must be wrapped in an `if` block:

```
$: if (browserany) {
	documentvar document: Document

window.document returns a reference to the document contained in the window.




MDN Reference


.title(property) Document.title: string

The document.title property gets or sets the current title of the document. When present, it defaults to the value of the 
```

----
url: https://svelte.dev/docs/svelte/$props
----

[Skip to main content](#main)

The inputs to a component are referred to as *props*, which is short for *properties*. You pass props to components just like you pass attributes to elements:

App

```
<script>
	import MyComponent from './MyComponent.svelte';
</script>

<MyComponent adjective="cool" />
```

```
<script lang="ts">
	import MyComponent from './MyComponent.svelte';
</script>

<MyComponent adjective="cool" />
```

On the other side, inside `MyComponent.svelte`, we can receive props with the `$props` rune...

MyComponent

```
<script>
	let props = $props();
</script>

<p>this component is {props.adjective}</p>
```

```
<script lang="ts">
	let props = $props();
</script>

<p>this component is {props.adjective}</p>
```

...though more commonly, you’ll [*destructure*](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment) your props:

MyComponent

```
<script>
	let { adjective } = $props();
</script>

<p>this component is {adjective}</p>
```

```
<script lang="ts">
	let { adjective } = $props();
</script>

<p>this component is {adjective}</p>
```

## Fallback values[](#Fallback-values)

Destructuring allows us to declare fallback values, which are used if the parent component does not set a given prop (or the value is `undefined`):

```
let { adjectivelet adjective: any = 'happy' } = $propsfunction $props(): any
namespace $props

Declares the props that a component accepts. Example:



let { optionalProp = 42, requiredProp, bindableProp = $bindable() }: { optionalProp?: number; requiredProps: string; bindableProp: boolean } = $props();

{@link https://svelte.dev/docs/svelte/$props Documentation}


();
```

> Fallback values are not turned into reactive state proxies (see [Updating props](#Updating-props) for more info)

## Renaming props[](#Renaming-props)

We can also use the destructuring assignment to rename props, which is necessary if they’re invalid identifiers, or a JavaScript keyword like `super`:

```
let { superany: trouperlet trouper: any = 'lights are gonna find me' } = $propsfunction $props(): any
namespace $props

Declares the props that a component accepts. Example:



let { optionalProp = 42, requiredProp, bindableProp = $bindable() }: { optionalProp?: number; requiredProps: string; bindableProp: boolean } = $props();

{@link https://svelte.dev/docs/svelte/$props Documentation}


();
```

## Rest props[](#Rest-props)

Finally, we can use a *rest property* to get, well, the rest of the props:

```
let { alet a: any, blet b: any, clet c: any, ...otherslet others: any } = $propsfunction $props(): any
namespace $props

Declares the props that a component accepts. Example:



let { optionalProp = 42, requiredProp, bindableProp = $bindable() }: { optionalProp?: number; requiredProps: string; bindableProp: boolean } = $props();

{@link https://svelte.dev/docs/svelte/$props Documentation}


();
```

## Updating props[](#Updating-props)

References to a prop inside a component update when the prop itself updates — when `count` changes in `App.svelte`, it will also change inside `Child.svelte`. But the child component is able to temporarily override the prop value, which can be useful for unsaved ephemeral state:

[Open in playground](/playground/untitled#H4sIAAAAAAAAA6WQQU-EQAyF_0rTmCxEsuiVBRLjX_AmHmah6MShM5kp6obw380AyarZPXlsXt9rvzchq4GwwCcanPXKa3OC0XVKNL-C89YFzLDXhgIWzxMeVaDN8eDcPnyQEcIMW8tCLAELLEPrtZO64UZ0DBV4fNOmg97bAXb7fJk26-7QcFw0JNDakQUquAmihJK79NBwmZ_TuDyOIpbBcmt0-15NSQpVDclqvK3gPp2Xs4scIHHKE0tawLSszDFvzVjz1r82EfIaM7wEJ_QlWIgfKUM5uajHRnDOfhXyk-t6JZF02ljnSLuUnPwfto3nL7Kesf68eBXsJUNR2nxq7rDolQk0fwNciJZcKgIAAA)

```
<script>
	import Child from './Child.svelte';

	let count = $state(0);
</script>

<button onclick={() => (count += 1)}>
	clicks (parent): {count}
</button>

<Child {count} />
```

```
<script lang="ts">
	import Child from './Child.svelte';

	let count = $state(0);
</script>

<button onclick={() => (count += 1)}>
	clicks (parent): {count}
</button>

<Child {count} />
```

```
<script>
	let { count } = $props();
</script>

<button onclick={() => (count += 1)}>
	clicks (child): {count}
</button>
```

```
<script lang="ts">
	let { count } = $props();
</script>

<button onclick={() => (count += 1)}>
	clicks (child): {count}
</button>
```

While you can temporarily *reassign* props, you should not *mutate* props unless they are [bindable]($bindable).

If the prop is a regular object, the mutation will have no effect:

[Open in playground](/playground/untitled#H4sIAAAAAAAAA3WQzU7DMBCEX2W1QmorQgJXk0RC3HkBwiFxN6rBWVvxpoAsvztKWonw0-N6Z3a-cURuB0KFT45vRmq1mCOBH50PmGFvLAVUzxG7NtBZ-eB9Ho5khTBD7ViIJaDCMujReKkbbsQM3o0Cjwdj99CPboBNXizT2bq5b7gsvh1cnrSueyUtVYyg3cSi4BZSgqLGDP-LF_oQVDJOlKF8-nk_M2PKfiCvky9DWxKIZwJIUMHV8g_b3R_WbhJxDI61NfqtitsdVDXE-UhRwKENwA6o70nL_HY6mS-N4LqCu4ZTWiIXf1AQ15I0x50iVr1_dbjY_CVDaY19N7xH1bc2UPoCtLcdIuUBAAA)

```
<script>
	import Child from './Child.svelte';
</script>

<Child object={{ count: 0 }} />
```

```
<script lang="ts">
	import Child from './Child.svelte';
</script>

<Child object={{ count: 0 }} />
```

```
<script>
	let { object } = $props();
</script>

<button onclick={() => {
	// has no effect
	object.count += 1
}}>
	clicks: {object.count}
</button>
```

```
<script lang="ts">
	let { object } = $props();
</script>

<button onclick={() => {
	// has no effect
	object.count += 1
}}>
	clicks: {object.count}
</button>
```

If the prop is a reactive state proxy, however, then mutations *will* have an effect but you will see an [`ownership_invalid_mutation`](runtime-warnings#Client-warnings-ownership_invalid_mutation) warning, because the component is mutating state that does not ‘belong’ to it:

[Open in playground](/playground/untitled#H4sIAAAAAAAAA3WRzU7DMBCEX2VZIbWIqIFr2lRCcOEZCAcn2VKDs47idUMV-d1R4lSUnx6tmV1_Mzsgq4Yww2c-KKNraLwo0ZYxwZ025DB7GbBUjmbfQ9uu3IGMECZYWRZicZjhxlWdbmVbcCG6aW0n8LjXpoZdZxtYrNLpNY8u1gWPRkMCtnynSiCHaydKaDlU1rNkcBdu1gVv0u-9vIkbhzgSIN1igv9xCX0KZtJ5SlCO7aiPYTAkP7KcI11OM0IOJ8wwgradbd3yL17pRSyD5cro6iMfljeQb2EYl6Qp9NoYqJR3BLInmGJCScb2IBZ8WyuhZPaWXqDXsgcFvepY89sKniwvJN6HZluEcnC0HupJtj1fjWJUVvGT2xzuCw5hijOxuezUYrSEMUrEP-v0Vz8XW31NUJQ2veYas50yjsIXg_8-OVgCAAA)

```
<script>
	import Child from './Child.svelte';

	let object = $state({count: 0});
</script>

<Child {object} />
```

```
<script lang="ts">
	import Child from './Child.svelte';

	let object = $state({count: 0});
</script>

<Child {object} />
```

```
<script>
	let { object } = $props();
</script>

<button onclick={() => {
	// will cause the count below to update,
	// but with a warning. Don't mutate
	// objects you don't own!
	object.count += 1
}}>
	clicks: {object.count}
</button>
```

```
<script lang="ts">
	let { object } = $props();
</script>

<button onclick={() => {
	// will cause the count below to update,
	// but with a warning. Don't mutate
	// objects you don't own!
	object.count += 1
}}>
	clicks: {object.count}
</button>
```

The fallback value of a prop not declared with `$bindable` is left untouched — it is not turned into a reactive state proxy — meaning mutations will not cause updates:

[Open in playground](/playground/untitled#H4sIAAAAAAAAA3WQ3U7DMAyFX8WykLaJssJtWCch7nkBykWaOVpY5kSNO0BR3h21m0T5u7Tsc87nk5H1kVDhU-CbnrQRdyKw2vtOmwPEPsSEFVrnKaF6ztjpRBfJQ4zrdCIvhBWawEIsCRVukuldlG3LrbhjDL3A4975Hdg-HGGxrqfpIl3ct7ypvxS8Od_WW6zwryChd0El_UAVykcc9yMdluob3DzjfzxPAhlC90pGoIEMJgwsCm6hQIEGrqYClqtfkN0gEhgCG-_MocnLFTRbyKNnXcNeJ-AAZO3o6yzIflbqSfuBwCUYEu1GxTl_PWXDdQN3LZcy8U3uSUGen5QR5gwwK-nHw__W9FKhaOffHO9QWe0TlU9fV1N9BQIAAA)

```
<script>
	import Child from './Child.svelte';
</script>

<Child />
```

```
<script lang="ts">
	import Child from './Child.svelte';
</script>

<Child />
```

```
<script>
	let { object = { count: 0 } } = $props();
</script>

<button onclick={() => {
	// has no effect if the fallback value is used
	object.count += 1
}}>
	clicks: {object.count}
</button>
```

```
<script lang="ts">
	let { object = { count: 0 } } = $props();
</script>

<button onclick={() => {
	// has no effect if the fallback value is used
	object.count += 1
}}>
	clicks: {object.count}
</button>
```

In summary: don’t mutate props. Either use callback props to communicate changes, or — if parent and child should share the same object — use the [`$bindable`]($bindable) rune.

## Type safety[](#Type-safety)

You can add type safety to your components by annotating your props, as you would with any other variable declaration. In TypeScript that might look like this...

```
<script lang="ts">
	let { adjective }: { adjective: string } = $props();
</script>
```

...while in JSDoc you can do this:

```
<script>
	/** @type {{ adjective: string }} */
	let { adjective } = $props();
</script>
```

You can, of course, separate the type declaration from the annotation:

```
<script lang="ts">
	interface Props {
		adjective: string;
	}

	let { adjective }: Props = $props();
</script>
```

> Interfaces for native DOM elements are provided in the `svelte/elements` module (see [Typing wrapper components](typescript#Typing-wrapper-components))

If your component exposes [snippet](snippet) props like `children`, these should be typed using the `Snippet` interface imported from `'svelte'` — see [Typing snippets](snippet#Typing-snippets) for examples.

Adding types is recommended, as it ensures that people using your component can easily discover which props they should provide.

## $props.id()[](#$props.id\(\))

This rune, added in version 5.20.0, generates an ID that is unique to the current component instance. When hydrating a server-rendered component, the value will be consistent between server and client.

This is useful for linking elements via attributes like `for` and `aria-labelledby`.

```
<script>
	const uid = $props.id();
</script>

<form>
	<label for="{uid}-firstname">First Name: </label>
	<input id="{uid}-firstname" type="text" />

	<label for="{uid}-lastname">Last Name: </label>
	<input id="{uid}-lastname" type="text" />
</form>
```

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/02-runes/05-$props.md) [llms.txt](/docs/svelte/$props/llms.txt)

previous next

[$effect](/docs/svelte/$effect) [$bindable](/docs/svelte/$bindable)

----
url: https://svelte.dev/docs/svelte/nested-style-elements
----

[Skip to main content](#main)

There can only be one top-level `<style>` tag per component.

However, it is possible to have a `<style>` tag nested inside other elements or logic blocks.

In that case, the `<style>` tag will be inserted as-is into the DOM; no scoping or processing will be done on the `<style>` tag.

```
<div>
	<style>
		/* this style tag will be inserted as-is */
		div {
			/* this will apply to all `<div>` elements in the DOM */
			color: red;
		}
	</style>
</div>
```

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/04-styling/04-nested-style-elements.md) [llms.txt](/docs/svelte/nested-style-elements/llms.txt)

previous next

[Custom properties](/docs/svelte/custom-properties) [\<svelte:boundary>](/docs/svelte/svelte-boundary)

----
url: https://svelte.dev/docs/svelte/svelte-window
----

[Skip to main content](#main)

```
<svelte:window onevent={handler} />
```

```
<svelte:window bind:prop={value} />
```

The `<svelte:window>` element allows you to add event listeners to the `window` object without worrying about removing them when the component is destroyed, or checking for the existence of `window` when server-side rendering.

This element may only appear at the top level of your component — it cannot be inside a block or element.

```
<script>
	function handleKeydown(event) {
		alert(`pressed the ${event.key} key`);
	}
</script>

<svelte:window onkeydown={handleKeydown} />
```

You can also bind to the following properties:

* `innerWidth`
* `innerHeight`
* `outerWidth`
* `outerHeight`
* `scrollX`
* `scrollY`
* `online` — an alias for `window.navigator.onLine`
* `devicePixelRatio`

All except `scrollX` and `scrollY` are readonly.

```
<svelte:window bind:scrollY={y} />
```

> Note that the page will not be scrolled to the initial value to avoid accessibility issues. Only subsequent changes to the bound variable of `scrollX` and `scrollY` will cause scrolling. If you have a legitimate reason to scroll when the component is rendered, call `scrollTo()` in an `$effect`.

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/05-special-elements/02-svelte-window.md) [llms.txt](/docs/svelte/svelte-window/llms.txt)

previous next

[\<svelte:boundary>](/docs/svelte/svelte-boundary) [\<svelte:document>](/docs/svelte/svelte-document)

----
url: https://svelte.dev/docs/svelte/best-practices
----

[Skip to main content](#main)

This document outlines some best practices that will help you write fast, robust Svelte apps. It is also available as a `svelte-core-bestpractices` skill for your agents.

## $state[](#$state)

Only use the `$state` rune for variables that should be *reactive* — in other words, variables that cause an `$effect`, `$derived` or template expression to update. Everything else can be a normal variable.

Objects and arrays (`$state({...})` or `$state([...])`) are made deeply reactive, meaning mutation will trigger updates. This has a trade-off: in exchange for fine-grained reactivity, the objects must be proxied, which has performance overhead. In cases where you’re dealing with large objects that are only ever reassigned (rather than mutated), use `$state.raw` instead. This is often the case with API responses, for example.

## $derived[](#$derived)

To compute something from state, use `$derived` rather than `$effect`:

```
// do this
let squarelet square: number = $derivedfunction $derived<number>(expression: number): number
namespace $derived

Declares derived state, i.e. one that depends on other state variables.
The expression inside $derived(...) should be free of side-effects.




Example:



let double = $derived(count * 2);

{@link https://svelte.dev/docs/svelte/$derived Documentation}


expression 

The derived state expression


(numlet num: number * numlet num: number);

// don't do this
let squarelet square: any;

$effectfunction $effect(fn: () => void | (() => void)): void
namespace $effect

Runs code when a component is mounted to the DOM, and then whenever its dependencies change, i.e. $state or $derived values.
The timing of the execution is after the DOM has been updated.




Example:



$effect(() => console.log('The count is now ' + count));

If you return a function from the effect, it will be called right before the effect is run again, or when the component is unmounted.




Does not run during server-side rendering.




{@link https://svelte.dev/docs/svelte/$effect Documentation}


fn 

The function to execute


(() => {
	squarelet square: number = numlet num: number * numlet num: number;
});
```

> `$derived` is given an expression, *not* a function. If you need to use a function (because the expression is complex, for example) use `$derived.by`.

Deriveds are writable — you can assign to them, just like `$state`, except that they will re-evaluate when their expression changes.

If the derived expression is an object or array, it will be returned as-is — it is *not* made deeply reactive. You can, however, use `$state` inside `$derived.by` in the rare cases that you need this.

## $effect[](#$effect)

Effects are an escape hatch and should mostly be avoided. In particular, avoid updating state inside effects.

* If you need to sync state to an external library such as D3, it is often neater to use [`{@attach ...}`](@attach)
* If you need to run some code in response to user interaction, put the code directly in an event handler or use a [function binding](bind#Function-bindings) as appropriate
* If you need to log values for debugging purposes, use [`$inspect`]($inspect)
* If you need to observe something external to Svelte, use [`createSubscriber`](svelte-reactivity#createSubscriber)

Never wrap the contents of an effect in `if (browser) {...}` or similar — effects do not run on the server.

## $props[](#$props)

Treat props as though they will change. For example, values that depend on props should usually use `$derived`:

```
let { typelet type: any } = $propsfunction $props(): any
namespace $props

Declares the props that a component accepts. Example:



let { optionalProp = 42, requiredProp, bindableProp = $bindable() }: { optionalProp?: number; requiredProps: string; bindableProp: boolean } = $props();

{@link https://svelte.dev/docs/svelte/$props Documentation}


();

// do this
let colorlet color: string = $derivedfunction $derived<"red" | "green">(expression: "red" | "green"): "red" | "green"
namespace $derived

Declares derived state, i.e. one that depends on other state variables.
The expression inside $derived(...) should be free of side-effects.




Example:



let double = $derived(count * 2);

{@link https://svelte.dev/docs/svelte/$derived Documentation}


expression 

The derived state expression


(typelet type: any === 'danger' ? 'red' : 'green');

// don't do this — `color` will not update if `type` changes
let colorlet color: string = typelet type: any === 'danger' ? 'red' : 'green';
```

## $inspect.trace[](#$inspect.trace)

`$inspect.trace` is a debugging tool for reactivity. If something is not updating properly or running more than it should you can add `$inspect.trace(label)` as the first line of an `$effect` or `$derived.by` (or any function they call) to trace their dependencies and discover which one triggered an update.

## #key block[](#key-block)

While the `#key` block is useful when you want transitions/animations to run when a certain expression changes, it can be very expensive — it unmounts every element/component inside each time, so should be used sparingly. Instead of using `#key` to cause expressions in a child component’s `<script>` block to re-run, for example, consider wrapping those expressions in `$derived`.

## Events[](#Events)

Any element attribute starting with `on` is treated as an event listener:

```
<button onclick={() => {...}}>click me</button>

<!-- attribute shorthand also works -->
<button {onclick}>...</button>

<!-- so do spread attributes -->
<button {...props}>...</button>
```

If you need to attach listeners to `window` or `document` you can use `<svelte:window>` and `<svelte:document>`:

```
<svelte:window onkeydown={...} />
<svelte:document onvisibilitychange={...} />
```

Avoid using `onMount` or `$effect` for this.

## Snippets[](#Snippets)

[Snippets](snippet) are a way to define reusable chunks of markup that can be instantiated with the [`{@render ...}`](@render) tag, or passed to components as props. They must be declared within the template.

```
{#snippet greeting(name)}
  <p>hello {name}!</p>
{/snippet}

{@render greeting('world')}
```

> Snippets declared at the top level of a component (i.e. not inside elements or blocks) can be referenced inside `<script>`. A snippet that doesn’t reference component state is also available in a `<script module>`, in which case it can be exported for use by other components.

## Each blocks[](#Each-blocks)

Prefer to use [keyed each blocks](each#Keyed-each-blocks) — this improves performance by allowing Svelte to surgically insert or remove items rather than updating the DOM belonging to existing items.

> The key *must* uniquely identify the object. Do not use the index as a key.

Avoid destructuring if you need to mutate the item (with something like `bind:value={item.count}`, for example).

## Using JavaScript variables in CSS[](#Using-JavaScript-variables-in-CSS)

If you have a JS variable that you want to use inside CSS you can set a CSS custom property with the `style:` directive.

```
<div style:--columns={columns}>...</div>
```

You can then reference `var(--columns)` inside the component’s `<style>`.

## Styling child components[](#Styling-child-components)

The CSS in a component’s `<style>` is scoped to that component. If a parent component needs to control the child’s styles, the preferred way is to use CSS custom properties:

```
<!-- Parent.svelte -->
<Child --color="red" />

<!-- Child.svelte -->
<h1>Hello</h1>

<style>
	h1 {
		color: var(--color);
	}
</style>
```

If this is impossible (for example, the child component comes from a library) you can use `:global` to override styles:

```
<div>
	<Child />
</div>

<style>
	div :global {
		h1 {
			color: red;
		}
	}
</style>
```

## Context[](#Context)

Consider using context instead of declaring state in a shared module. This will scope the state to the part of the app that needs it, and eliminate the possibility of it leaking between users when server-side rendering.

Use `createContext` rather than `setContext` and `getContext`, as it provides type safety.

## Async Svelte[](#Async-Svelte)

If using version 5.36 or higher, you can use [await expressions](await-expressions) and [hydratable](hydratable) to use promises directly inside components. Note that these require the `experimental.async` option to be enabled in the plugin options in `vite.config.js` or in the `svelte.config.js` as they are not yet considered fully stable.

## Avoid legacy features[](#Avoid-legacy-features)

Always use runes mode for new code, and avoid features that have more modern replacements:

* use `$state` instead of implicit reactivity (e.g. `let count = 0; count += 1`)
* use `$derived` and `$effect` instead of `$:` assignments and statements (but only use effects when there is no better solution)
* use `$props` instead of `export let`, `$$props` and `$$restProps`
* use `onclick={...}` instead of `on:click={...}`
* use `{#snippet ...}` and `{@render ...}` instead of `<slot>` and `$$slots` and `<svelte:fragment>`
* use `<DynamicComponent>` instead of `<svelte:component this={DynamicComponent}>`
* use `import Self from './ThisComponent.svelte'` and `<Self>` instead of `<svelte:self>`
* use classes with `$state` fields to share reactivity between components, instead of using stores
* use `{@attach ...}` instead of `use:action`
* use clsx-style arrays and objects in `class` attributes, instead of the `class:` directive

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/07-misc/01-best-practices.md) [llms.txt](/docs/svelte/best-practices/llms.txt)

previous next

[Hydratable data](/docs/svelte/hydratable) [Testing](/docs/svelte/testing)

----
url: https://svelte.dev/docs/svelte/bind
----

[Skip to main content](#main)

Data ordinarily flows down, from parent to child. The `bind:` directive allows data to flow the other way, from child to parent.

The general syntax is `bind:property={expression}`, where `expression` is an [*lvalue*](https://press.rebus.community/programmingfundamentals/chapter/lvalue-and-rvalue/) (i.e. a variable or an object property). When the expression is an identifier with the same name as the property, we can omit the expression — in other words these are equivalent:

```
<input bind:value={value} />
<input bind:value />
```

Svelte creates an event listener that updates the bound value. If an element already has a listener for the same event, that listener will be fired before the bound value is updated.

Most bindings are *two-way*, meaning that changes to the value will affect the element and vice versa. A few bindings are *readonly*, meaning that changing their value will have no effect on the element.

## Function bindings[](#Function-bindings)

You can also use `bind:property={get, set}`, where `get` and `set` are functions, allowing you to perform validation and transformation:

```
<input bind:value={
	() => value,
	(v) => value = v.toLowerCase()}
/>
```

In the case of readonly bindings like [dimension bindings](#Dimensions), the `get` value should be `null`:

```
<div
	bind:clientWidth={null, redraw}
	bind:clientHeight={null, redraw}
>...</div>
```

> Function bindings are available in Svelte 5.9.0 and newer.

## \<input bind:value>[](#input-bind:value)

A `bind:value` directive on an `<input>` element binds the input’s `value` property:

```
<script>
	let message = $state('hello');
</script>

<input bind:value={message} />
<p>{message}</p>
```

In the case of a numeric input (`type="number"` or `type="range"`), the value will be coerced to a number:

[Open in playground](/playground/untitled#H4sIAAAAAAAAA6WR0UrDQBBFf2W5-KA0GOvjmg34A_6A68NsOi0Lm-mSndRKyL9LilqEIhTfhsvcO2e4E4R6hsXL2PMQOxOibKLsCipsY-IC-zohUOGvveec78uBkzIqdHtRFi2waEo3xKytF6-J1ZBx5qYoKd-u756-1XBWHxe1qc82aRIFTqeEJkoe1ehHZuchYx948DjB2QOlkd1Es-mjOI8HD9PT0Xmsl7G-EDCQ7PgKf1P_oFxJFf5J9Zf_F1Vulw9WZnE4M5FZmTA3dW5R4VJVykeF1WHkCst92FO_mN8qKMX0HmUDu6VUeP4E7KcykhUCAAA)

```
<script>
	let a = $state(1);
	let b = $state(2);
</script>

<label>
	<input type="number" bind:value={a} min="0" max="10" />
	<input type="range" bind:value={a} min="0" max="10" />
</label>

<label>
	<input type="number" bind:value={b} min="0" max="10" />
	<input type="range" bind:value={b} min="0" max="10" />
</label>

<p>{a} + {b} = {a + b}</p>
```

```
<script lang="ts">
	let a = $state(1);
	let b = $state(2);
</script>

<label>
	<input type="number" bind:value={a} min="0" max="10" />
	<input type="range" bind:value={a} min="0" max="10" />
</label>

<label>
	<input type="number" bind:value={b} min="0" max="10" />
	<input type="range" bind:value={b} min="0" max="10" />
</label>

<p>{a} + {b} = {a + b}</p>
```

If the input is empty or invalid (in the case of `type="number"`), the value is `undefined`.

Since 5.6.0, if an `<input>` has a `defaultValue` and is part of a form, it will revert to that value instead of the empty string when the form is reset. Note that for the initial render the value of the binding takes precedence unless it is `null` or `undefined`.

```
<script>
	let value = $state('');
</script>

<form>
	<input bind:value defaultValue="not the empty string">
	<input type="reset" value="Reset">
</form>
```

> Use reset buttons sparingly, and ensure that users won’t accidentally click them while trying to submit the form.

## \<input bind:checked>[](#input-bind:checked)

Checkbox inputs can be bound with `bind:checked`:

```
<label>
	<input type="checkbox" bind:checked={accepted} />
	Accept terms and conditions
</label>
```

Since 5.6.0, if an `<input>` has a `defaultChecked` attribute and is part of a form, it will revert to that value instead of `false` when the form is reset. Note that for the initial render the value of the binding takes precedence unless it is `null` or `undefined`.

```
<script>
	let checked = $state(true);
</script>

<form>
	<input type="checkbox" bind:checked defaultChecked={true}>
	<input type="reset" value="Reset">
</form>
```

> Use `bind:group` for radio inputs instead of `bind:checked`.

## \<input bind:indeterminate>[](#input-bind:indeterminate)

Checkboxes can be in an [indeterminate](https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/indeterminate) state, independently of whether they are checked or unchecked:

```
<script>
	let checked = $state(false);
	let indeterminate = $state(true);
</script>

<form>
	<input type="checkbox" bind:checked bind:indeterminate>

	{#if indeterminate}
		waiting...
	{:else if checked}
		checked
	{:else}
		unchecked
	{/if}
</form>
```

## \<input bind:group>[](#input-bind:group)

Inputs that work together can use `bind:group`:

[Open in playground](/playground/untitled#H4sIAAAAAAAAA62UTY_TMBCG_8pgIaWt0o32GtIIWAluCAESh6aHSTptzLq2ZY-7Dd3-d5QvsqwQINHbxHnfZ75kn4XGA4lUlFJv070zwYpY7KQiL9L1WZToaVC8sfbGH0kxiVhURjNp9iIVma-ctJwXumBFDGwcS6UQVvDSMzLNoo8KpY7mrwrdipLFAl5zYwnOnp3U-_XmAotk9O-kUlLv_eRfb1prlkyJdFbf5nfBsznI7wSNCQ7K4JxkkyX1bS95sVxC1xFtweFWGpDaBvaAjuAQOKBSDdCpUsHLI8FymRc6U1iSyrNOCm2Vq0J07kLANKTVeWzzAkdUoVV1XRYCkhy6MEt61n9Bv9ZGETzUhNyjnxxcJcFnKzVWdQ8fPibwszFWNVX3pTmNk7TGBoVMgBrQOWz-MMTR-6yicd1TRZ9kRX05bfSXJv-Z-pZQ-x7bhdfi3tVEfqi3j69Ffh-wghmd2OG85z89-WVHNv8yLDaFacdZYvPu57uBncLPNDffjNSzKIZoDo-PEH0wmqLBUejMc6Oov9JtFji3YcFb6a3CJoVSmeq-vc986W5mJxex-N1bwXRikbILFIt2BiLtHhhx2cSCUaoHqbci3aHydPkBR3aPG5AEAAA)

```
<script>
	let tortilla = $state('Plain');

	/** @type {string[]} */
	let fillings = $state([]);
</script>

<h1>Customize your burrito</h1>

<!-- grouped radio inputs are mutually exclusive -->
<label><input type="radio" bind:group={tortilla} value="Plain" /> Plain</label>
<label><input type="radio" bind:group={tortilla} value="Whole wheat" /> Whole wheat</label>
<label><input type="radio" bind:group={tortilla} value="Spinach" /> Spinach</label>

<!-- grouped checkbox inputs populate an array -->
<label><input type="checkbox" bind:group={fillings} value="Rice" /> Rice</label>
<label><input type="checkbox" bind:group={fillings} value="Beans" /> Beans</label>
<label><input type="checkbox" bind:group={fillings} value="Cheese" /> Cheese</label>
<label><input type="checkbox" bind:group={fillings} value="Guac (extra)" /> Guac (extra)</label>

<p>Tortilla: {tortilla}</p>
<p>Fillings: {fillings.join(', ') || 'None'}</p>

<style>
	label {
		display: block;
	}
</style>
```

```
<script lang="ts">
	let tortilla = $state('Plain');
	let fillings: string[] = $state([]);
</script>

<h1>Customize your burrito</h1>

<!-- grouped radio inputs are mutually exclusive -->
<label><input type="radio" bind:group={tortilla} value="Plain" /> Plain</label>
<label><input type="radio" bind:group={tortilla} value="Whole wheat" /> Whole wheat</label>
<label><input type="radio" bind:group={tortilla} value="Spinach" /> Spinach</label>

<!-- grouped checkbox inputs populate an array -->
<label><input type="checkbox" bind:group={fillings} value="Rice" /> Rice</label>
<label><input type="checkbox" bind:group={fillings} value="Beans" /> Beans</label>
<label><input type="checkbox" bind:group={fillings} value="Cheese" /> Cheese</label>
<label><input type="checkbox" bind:group={fillings} value="Guac (extra)" /> Guac (extra)</label>

<p>Tortilla: {tortilla}</p>
<p>Fillings: {fillings.join(', ') || 'None'}</p>

<style>
	label {
		display: block;
	}
</style>
```

> `bind:group` only works if the inputs are in the same Svelte component.

## \<input bind:files>[](#input-bind:files)

On `<input>` elements with `type="file"`, you can use `bind:files` to get the [`FileList` of selected files](https://developer.mozilla.org/en-US/docs/Web/API/FileList). When you want to update the files programmatically, you always need to use a `FileList` object. Currently `FileList` objects cannot be constructed directly, so you need to create a new [`DataTransfer`](https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer) object and get `files` from there.

```
<script>
	let files = $state();

	function clear() {
		files = new DataTransfer().files; // null or undefined does not work
	}
</script>

<label for="avatar">Upload a picture:</label>
<input accept="image/png, image/jpeg" bind:files id="avatar" name="avatar" type="file" />
<button onclick={clear}>clear</button>
```

`FileList` objects also cannot be modified, so if you want to e.g. delete a single file from the list, you need to create a new `DataTransfer` object and add the files you want to keep.

> `DataTransfer` may not be available in server-side JS runtimes. Leaving the state that is bound to `files` uninitialized prevents potential errors if components are server-side rendered.

## \<select bind:value>[](#select-bind:value)

A `<select>` value binding corresponds to the `value` property on the selected `<option>`, which can be any value (not just strings, as is normally the case in the DOM).

```
<select bind:value={selected}>
	<option value={a}>a</option>
	<option value={b}>b</option>
	<option value={c}>c</option>
</select>
```

A `<select multiple>` element behaves similarly to a checkbox group. The bound variable is an array with an entry corresponding to the `value` property of each selected `<option>`.

```
<select multiple bind:value={fillings}>
	<option value="Rice">Rice</option>
	<option value="Beans">Beans</option>
	<option value="Cheese">Cheese</option>
	<option value="Guac (extra)">Guac (extra)</option>
</select>
```

When the value of an `<option>` matches its text content, the attribute can be omitted.

```
<select multiple bind:value={fillings}>
	<option>Rice</option>
	<option>Beans</option>
	<option>Cheese</option>
	<option>Guac (extra)</option>
</select>
```

You can give the `<select>` a default value by adding a `selected` attribute to the `<option>` (or options, in the case of `<select multiple>`) that should be initially selected. If the `<select>` is part of a form, it will revert to that selection when the form is reset. Note that for the initial render the value of the binding takes precedence if it’s not `undefined`.

```
<select bind:value={selected}>
	<option value={a}>a</option>
	<option value={b} selected>b</option>
	<option value={c}>c</option>
</select>
```

Since 5.57.0, if a `<select>` has a `defaultValue` and is part of a form, it will revert to that value instead of the empty string when the form is reset. Note that for the initial render the value of the binding takes precedence unless it is `null` or `undefined`.

```
<form>
	<select bind:value defaultValue="b">
		<option>a</option>
		<option>b</option>
		<option>c</option>
	</select>
	<input type="reset" value="Reset">
</form>
```

## \<audio>[](#audio)

`<audio>` elements have their own set of bindings — five two-way ones...

* [`currentTime`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/currentTime)
* [`playbackRate`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/playbackRate)
* [`paused`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/paused)
* [`volume`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/volume)
* [`muted`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/muted)

...and six readonly ones:

* [`duration`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/duration)
* [`buffered`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/buffered)
* [`seekable`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/seekable)
* [`seeking`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/seeking_event)
* [`ended`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/ended)
* [`readyState`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/readyState)
* [`played`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/played)

```
<audio src={clip} bind:duration bind:currentTime bind:paused></audio>
```

## \<video>[](#video)

`<video>` elements have all the same bindings as [`<audio>`](#audio) elements, plus readonly [`videoWidth`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLVideoElement/videoWidth) and [`videoHeight`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLVideoElement/videoHeight) bindings.

## \<img>[](#img)

`<img>` elements have two readonly bindings:

* [`naturalWidth`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/naturalWidth)
* [`naturalHeight`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/naturalHeight)

## \<details bind:open>[](#details-bind:open)

`<details>` elements support binding to the `open` property.

```
<details bind:open={isOpen}>
	<summary>How do you comfort a JavaScript bug?</summary>
	<p>You console it.</p>
</details>
```

## window and document[](#window-and-document)

To bind to properties of `window` and `document`, see [`<svelte:window>`](svelte-window) and [`<svelte:document>`](svelte-document).

## Contenteditable bindings[](#Contenteditable-bindings)

Elements with the `contenteditable` attribute support the following bindings:

* [`innerHTML`](https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML)
* [`innerText`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/innerText)
* [`textContent`](https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent)

> There are [subtle differences between `innerText` and `textContent`](https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent#differences_from_innertext).

```
<div contenteditable="true" bind:innerHTML={html}></div>
```

## Dimensions[](#Dimensions)

All visible elements have the following readonly bindings, measured with a `ResizeObserver`:

* [`clientWidth`](https://developer.mozilla.org/en-US/docs/Web/API/Element/clientWidth)
* [`clientHeight`](https://developer.mozilla.org/en-US/docs/Web/API/Element/clientHeight)
* [`offsetWidth`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetWidth)
* [`offsetHeight`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetHeight)
* [`contentRect`](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserverEntry/contentRect)
* [`contentBoxSize`](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserverEntry/contentBoxSize)
* [`borderBoxSize`](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserverEntry/borderBoxSize)
* [`devicePixelContentBoxSize`](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserverEntry/devicePixelContentBoxSize)

```
<div bind:offsetWidth={width} bind:offsetHeight={height}>
	<Chart {width} {height} />
</div>
```

> `display: inline` elements do not have a width or height (except for elements with ‘intrinsic’ dimensions, like `<img>` and `<canvas>`), and cannot be observed with a `ResizeObserver`. You will need to change the `display` style of these elements to something else, such as `inline-block`. Note that CSS transformations do not trigger `ResizeObserver` callbacks.

## bind:this[](#bind:this)

```
bind:this={dom_node}
```

To get a reference to a DOM node, use `bind:this`. The value will be `undefined` until the component is mounted — in other words, you should read it inside an effect or an event handler, but not during component initialisation:

```
<script>
	/** @type {HTMLCanvasElement} */
	let canvas;

	$effect(() => {
		const ctx = canvas.getContext('2d');
		drawStuff(ctx);
	});
</script>

<canvas bind:this={canvas}></canvas>
```

Components also support `bind:this`, allowing you to interact with component instances programmatically.

App

```
<ShoppingCart bind:this={cart} />

<button onclick={() => cart.empty()}> Empty shopping cart </button>
```

ShoppingCart

```
<script>
	// All instance exports are available on the instance object
	export function empty() {
		// ...
	}
</script>
```

```
<script lang="ts">
	// All instance exports are available on the instance object
	export function empty() {
		// ...
	}
</script>
```

> In case of using [the function bindings](#Function-bindings), the getter is required to ensure that the correct value is nullified on component or element destruction.

## bind:*property* for components[](#bind:property-for-components)

```
bind:property={variable}
```

You can bind to component props using the same syntax as for elements.

```
<Keypad bind:value={pin} />
```

While Svelte props are reactive without binding, that reactivity only flows downward into the component by default. Using `bind:property` allows changes to the property from within the component to flow back up out of the component.

To mark a property as bindable, use the [`$bindable`]($bindable) rune:

```
<script>
	let { readonlyProperty, bindableProperty = $bindable() } = $props();
</script>
```

Declaring a property as bindable means it *can* be used using `bind:`, not that it *must* be used using `bind:`.

Bindable properties can have a fallback value:

```
<script>
	let { bindableProperty = $bindable('fallback value') } = $props();
</script>
```

This fallback value *only* applies when the property is *not* bound. When the property is bound and a fallback value is present, the parent is expected to provide a value other than `undefined`, else a runtime error is thrown. This prevents hard-to-reason-about situations where it’s unclear which value should apply.

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/03-template-syntax/12-bind.md) [llms.txt](/docs/svelte/bind/llms.txt)

previous next

[{let/const ...}](/docs/svelte/declaration-tags) [use:](/docs/svelte/use)

----
url: https://svelte.dev/docs/svelte/svelte-attachments
----

[Skip to main content](#main)

```
import { createAttachmentKey(alias) function createAttachmentKey(): symbol
import createAttachmentKey

Creates an object key that will be recognised as an attachment when the object is spread onto an element,
as a programmatic alternative to using {@attach ...}. This can be useful for library authors, though
is generally not needed when building an app.



<script>
	import { createAttachmentKey } from 'svelte/attachments';

	const props = {
		class: 'cool',
		onclick: () => alert('clicked'),
		[createAttachmentKey()]: (node) => {
			node.textContent = 'attached!';
		}
	};
</script>

<button {...props}>click me</button>

5.29


reference, fromAction(alias) function fromAction<E extends EventTarget, T extends unknown>(action: Action<E, T, Record<never, any>> | ((element: E, arg: T) => void | ActionReturn<T, Record<never, any>>), fn: () => T): Attachment<E> (+1 overload)
import fromAction

Converts an action into an attachment keeping the same behavior.
It's useful if you want to start using attachments on components but you have actions provided by a library.




Note that the second argument, if provided, must be a function that returns the argument to the
action function, not the argument itself.



<!-- with an action -->
<div use:foo={bar}>...</div>

<!-- with an attachment -->
<div {@attach fromAction(foo, () => bar)}>...</div>
reference } from 'svelte/attachments';
```

## createAttachmentKey[](#createAttachmentKey)

> Available since 5.29

Creates an object key that will be recognised as an attachment when the object is spread onto an element, as a programmatic alternative to using `{@attach ...}`. This can be useful for library authors, though is generally not needed when building an app.

```
<script>
	import { createAttachmentKey } from 'svelte/attachments';

	const props = {
		class: 'cool',
		onclick: () => alert('clicked'),
		[createAttachmentKey()]: (node) => {
			node.textContent = 'attached!';
		}
	};
</script>

<button {...props}>click me</button>
```

```
function createAttachmentKey(): symbol;
```

## fromAction[](#fromAction)

Converts an [action](/docs/svelte/use) into an [attachment](/docs/svelte/@attach) keeping the same behavior. It’s useful if you want to start using attachments on components but you have actions provided by a library.

Note that the second argument, if provided, must be a function that *returns* the argument to the action function, not the argument itself.

```
<!-- with an action -->
<div use:foo={bar}>...</div>

<!-- with an attachment -->
<div {@attach fromAction(foo, () => bar)}>...</div>
```

```
function fromAction<
	E extends EventTarget,
	T extends unknown
>(
	action:
		| Action<E, T>
		| ((element: E, arg: T) => void | ActionReturn<T>),
	fn: () => T
): Attachment<E>;
```

```
function fromAction<E extends EventTarget>(
	action:
		| Action<E, void>
		| ((element: E) => void | ActionReturn<void>)
): Attachment<E>;
```

## Attachment[](#Attachment)

An [attachment](/docs/svelte/@attach) is a function that runs when an element is mounted to the DOM, and optionally returns a function that is called when the element is later removed.

It can be attached to an element with an `{@attach ...}` tag, or by spreading an object containing a property created with [`createAttachmentKey`](/docs/svelte/svelte-attachments#createAttachmentKey).

```
interface Attachment<T extends EventTarget = Element> {/*…*/}
```

```
(element: T): void | (() => void);
```

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/98-reference/21-svelte-attachments.md) [llms.txt](/docs/svelte/svelte-attachments/llms.txt)

previous next

[svelte/animate](/docs/svelte/svelte-animate) [svelte/compiler](/docs/svelte/svelte-compiler)

----
url: https://svelte.dev/docs/svelte/svelte-head
----

[Skip to main content](#main)

```
<svelte:head>...</svelte:head>
```

This element makes it possible to insert elements into `document.head`. During server-side rendering, `head` content is exposed separately to the main `body` content.

As with `<svelte:window>`, `<svelte:document>` and `<svelte:body>`, this element may only appear at the top level of your component and must never be inside a block or element.

```
<svelte:head>
	<title>Hello world!</title>
	<meta name="description" content="This is where the description goes for SEO" />
</svelte:head>
```

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/05-special-elements/05-svelte-head.md) [llms.txt](/docs/svelte/svelte-head/llms.txt)

previous next

[\<svelte:body>](/docs/svelte/svelte-body) [\<svelte:element>](/docs/svelte/svelte-element)

----
url: https://svelte.dev/docs/svelte/v5-migration-guide/llms.txt
----

````
Version 5 comes with an overhauled syntax and reactivity system. While it may look different at first, you'll soon notice many similarities. This guide goes over the changes in detail and shows you how to upgrade. Along with it, we also provide information on _why_ we did these changes.

You don't have to migrate to the new syntax right away — Svelte 5 still supports the old Svelte 4 syntax, and you can mix and match components using the new syntax with components using the old and vice versa. We expect many people to be able to upgrade with only a few lines of code changed initially. There's also a [migration script](#Migration-script) that helps you with many of these steps automatically.

## Reactivity syntax changes

At the heart of Svelte 5 is the new runes API. Runes are basically compiler instructions that inform Svelte about reactivity. Syntactically, runes are functions starting with a dollar-sign.

### let → $state

In Svelte 4, a `let` declaration at the top level of a component was implicitly reactive. In Svelte 5, things are more explicit: a variable is reactive when created using the `$state` rune. Let's migrate the counter to runes mode by wrapping the counter in `$state`:

```svelte
<script>
	let count = +++$state(0)+++;
</script>
```

Nothing else changes. `count` is still the number itself, and you read and write directly to it, without a wrapper like `.value` or `getCount()`.

> [!DETAILS] Why we did this
> `let` being implicitly reactive at the top level worked great, but it meant that reactivity was constrained — a `let` declaration anywhere else was not reactive. This forced you to resort to using stores when refactoring code out of the top level of components for reuse. This meant you had to learn an entirely separate reactivity model, and the result often wasn't as nice to work with. Because reactivity is more explicit in Svelte 5, you can keep using the same API outside the top level of components. Head to [the tutorial](/tutorial) to learn more.

### $: → $derived/$effect

In Svelte 4, a `$:` statement at the top level of a component could be used to declare a derivation, i.e. state that is entirely defined through a computation of other state. In Svelte 5, this is achieved using the `$derived` rune:

```svelte
<script>
	let count = $state(0);
	---$:--- +++const+++ double = +++$derived(count * 2)+++;
</script>
```

As with `$state`, nothing else changes. `double` is still the number itself, and you read it directly, without a wrapper like `.value` or `getDouble()`.

A `$:` statement could also be used to create side effects. In Svelte 5, this is achieved using the `$effect` rune:

```svelte
<script>
	let count = $state(0);

	---$:---+++$effect(() =>+++ {
		if (count > 5) {
			alert('Count is too high!');
		}
	}+++);+++
</script>
```

Note that [when `$effect` runs is different]($effect#Understanding-dependencies) than when `$:` runs.

> [!DETAILS] Why we did this
> `$:` was a great shorthand and easy to get started with: you could slap a `$:` in front of most code and it would somehow work. This intuitiveness was also its drawback the more complicated your code became, because it wasn't as easy to reason about. Was the intent of the code to create a derivation, or a side effect? With `$derived` and `$effect`, you have a bit more up-front decision making to do (spoiler alert: 90% of the time you want `$derived`), but future-you and other developers on your team will have an easier time.
>
> There were also gotchas that were hard to spot:
>
> - `$:` only updated directly before rendering, which meant you could read stale values in-between rerenders
> - `$:` only ran once per tick, which meant that statements may run less often than you think
> - `$:` dependencies were determined through static analysis of the dependencies. This worked in most cases, but could break in subtle ways during a refactoring where dependencies would be for example moved into a function and no longer be visible as a result
> - `$:` statements were also ordered by using static analysis of the dependencies. In some cases there could be ties and the ordering would be wrong as a result, needing manual interventions. Ordering could also break while refactoring code and some dependencies no longer being visible as a result.
>
> Lastly, it wasn't TypeScript-friendly (our editor tooling had to jump through some hoops to make it valid for TypeScript), which was a blocker for making Svelte's reactivity model truly universal.
>
> `$derived` and `$effect` fix all of these by
>
> - always returning the latest value
> - running as often as needed to be stable
> - determining the dependencies at runtime, and therefore being immune to refactorings
> - executing dependencies as needed and therefore being immune to ordering problems
> - being TypeScript-friendly

### export let → $props

In Svelte 4, properties of a component were declared using `export let`. Each property was one declaration. In Svelte 5, all properties are declared through the `$props` rune, through destructuring:

```svelte
<script>
	---export let optional = 'unset';---
	---export let required;---
	+++let { optional = 'unset', required } = $props();+++
</script>
```

There are multiple cases where declaring properties becomes less straightforward than having a few `export let` declarations:

- you want to rename the property, for example because the name is a reserved identifier (e.g. `class`)
- you don't know which other properties to expect in advance
- you want to forward every property to another component

All these cases need special syntax in Svelte 4:

- renaming: `export { klass as class}`
- other properties: `$$restProps`
- all properties `$$props`

In Svelte 5, the `$props` rune makes this straightforward without any additional Svelte-specific syntax:

- renaming: use property renaming `let { class: klass } = $props();`
- other properties: use spreading `let { foo, bar, ...rest } = $props();`
- all properties: don't destructure `let props = $props();`

```svelte
<script>
	---let klass = '';---
	---export { klass as class};---
	+++let { class: klass, ...rest } = $props();+++
</script>
<button class={klass} {...---$$restProps---+++rest+++}>click me</button>
```

> [!DETAILS] Why we did this
> `export let` was one of the more controversial API decisions, and there was a lot of debate about whether you should think about a property being `export`ed or `import`ed. `$props` doesn't have this trait. It's also in line with the other runes, and the general thinking reduces to "everything special to reactivity in Svelte is a rune".
>
> There were also a lot of limitations around `export let`, which required additional API, as shown above. `$props` unite this in one syntactical concept that leans heavily on regular JavaScript destructuring syntax.

## Event changes

Event handlers have been given a facelift in Svelte 5. Whereas in Svelte 4 we use the `on:` directive to attach an event listener to an element, in Svelte 5 they are properties like any other (in other words — remove the colon):

```svelte
<script>
	let count = $state(0);
</script>

<button on---:---click={() => count++}>
	clicks: {count}
</button>
```

Since they're just properties, you can use the normal shorthand syntax...

```svelte
<script>
	let count = $state(0);

	function onclick() {
		count++;
	}
</script>

<button {onclick}>
	clicks: {count}
</button>
```

...though when using a named event handler function it's usually better to use a more descriptive name.

### Component events

In Svelte 4, components could emit events by creating a dispatcher with `createEventDispatcher`.

This function is deprecated in Svelte 5. Instead, components should accept _callback props_ — which means you then pass functions as properties to these components:

```svelte
<!--- file: App.svelte --->
<script>
	import Pump from './Pump.svelte';

	let size = $state(15);
	let burst = $state(false);

	function reset() {
		size = 15;
		burst = false;
	}
</script>

<Pump
	---on:---inflate={(power) => {
		size += power---.detail---;
		if (size > 75) burst = true;
	}}
	---on:---deflate={(power) => {
		if (size > 0) size -= power---.detail---;
	}}
/>

{#if burst}
	<button onclick={reset}>new balloon</button>
	<span class="boom">💥</span>
{:else}
	<span class="balloon" style="scale: {0.01 * size}">
		🎈
	</span>
{/if}
```

```svelte
<!--- file: Pump.svelte --->
<script>
	---import { createEventDispatcher } from 'svelte';---
	---const dispatch = createEventDispatcher();---

	+++let { inflate, deflate } = $props();+++
	let power = $state(5);
</script>

<button onclick={() => ---dispatch('inflate', power)---+++inflate(power)+++}>
	inflate
</button>
<button onclick={() => ---dispatch('deflate', power)---+++deflate(power)+++}>
	deflate
</button>
<button onclick={() => power--}>-</button>
Pump power: {power}
<button onclick={() => power++}>+</button>
```

### Bubbling events

Instead of doing `<button on:click>` to 'forward' the event from the element to the component, the component should accept an `onclick` callback prop:

```svelte
<script>
	+++let { onclick } = $props();+++
</script>

<button ---on:click--- +++{onclick}+++>
	click me
</button>
```

Note that this also means you can 'spread' event handlers onto the element along with other props instead of tediously forwarding each event separately:

```svelte
<script>
	let props = $props();
</script>

<button ---{...$$props} on:click on:keydown on:all_the_other_stuff--- +++{...props}+++>
	click me
</button>
```

### Event modifiers

In Svelte 4, you can add event modifiers to handlers:

```svelte
<button on:click|once|preventDefault={handler}>...</button>
```

Modifiers are specific to `on:` and so do not work with modern event handlers. Adding things like `event.preventDefault()` inside the handler itself is preferable, since all the logic lives in one place rather than being split between handler and modifiers.

Since event handlers are just functions, you can create your own wrappers as necessary:

```svelte
<script>
	function once(fn) {
		return function (event) {
			if (fn) fn.call(this, event);
			fn = null;
		};
	}

	function preventDefault(fn) {
		return function (event) {
			event.preventDefault();
			fn.call(this, event);
		};
	}
</script>

<button onclick={once(preventDefault(handler))}>...</button>
```

There are three modifiers — `capture`, `passive` and `nonpassive` — that can't be expressed as wrapper functions, since they need to be applied when the event handler is bound rather than when it runs.

For `capture`, we add the modifier to the event name:

```svelte
<button onclickcapture={...}>...</button>
```

Changing the [`passive`](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#using_passive_listeners) option of an event handler, meanwhile, is not something to be done lightly. If you have a use case for it — and you probably don't! — then you will need to use an action to apply the event handler yourself.

### Multiple event handlers

In Svelte 4, this is possible:

```svelte
<button on:click={one} on:click={two}>...</button>
```

Duplicate attributes/properties on elements — which now includes event handlers — are not allowed. Instead, do this:

```svelte
<button
	onclick={(e) => {
		one(e);
		two(e);
	}}
>
	...
</button>
```

When spreading props, local event handlers must go _after_ the spread, or they risk being overwritten:

```svelte
<button
	{...props}
	onclick={(e) => {
		doStuff(e);
		props.onclick?.(e);
	}}
>
	...
</button>
```

> [!DETAILS] Why we did this
> `createEventDispatcher` was always a bit boilerplate-y:
>
> - import the function
> - call the function to get a dispatch function
> - call said dispatch function with a string and possibly a payload
> - retrieve said payload on the other end through a `.detail` property, because the event itself was always a `CustomEvent`
>
> It was always possible to use component callback props, but because you had to listen to DOM events using `on:`, it made sense to use `createEventDispatcher` for component events due to syntactical consistency. Now that we have event attributes (`onclick`), it's the other way around: Callback props are now the more sensible thing to do.
>
> The removal of event modifiers is arguably one of the changes that seems like a step back for those who've liked the shorthand syntax of event modifiers. Given that they are not used that frequently, we traded a smaller surface area for more explicitness. Modifiers also were inconsistent, because most of them were only usable on DOM elements.
>
> Multiple listeners for the same event are also no longer possible, but it was something of an anti-pattern anyway, since it impedes readability: if there are many attributes, it becomes harder to spot that there are two handlers unless they are right next to each other. It also implies that the two handlers are independent, when in fact something like `event.stopImmediatePropagation()` inside `one` would prevent `two` from being called.
>
> By deprecating `createEventDispatcher` and the `on:` directive in favour of callback props and normal element properties, we:
>
> - reduce Svelte's learning curve
> - remove boilerplate, particularly around `createEventDispatcher`
> - remove the overhead of creating `CustomEvent` objects for events that may not even have listeners
> - add the ability to spread event handlers
> - add the ability to know which event handlers were provided to a component
> - add the ability to express whether a given event handler is required or optional
> - increase type safety (previously, it was effectively impossible for Svelte to guarantee that a component didn't emit a particular event)

## Snippets instead of slots

In Svelte 4, content can be passed to components using slots. Svelte 5 replaces them with snippets, which are more powerful and flexible, and so slots are deprecated in Svelte 5.

They continue to work, however, and you can pass snippets to a component that uses slots:

```svelte
<!--- file: Child.svelte --->
<slot />
<hr />
<slot name="foo" message="hello" />
```

```svelte
<!--- file: Parent.svelte --->
<script>
	import Child from './Child.svelte';
</script>

<Child>
	default child content

	{#snippet foo({ message })}
		message from child: {message}
	{/snippet}
</Child>
```

(The reverse is not true — you cannot pass slotted content to a component that uses [`{@render ...}`](/docs/svelte/@render) tags.)

When using custom elements, you should still use `<slot />` like before. In a future version, when Svelte removes its internal version of slots, it will leave those slots as-is, i.e. output a regular DOM tag instead of transforming it.

### Default content

In Svelte 4, the easiest way to pass a piece of UI to the child was using a `<slot />`. In Svelte 5, this is done using the `children` prop instead, which is then shown with `{@render children()}`:

```svelte
<script>
	+++let { children } = $props();+++
</script>

---<slot />---
+++{@render children?.()}+++
```

### Multiple content placeholders

If you wanted multiple UI placeholders, you had to use named slots. In Svelte 5, use props instead, name them however you like and `{@render ...}` them:

```svelte
<script>
	+++let { header, main, footer } = $props();+++
</script>

<header>
	---<slot name="header" />---
	+++{@render header()}+++
</header>

<main>
	---<slot name="main" />---
	+++{@render main()}+++
</main>

<footer>
	---<slot name="footer" />---
	+++{@render footer()}+++
</footer>
```

### Passing data back up

In Svelte 4, you would pass data to a `<slot />` and then retrieve it with `let:` in the parent component. In Svelte 5, snippets take on that responsibility:

```svelte
<!--- file: App.svelte --->
<script>
	import List from './List.svelte';
</script>

<List items={['one', 'two', 'three']} ---let:item--->
	+++{#snippet item(text)}+++
		<span>{text}</span>
	+++{/snippet}+++
	---<span slot="empty">No items yet</span>---
	+++{#snippet empty()}
		<span>No items yet</span>
	{/snippet}+++
</List>
```

```svelte
<!--- file: List.svelte --->
<script>
	let { items, +++item, empty+++ } = $props();
</script>

{#if items.length}
	<ul>
		{#each items as entry}
			<li>
				---<slot item={entry} />---
				+++{@render item(entry)}+++
			</li>
		{/each}
	</ul>
{:else}
	---<slot name="empty" />---
	+++{@render empty?.()}+++
{/if}
```

> [!DETAILS] Why we did this
> Slots were easy to get started with, but the more advanced the use case became, the more involved and confusing the syntax became:
>
> - the `let:` syntax was confusing to many people as it _creates_ a variable whereas all other `:` directives _receive_ a variable
> - the scope of a variable declared with `let:` wasn't clear. In the example above, it may look like you can use the `item` slot prop in the `empty` slot, but that's not true
> - named slots had to be applied to an element using the `slot` attribute. Sometimes you didn't want to create an element, so we had to add the `<svelte:fragment>` API
> - named slots could also be applied to a component, which changed the semantics of where `let:` directives are available (even today us maintainers often don't know which way around it works)
>
> Snippets solve all of these problems by being much more readable and clear. At the same time they're more powerful as they allow you to define sections of UI that you can render _anywhere_, not just passing them as props to a component.

## Migration script

By now you should have a pretty good understanding of the before/after and how the old syntax relates to the new syntax. It probably also became clear that a lot of these migrations are rather technical and repetitive — something you don't want to do by hand.

We thought the same, which is why we provide a migration script to do most of the migration automatically. You can upgrade your project by using `npx sv migrate svelte-5`. This will do the following things:

- bump core dependencies in your `package.json`
- migrate to runes (`let` → `$state` etc)
- migrate to event attributes for DOM elements (`on:click` → `onclick`)
- migrate slot creations to render tags (`<slot />` → `{@render children()}`)
- migrate slot usages to snippets (`<div slot="x">...</div>` → `{#snippet x()}<div>...</div>{/snippet}`)
- migrate obvious component creations (`new Component(...)` → `mount(Component, ...)`)

You can also migrate a single component in VS Code through the `Migrate Component to Svelte 5 Syntax` command, or in our Playground through the `Migrate` button.

Not everything can be migrated automatically, and some migrations need manual cleanup afterwards. The following sections describe these in more detail.

### run

You may see that the migration script converts some of your `$:` statements to a `run` function which is imported from `svelte/legacy`. This happens if the migration script couldn't reliably migrate the statement to a `$derived` and concluded this is a side effect instead. In some cases this may be wrong and it's best to change this to use a `$derived` instead. In other cases it may be right, but since `$:` statements also ran on the server but `$effect` does not, it isn't safe to transform it as such. Instead, `run` is used as a stopgap solution. `run` mimics most of the characteristics of `$:`, in that it runs on the server once, and runs as `$effect.pre` on the client (`$effect.pre` runs _before_ changes are applied to the DOM; most likely you want to use `$effect` instead).

```svelte
<script>
	---import { run } from 'svelte/legacy';---
	---run(() => {---
	+++$effect(() => {+++
		// some side effect code
	})
</script>
```

### Event modifiers

Event modifiers are not applicable to event attributes (e.g. you can't do `onclick|preventDefault={...}`). Therefore, when migrating event directives to event attributes, we need a function-replacement for these modifiers. These are imported from `svelte/legacy`, and should be migrated away from in favor of e.g. just using `event.preventDefault()`.

```svelte
<script>
	---import { preventDefault } from 'svelte/legacy';---
</script>

<button
	onclick={---preventDefault---((event) => {
		+++event.preventDefault();+++
		// ...
	})}
>
	click me
</button>
```

### Things that are not automigrated

The migration script does not convert `createEventDispatcher`. You need to adjust those parts manually. It doesn't do it because it's too risky because it could result in breakage for users of the component, which the migration script cannot find out.

The migration script does not convert `beforeUpdate/afterUpdate`. It doesn't do it because it's impossible to determine the actual intent of the code. As a rule of thumb you can often go with a combination of `$effect.pre` (runs at the same time as `beforeUpdate` did) and `tick` (imported from `svelte`, allows you to wait until changes are applied to the DOM and then do some work).

## Components are no longer classes

In Svelte 3 and 4, components are classes. In Svelte 5 they are functions and should be instantiated differently. If you need to manually instantiate components, you should use `mount` or `hydrate` (imported from `svelte`) instead. If you see this error using SvelteKit, try updating to the latest version of SvelteKit first, which adds support for Svelte 5. If you're using Svelte without SvelteKit, you'll likely have a `main.js` file (or similar) which you need to adjust:

```js
+++import { mount } from 'svelte';+++
import App from './App.svelte'

---const app = new App({ target: document.getElementById("app") });---
+++const app = mount(App, { target: document.getElementById("app") });+++

export default app;
```

`mount` and `hydrate` have the exact same API. The difference is that `hydrate` will pick up the Svelte's server-rendered HTML inside its target and hydrate it. Both return an object with the exports of the component and potentially property accessors (if compiled with `accessors: true`). They do not come with the `$on`, `$set` and `$destroy` methods you may know from the class component API. These are its replacements:

For `$on`, instead of listening to events, pass them via the `events` property on the options argument.

```js
+++import { mount } from 'svelte';+++
import App from './App.svelte'

---const app = new App({ target: document.getElementById("app") });
app.$on('event', callback);---
+++const app = mount(App, { target: document.getElementById("app"), events: { event: callback } });+++
```

> [!NOTE] Note that using `events` is discouraged — instead, [use callbacks](#Event-changes)

For `$set`, use `$state` instead to create a reactive property object and manipulate it. If you're doing this inside a `.js` or `.ts` file, adjust the ending to include `.svelte`, i.e. `.svelte.js` or `.svelte.ts`.

```js
+++import { mount } from 'svelte';+++
import App from './App.svelte'

---const app = new App({ target: document.getElementById("app"), props: { foo: 'bar' } });
app.$set({ foo: 'baz' });---
+++const props = $state({ foo: 'bar' });
const app = mount(App, { target: document.getElementById("app"), props });
props.foo = 'baz';+++
```

For `$destroy`, use `unmount` instead.

```js
+++import { mount, unmount } from 'svelte';+++
import App from './App.svelte'

---const app = new App({ target: document.getElementById("app"), props: { foo: 'bar' } });
app.$destroy();---
+++const app = mount(App, { target: document.getElementById("app") });
unmount(app);+++
```

As a stop-gap-solution, you can also use `createClassComponent` or `asClassComponent` (imported from `svelte/legacy`) instead to keep the same API known from Svelte 4 after instantiating.

```js
+++import { createClassComponent } from 'svelte/legacy';+++
import App from './App.svelte'

---const app = new App({ target: document.getElementById("app") });---
+++const app = createClassComponent({ component: App, target: document.getElementById("app") });+++

export default app;
```

If this component is not under your control, you can use the `compatibility.componentApi` compiler option for auto-applied backwards compatibility, which means code using `new Component(...)` keeps working without adjustments (note that this adds a bit of overhead to each component). This will also add `$set` and `$on` methods for all component instances you get through `bind:this`.

```js
/// svelte.config.js
export default {
	compilerOptions: {
		compatibility: {
			componentApi: 4
		}
	}
};
```

Note that `mount` and `hydrate` are _not_ synchronous, so things like `onMount` won't have been called by the time the function returns and the pending block of promises will not have been rendered yet (because `#await` waits a microtask to wait for a potentially immediately-resolved promise). If you need that guarantee, call `flushSync` (import from `'svelte'`) after calling `mount/hydrate`.

### Server API changes

Similarly, components no longer have a `render` method when compiled for server-side rendering. Instead, pass the function to `render` from `svelte/server`:

```js
+++import { render } from 'svelte/server';+++
import App from './App.svelte';

---const { html, head } = App.render({ props: { message: 'hello' }});---
+++const { html, head } = render(App, { props: { message: 'hello' }});+++
```

In Svelte 4, rendering a component to a string also returned the CSS of all components. In Svelte 5, this is no longer the case by default because most of the time you're using a tooling chain that takes care of it in other ways (like SvelteKit). If you need CSS to be returned from `render`, you can set the `css` compiler option to `'injected'` and it will add `<style>` elements to the `head`.

### Component typing changes

The change from classes towards functions is also reflected in the typings: `SvelteComponent`, the base class from Svelte 4, is deprecated in favour of the new `Component` type which defines the function shape of a Svelte component. To manually define a component shape in a `d.ts` file:

```ts
import type { Component } from 'svelte';
export declare const MyComponent: Component<{
	foo: string;
}>;
```

To declare that a component of a certain type is required:

```js
import { ComponentA, ComponentB } from 'component-library';
---import type { SvelteComponent } from 'svelte';---
+++import type { Component } from 'svelte';+++

---let C: typeof SvelteComponent<{ foo: string }> = $state(---
+++let C: Component<{ foo: string }> = $state(+++
	Math.random() ? ComponentA : ComponentB
);
```

The two utility types `ComponentEvents` and `ComponentType` are also deprecated. `ComponentEvents` is obsolete because events are defined as callback props now, and `ComponentType` is obsolete because the new `Component` type is the component type already (i.e. `ComponentType<SvelteComponent<{ prop: string }>>` is equivalent to `Component<{ prop: string }>`).

### bind:this changes

Because components are no longer classes, using `bind:this` no longer returns a class instance with `$set`, `$on` and `$destroy` methods on it. It only returns the instance exports (`export function/const`) and, if you're using the `accessors` option, a getter/setter-pair for each property.

## `<svelte:component>` is no longer necessary

In Svelte 4, components are _static_ — if you render `<Thing>`, and the value of `Thing` changes, nothing happens. To make it dynamic you had to use `<svelte:component>`.

This is no longer true in Svelte 5:

```svelte
<script>
	import A from './A.svelte';
	import B from './B.svelte';

	let Thing = $state();
</script>

<select bind:value={Thing}>
	<option value={A}>A</option>
	<option value={B}>B</option>
</select>

<!-- these are equivalent -->
<Thing />
<svelte:component this={Thing} />
```
While migrating, keep in mind that your component's name should be capitalized (`Thing`) to distinguish it from elements, unless using dot notation.

### Dot notation indicates a component

In Svelte 4, `<foo.bar>` would create an element with a tag name of `"foo.bar"`. In Svelte 5, `foo.bar` is treated as a component instead. This is particularly useful inside `each` blocks:

```svelte
{#each items as item}
	<item.component {...item.props} />
{/each}
```

## Whitespace handling changed

Previously, Svelte employed a very complicated algorithm to determine if whitespace should be kept or not. Svelte 5 simplifies this which makes it easier to reason about as a developer. The rules are:

- Whitespace between nodes is collapsed to one whitespace
- Whitespace at the start and end of a tag is removed completely

  This new behavior is slightly different from native HTML rendering. For example, `<p>foo<span> - bar</span></p>` will render:

  - `foo - bar` in HTML
  - `foo- bar` in Svelte 5

  You can reintroduce the missing space by moving it outside the `<span>`...

  ```svelte
  <p>foo <span>- bar</span></p>
  ```

  ...or, if necessary for styling reasons, including it as an expression:

  ```svelte
  <p>foo<span>{' '}- bar</span></p>
  ```

- Certain exceptions apply such as keeping whitespace inside `pre` tags

As before, you can disable whitespace trimming by setting the `preserveWhitespace` option in your compiler settings or on a per-component basis in `<svelte:options>`.

## Modern browser required

Svelte 5 requires a modern browser (in other words, not Internet Explorer) for various reasons:

- it uses [`Proxies`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy)
- elements with `clientWidth`/`clientHeight`/`offsetWidth`/`offsetHeight` bindings use a [`ResizeObserver`](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver) rather than a convoluted `<iframe>` hack
- `<input type="range" bind:value={...} />` only uses an `input` event listener, rather than also listening for `change` events as a fallback

The `legacy` compiler option, which generated bulkier but IE-friendly code, no longer exists.

## Changes to compiler options

- The `false`/`true` (already deprecated previously) and the `"none"` values were removed as valid values from the `css` option
- The `legacy` option was repurposed
- The `hydratable` option has been removed. Svelte components are always hydratable now
- The `enableSourcemap` option has been removed. Source maps are always generated now, tooling can choose to ignore it
- The `tag` option was removed. Use `<svelte:options customElement="tag-name" />` inside the component instead
- The `loopGuardTimeout`, `format`, `sveltePath`, `errorMode` and `varsReport` options were removed

## The `children` prop is reserved

Content inside component tags becomes a snippet prop called `children`. You cannot have a separate prop by that name.

## Breaking changes in runes mode

Some breaking changes only apply once your component is in runes mode.

### Bindings to component exports are not allowed

Exports from runes mode components cannot be bound to directly. For example, having `export const foo = ...` in component `A` and then doing `<A bind:foo />` causes an error. Use `bind:this` instead — `<A bind:this={a} />` — and access the export as `a.foo`. This change makes things easier to reason about, as it enforces a clear separation between props and exports.

### Bindings need to be explicitly defined using `$bindable()`

In Svelte 4 syntax, every property (declared via `export let`) is bindable, meaning you can `bind:` to it. In runes mode, properties are not bindable by default: you need to denote bindable props with the `$bindable` rune.

If a bindable property has a default value (e.g. `let { foo = $bindable('bar') } = $props();`), you need to pass a non-`undefined` value to that property if you're binding to it. This prevents ambiguous behavior — the parent and child must have the same value — and results in better performance (in Svelte 4, the default value was reflected back to the parent, resulting in wasteful additional render cycles).

### `accessors` option is ignored

Setting the `accessors` option to `true` makes properties of a component directly accessible on the component instance.

```svelte
<svelte:options accessors={true} />

<script>
	// available via componentInstance.name
	export let name;
</script>
```

In runes mode, properties are never accessible on the component instance. You can use component exports instead if you need to expose them.

```svelte
<script>
	let { name } = $props();
	// available via componentInstance.getName()
	export const getName = () => name;
</script>
```

Alternatively, if the place where they are instantiated is under your control, you can also make use of runes inside `.js/.ts` files by adjusting their ending to include `.svelte`, i.e. `.svelte.js` or `.svelte.ts`, and then use `$state`:

```js
+++import { mount } from 'svelte';+++
import App from './App.svelte'

---const app = new App({ target: document.getElementById("app"), props: { foo: 'bar' } });
app.foo = 'baz'---
+++const props = $state({ foo: 'bar' });
const app = mount(App, { target: document.getElementById("app"), props });
props.foo = 'baz';+++
```

### `immutable` option is ignored

Setting the `immutable` option has no effect in runes mode. This concept is replaced by how `$state` and its variations work.

### Classes are no longer "auto-reactive"

In Svelte 4, doing the following triggered reactivity:

```svelte
<script>
	let foo = new Foo();
</script>

<button on:click={() => (foo.value = 1)}>{foo.value}</button
>
```

This is because the Svelte compiler treated the assignment to `foo.value` as an instruction to update anything that referenced `foo`. In Svelte 5, reactivity is determined at runtime rather than compile time, so you should define `value` as a reactive `$state` field on the `Foo` class. Wrapping `new Foo()` with `$state(...)` will have no effect — only vanilla objects and arrays are made deeply reactive.

### Touch events are passive

When using `ontouchstart` and `ontouchmove` event attributes, the handlers are [passive](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#using_passive_listeners) to align with browser defaults. This greatly improves responsiveness by allowing the browser to scroll the document immediately, rather than waiting to see if the event handler calls `event.preventDefault()`.

In the very rare cases that you need to prevent these event defaults, you should use [`on`](/docs/svelte/svelte-events#on) instead (for example inside an action).

### Attribute/prop syntax is stricter

In Svelte 4, complex attribute values needn't be quoted:

<!-- prettier-ignore -->
```svelte
<Component prop=this{is}valid />
```

This is a footgun. In runes mode, if you want to concatenate stuff you must wrap the value in quotes:

```svelte
<Component prop="this{is}valid" />
```

Note that Svelte 5 will also warn if you have a single expression wrapped in quotes, like `answer="{42}"` — in Svelte 6, that will cause the value to be converted to a string, rather than passed as a number.

### HTML structure is stricter

In Svelte 4, you were allowed to write HTML code that would be repaired by the browser when server-side rendering it. For example you could write this...

```svelte
<table>
	<tr>
		<td>hi</td>
	</tr>
</table>
```

... and the browser would auto-insert a `<tbody>` element:

```svelte
<table>
	<tbody>
		<tr>
			<td>hi</td>
		</tr>
	</tbody>
</table>
```

Svelte 5 is more strict about the HTML structure and will throw a compiler error in cases where the browser would repair the DOM.

## Other breaking changes

### Stricter `@const` assignment validation

Assignments to destructured parts of a `@const` declaration are no longer allowed. It was an oversight that this was ever allowed.

### :is(...), :has(...), and :where(...) are scoped

Previously, Svelte did not analyse selectors inside `:is(...)`, `:has(...)`, and `:where(...)`, effectively treating them as global. Svelte 5 analyses them in the context of the current component. Some selectors may now therefore be treated as unused if they were relying on this treatment. To fix this, use `:global(...)` inside the `:is(...)/:has(...)/:where(...)` selectors.

When using Tailwind's `@apply` directive, add a `:global` selector to preserve rules that use Tailwind-generated `:is(...)` selectors:

<!-- prettier-ignore -->
```css
main +++:global+++ {
	@apply bg-blue-100 dark:bg-blue-900;
}
```

### CSS hash position no longer deterministic

Previously Svelte would always insert the CSS hash last. This is no longer guaranteed in Svelte 5. This is only breaking if you [have very weird css selectors](https://stackoverflow.com/questions/15670631/does-the-order-of-classes-listed-on-an-item-affect-the-css).

### Scoped CSS uses :where(...)

To avoid issues caused by unpredictable specificity changes, scoped CSS selectors now use `:where(.svelte-xyz123)` selector modifiers alongside `.svelte-xyz123` (where `xyz123` is, as previously, a hash of the `<style>` contents). You can read more detail [here](https://github.com/sveltejs/svelte/pull/10443).

In the event that you need to support ancient browsers that don't implement `:where`, you can manually alter the emitted CSS, at the cost of unpredictable specificity changes:

```js
// @errors: 2552
css = css.replace(/:where\((.+?)\)/, '$1');
```

### Error/warning codes have been renamed

Error and warning codes have been renamed. Previously they used dashes to separate the words, they now use underscores (e.g. foo-bar becomes foo_bar). Additionally, a handful of codes have been reworded slightly.

### Reduced number of namespaces

The number of valid namespaces you can pass to the compiler option `namespace` has been reduced to `html` (the default), `mathml` and `svg`.

The `foreign` namespace was only useful for Svelte Native, which we're planning to support differently in a 5.x minor.

### beforeUpdate/afterUpdate changes

`beforeUpdate` no longer runs twice on initial render if it modifies a variable referenced in the template.

`afterUpdate` callbacks in a parent component will now run after `afterUpdate` callbacks in any child components.

`beforeUpdate/afterUpdate` no longer run when the component contains a `<slot>` and its content is updated.

Both functions are disallowed in runes mode — use `$effect.pre(...)` and `$effect(...)` instead.

### `contenteditable` behavior change

If you have a `contenteditable` node with a corresponding binding _and_ a reactive value inside it (example: `<div contenteditable=true bind:textContent>count is {count}</div>`), then the value inside the contenteditable will not be updated by updates to `count` because the binding takes full control over the content immediately and it should only be updated through it.

### `oneventname` attributes no longer accept string values

In Svelte 4, it was possible to specify event attributes on HTML elements as a string:

```svelte
<button onclick="alert('hello')">...</button>
```

This is not recommended, and is no longer possible in Svelte 5, where properties like `onclick` replace `on:click` as the mechanism for adding event handlers.

### `null` and `undefined` become the empty string

In Svelte 4, `null` and `undefined` were printed as the corresponding string. In 99 out of 100 cases you want this to become the empty string instead, which is also what most other frameworks out there do. Therefore, in Svelte 5, `null` and `undefined` become the empty string.

### `bind:files` values can only be `null`, `undefined` or `FileList`

`bind:files` is now a two-way binding. As such, when setting a value, it needs to be either falsy (`null` or `undefined`) or of type `FileList`.

### Bindings now react to form resets

Previously, bindings did not take into account `reset` event of forms, and therefore values could get out of sync with the DOM. Svelte 5 fixes this by placing a `reset` listener on the document and invoking bindings where necessary.

### `walk` no longer exported

`svelte/compiler` reexported `walk` from `estree-walker` for convenience. This is no longer true in Svelte 5, import it directly from that package instead in case you need it.

### Content inside `svelte:options` is forbidden

In Svelte 4 you could have content inside a `<svelte:options />` tag. It was ignored, but you could write something in there. In Svelte 5, content inside that tag is a compiler error.

### `<slot>` elements in declarative shadow roots are preserved

Svelte 4 replaced the `<slot />` tag in all places with its own version of slots. Svelte 5 preserves them in the case they are a child of a `<template shadowrootmode="...">` element.

### `<svelte:element>` tag must be an expression

In Svelte 4, `<svelte:element this="div">` is valid code. This makes little sense — you should just do `<div>`. In the vanishingly rare case that you _do_ need to use a literal value for some reason, you can do this:

```svelte
<svelte:element this=+++{+++"div"+++}+++>
```

Note that whereas Svelte 4 would treat `<svelte:element this="input">` (for example) identically to `<input>` for the purposes of determining which `bind:` directives could be applied, Svelte 5 does not.

### `mount` plays transitions by default

The `mount` function used to render a component tree plays transitions by default unless the `intro` option is set to `false`. This is different from legacy class components which, when manually instantiated, didn't play transitions by default.

### `<img src={...}>` and `{@html ...}` hydration mismatches are not repaired

In Svelte 4, if the value of a `src` attribute or `{@html ...}` tag differ between server and client (a.k.a. a hydration mismatch), the mismatch is repaired. This is very costly: setting a `src` attribute (even if it evaluates to the same thing) causes images and iframes to be reloaded, and reinserting a large blob of HTML is slow.

Since these mismatches are extremely rare, Svelte 5 assumes that the values are unchanged, but in development will warn you if they are not. To force an update you can do something like this:

```svelte
<script>
	let { markup, src } = $props();

	if (typeof window !== 'undefined') {
		// stash the values...
		const initial = { markup, src };

		// unset them...
		markup = src = undefined;

		$effect(() => {
			// ...and reset after we've mounted
			markup = initial.markup;
			src = initial.src;
		});
	}
</script>

{@html markup}
<img {src} />
```

### Hydration works differently

Svelte 5 makes use of comments during server-side rendering which are used for more robust and efficient hydration on the client. You therefore should not remove comments from your HTML output if you intend to hydrate it, and if you manually authored HTML to be hydrated by a Svelte component, you need to adjust that HTML to include said comments at the correct positions.

### `onevent` attributes are delegated

Event attributes replace event directives: Instead of `on:click={handler}` you write `onclick={handler}`. For backwards compatibility the `on:event` syntax is still supported and behaves the same as in Svelte 4. Some of the `onevent` attributes however are delegated, which means you need to take care to not stop event propagation on those manually, as they then might never reach the listener for this event type at the root.

### `--style-props` uses a different element

Svelte 5 uses an extra `<svelte-css-wrapper>` element instead of a `<div>` to wrap the component when using CSS custom properties.

<!-- TODO in final docs, add link to corresponding section for more details -->
````

----
url: https://svelte.dev/docs/svelte/imperative-component-api
----

[Skip to main content](#main)

Every Svelte application starts by imperatively creating a root component. On the client this component is mounted to a specific element. On the server, you want to get back a string of HTML instead which you can render. The following functions help you achieve those tasks.

## mount[](#mount)

Instantiates a component and mounts it to the given target:

```
import { mount(alias) function mount<Props extends Record<string, any>, Exports extends Record<string, any>>(component: ComponentType<SvelteComponent<Props>> | Component<Props, Exports, any>, options: MountOptions<Props>): Exports
import mount

Mounts a component to the given target and returns the exports and potentially the props (if compiled with accessors: true) of the component.
Transitions will play during the initial render unless the intro option is set to false.


reference } from 'svelte';
import App(alias) type App = SvelteComponent<Record<string, any>, any, any>
(alias) const App: LegacyComponentType
import App from './App.svelte';

const appconst app: {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<string, any> = mount(alias) mount<Record<string, any>, {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<string, any>>(component: ComponentType<SvelteComponent<Record<string, any>, any, any>> | Component<Record<string, any>, {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<string, any>, any>, options: MountOptions<...>): {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<...>
import mount

Mounts a component to the given target and returns the exports and potentially the props (if compiled with accessors: true) of the component.
Transitions will play during the initial render unless the intro option is set to false.


reference(App(alias) const App: LegacyComponentType
import App, {
	target(property) target: Document | Element | ShadowRoot

Target element where the component will be mounted.


: documentvar document: Document

window.document returns a reference to the document contained in the window.




MDN Reference


.querySelector(method) ParentNode.querySelector<Element>(selectors: string): Element | null (+4 overloads)

Returns the first element that is a descendant of node that matches selectors.




MDN Reference


('#app'),
	props(property) props?: Record<string, any> | undefined

Component properties.


: { some(property) some: string: 'property' }
});
```

You can mount multiple components per page, and you can also mount from within your application, for example when creating a tooltip component and attaching it to the hovered element.

Note that unlike calling `new App(...)` in Svelte 4, things like effects (including `onMount` callbacks, and action functions) will not run during `mount`. If you need to force pending effects to run (in the context of a test, for example) you can do so with `flushSync()`.

## unmount[](#unmount)

Unmounts a component that was previously created with [`mount`](#mount) or [`hydrate`](#hydrate).

If `options.outro` is `true`, [transitions](transition) will play before the component is removed from the DOM:

```
import { mount(alias) function mount<Props extends Record<string, any>, Exports extends Record<string, any>>(component: ComponentType<SvelteComponent<Props>> | Component<Props, Exports, any>, options: MountOptions<Props>): Exports
import mount

Mounts a component to the given target and returns the exports and potentially the props (if compiled with accessors: true) of the component.
Transitions will play during the initial render unless the intro option is set to false.


reference, unmount(alias) function unmount(component: Record<string, any>, options?: {
    outro?: boolean;
} | undefined): Promise<void>
import unmount

Unmounts a component that was previously mounted using mount or hydrate.




Since 5.13.0, if options.outro is true, transitions will play before the component is removed from the DOM.




Returns a Promise that resolves after transitions have completed if options.outro is true, or immediately otherwise (prior to 5.13.0, returns void).



import { mount, unmount } from 'svelte';
import App from './App.svelte';

const app = mount(App, { target: document.body });

// later...
unmount(app, { outro: true });
reference } from 'svelte';
import App(alias) type App = SvelteComponent<Record<string, any>, any, any>
(alias) const App: LegacyComponentType
import App from './App.svelte';

const appconst app: {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<string, any> = mount(alias) mount<Record<string, any>, {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<string, any>>(component: ComponentType<SvelteComponent<Record<string, any>, any, any>> | Component<Record<string, any>, {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<string, any>, any>, options: MountOptions<...>): {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<...>
import mount

Mounts a component to the given target and returns the exports and potentially the props (if compiled with accessors: true) of the component.
Transitions will play during the initial render unless the intro option is set to false.


reference(App(alias) const App: LegacyComponentType
import App, { target(property) target: Document | Element | ShadowRoot

Target element where the component will be mounted.


: documentvar document: Document

window.document returns a reference to the document contained in the window.




MDN Reference


.body(property) Document.body: HTMLElement

The Document.body property represents the  or  node of the current document, or null if no such element exists.




MDN Reference


 });

// later
unmount(alias) unmount(component: Record<string, any>, options?: {
    outro?: boolean;
} | undefined): Promise<void>
import unmount

Unmounts a component that was previously mounted using mount or hydrate.




Since 5.13.0, if options.outro is true, transitions will play before the component is removed from the DOM.




Returns a Promise that resolves after transitions have completed if options.outro is true, or immediately otherwise (prior to 5.13.0, returns void).



import { mount, unmount } from 'svelte';
import App from './App.svelte';

const app = mount(App, { target: document.body });

// later...
unmount(app, { outro: true });
reference(appconst app: {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<string, any>, { outro(property) outro?: boolean | undefined: true });
```

Returns a `Promise` that resolves after transitions have completed if `options.outro` is true, or immediately otherwise.

## render[](#render)

Only available on the server and when compiling with the `server` option. Takes a component and returns an object with `body` and `head` properties on it, which you can use to populate the HTML when server-rendering your app:

```
import { render(alias) function render<Comp extends SvelteComponent<any> | Component<any>, Props extends ComponentProps<Comp> = ComponentProps<Comp>>(...args: {} extends Props ? [component: Comp extends SvelteComponent<any> ? ComponentType<Comp> : Comp, options?: {
    props?: Omit<Props, "$$slots" | "$$events">;
    context?: Map<any, any>;
    idPrefix?: string;
    csp?: Csp;
    transformError?: (error: unknown) => unknown | Promise<unknown>;
}] : [component: Comp extends SvelteComponent<any> ? ComponentType<Comp> : Comp, options: {
    props: Omit<Props, "$$slots" | "$$events">;
    context?: Map<any, any>;
    idPrefix?: string;
    csp?: Csp;
    transformError?: (error: unknown) => unknown | Promise<unknown>;
}]): RenderOutput
import render

Only available on the server and when compiling with the server option.
Takes a component and returns an object with body and head properties on it, which you can use to populate the HTML when server-rendering your app.


reference } from 'svelte/server';
import App(alias) type App = SvelteComponent<Record<string, any>, any, any>
(alias) const App: LegacyComponentType
import App from './App.svelte';

const resultconst result: RenderOutput = render(alias) render<SvelteComponent<Record<string, any>, any, any>, Record<string, any>>(component: ComponentType<SvelteComponent<Record<string, any>, any, any>>, options?: {
    props?: Omit<Record<string, any>, "$$slots" | "$$events"> | undefined;
    context?: Map<any, any>;
    idPrefix?: string;
    csp?: Csp;
    transformError?: ((error: unknown) => unknown | Promise<unknown>) | undefined;
} | undefined): RenderOutput
import render

Only available on the server and when compiling with the server option.
Takes a component and returns an object with body and head properties on it, which you can use to populate the HTML when server-rendering your app.


reference(App(alias) const App: LegacyComponentType
import App, {
	props(property) props?: Omit<Record<string, any>, "$$slots" | "$$events"> | undefined: { some(property) some: string: 'property' }
});
resultconst result: RenderOutput.body(property) SyncRenderOutput.body: string

HTML that goes somewhere into the <body>


; // HTML for somewhere in this <body> tag
resultconst result: RenderOutput.head(property) SyncRenderOutput.head: string

HTML that goes into the <head>


; // HTML for somewhere in this <head> tag
```

## hydrate[](#hydrate)

Like `mount`, but will reuse up any HTML rendered by Svelte’s SSR output (from the [`render`](#render) function) inside the target and make it interactive:

```
import { hydrate(alias) function hydrate<Props extends Record<string, any>, Exports extends Record<string, any>>(component: ComponentType<SvelteComponent<Props>> | Component<Props, Exports, any>, options: {} extends Props ? {
    target: Document | Element | ShadowRoot;
    props?: Props;
    events?: Record<string, (e: any) => any>;
    context?: Map<any, any>;
    intro?: boolean;
    recover?: boolean;
    transformError?: (error: unknown) => unknown;
} : {
    target: Document | Element | ShadowRoot;
    props: Props;
    events?: Record<string, (e: any) => any>;
    context?: Map<any, any>;
    intro?: boolean;
    recover?: boolean;
    transformError?: (error: unknown) => unknown;
}): Exports
import hydrate

Hydrates a component on the given target and returns the exports and potentially the props (if compiled with accessors: true) of the component


reference } from 'svelte';
import App(alias) type App = SvelteComponent<Record<string, any>, any, any>
(alias) const App: LegacyComponentType
import App from './App.svelte';

const appconst app: {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<string, any> = hydrate(alias) hydrate<Record<string, any>, {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<string, any>>(component: ComponentType<SvelteComponent<Record<string, any>, any, any>> | Component<Record<string, any>, {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<string, any>, any>, options: {
    ...;
}): {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<...>
import hydrate

Hydrates a component on the given target and returns the exports and potentially the props (if compiled with accessors: true) of the component


reference(App(alias) const App: LegacyComponentType
import App, {
	target(property) target: Document | Element | ShadowRoot: documentvar document: Document

window.document returns a reference to the document contained in the window.




MDN Reference


.querySelector(method) ParentNode.querySelector<Element>(selectors: string): Element | null (+4 overloads)

Returns the first element that is a descendant of node that matches selectors.




MDN Reference


('#app'),
	props(property) props?: Record<string, any> | undefined: { some(property) some: string: 'property' }
});
```

As with `mount`, effects will not run during `hydrate` — use `flushSync()` immediately afterwards if you need them to.

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/06-runtime/04-imperative-component-api.md) [llms.txt](/docs/svelte/imperative-component-api/llms.txt)

previous next

[Lifecycle hooks](/docs/svelte/lifecycle-hooks) [Hydratable data](/docs/svelte/hydratable)

----
url: https://svelte.dev/docs/svelte/svelte-compiler
----

[Skip to main content](#main)

```
import {
	VERSION(alias) const VERSION: string
import VERSION

The current version, as set in package.json.


reference,
	compile(alias) function compile(source: string, options: CompileOptions): CompileResult
import compile

compile converts your .svelte source code into a JavaScript module that exports a component


source 

The component source code


options 

The compiler options


reference,
	compileModule(alias) function compileModule(source: string, options: ModuleCompileOptions): CompileResult
import compileModule

compileModule takes your JavaScript source code containing runes, and turns it into a JavaScript module.


source 

The component source code


reference,
	migrate(alias) function migrate(source: string, { filename, use_ts }?: {
    filename?: string;
    use_ts?: boolean;
} | undefined): {
    code: string;
}
import migrate

Does a best-effort migration of Svelte code towards using runes, event attributes and render tags.
May throw an error if the code is too complex to migrate automatically.


reference,
	parse(alias) function parse(source: string, options: {
    filename?: string;
    modern: true;
    loose?: boolean;
}): AST.Root (+1 overload)
import parse

The parse function parses a component, returning only its abstract syntax tree.




The modern option (false by default in Svelte 5) makes the parser return a modern AST instead of the legacy AST.
modern will become true by default in Svelte 6, and the option will be removed in Svelte 7.


reference,
	parseCss(alias) function parseCss(source: string): _CSS.StyleSheetFile
import parseCss

The parseCss function parses a CSS stylesheet, returning its abstract syntax tree.


source 

The CSS source code


reference,
	preprocess(alias) function preprocess(source: string, preprocessor: PreprocessorGroup | PreprocessorGroup[], options?: {
    filename?: string;
} | undefined): Promise<Processed>
import preprocess

The preprocess function provides convenient hooks for arbitrarily transforming component source code.
For example, it can be used to convert a <style lang="sass"> block into vanilla CSS.


reference,
	print(alias) function print(ast: AST.SvelteNode, options?: Options | undefined): {
    code: string;
    map: any;
}
import print

print converts a Svelte AST node back into Svelte source code.
It is primarily intended for tools that parse and transform components using the compiler’s modern AST representation.




print(ast) requires an AST node produced by parse with modern: true, or any sub-node within that modern AST.
The result contains the generated source and a corresponding source map.
The output is valid Svelte, but formatting details such as whitespace or quoting may differ from the original.


reference,
	walk(alias) function walk(): never
import walk

Replace this with import { walk } from 'estree-walker'


reference
} from 'svelte/compiler';
```

## VERSION[](#VERSION)

The current version, as set in package.json.

```
const VERSION: string;
```

## compile[](#compile)

`compile` converts your `.svelte` source code into a JavaScript module that exports a component

```
function compile(
	source: string,
	options: CompileOptions
): CompileResult;
```

## compileModule[](#compileModule)

`compileModule` takes your JavaScript source code containing runes, and turns it into a JavaScript module.

```
function compileModule(
	source: string,
	options: ModuleCompileOptions
): CompileResult;
```

## migrate[](#migrate)

Does a best-effort migration of Svelte code towards using runes, event attributes and render tags. May throw an error if the code is too complex to migrate automatically.

```
function migrate(
	source: string,
	{
		filename,
		use_ts
	}?:
		| {
				filename?: string;
				use_ts?: boolean;
		  }
		| undefined
): {
	code: string;
};
```

## parse[](#parse)

The parse function parses a component, returning only its abstract syntax tree.

The `modern` option (`false` by default in Svelte 5) makes the parser return a modern AST instead of the legacy AST. `modern` will become `true` by default in Svelte 6, and the option will be removed in Svelte 7.

```
function parse(
	source: string,
	options: {
		filename?: string;
		modern: true;
		loose?: boolean;
	}
): AST.Root;
```

```
function parse(
	source: string,
	options?:
		| {
				filename?: string;
				modern?: false;
				loose?: boolean;
		  }
		| undefined
): Record<string, any>;
```

## parseCss[](#parseCss)

The parseCss function parses a CSS stylesheet, returning its abstract syntax tree.

```
function parseCss(source: string): AST.CSS.StyleSheetFile;
```

## preprocess[](#preprocess)

The preprocess function provides convenient hooks for arbitrarily transforming component source code. For example, it can be used to convert a `<style lang="sass">` block into vanilla CSS.

```
function preprocess(
	source: string,
	preprocessor: PreprocessorGroup | PreprocessorGroup[],
	options?:
		| {
				filename?: string;
		  }
		| undefined
): Promise<Processed>;
```

## print[](#print)

`print` converts a Svelte AST node back into Svelte source code. It is primarily intended for tools that parse and transform components using the compiler’s modern AST representation.

`print(ast)` requires an AST node produced by parse with modern: true, or any sub-node within that modern AST. The result contains the generated source and a corresponding source map. The output is valid Svelte, but formatting details such as whitespace or quoting may differ from the original.

```
function print(
	ast: AST.SvelteNode,
	options?: Options | undefined
): {
	code: string;
	map: any;
};
```

## walk[](#walk)

> Replace this with `import { walk } from 'estree-walker'`

```
function walk(): never;
```

## AST[](#AST)

````
namespace AST {
	export interface BaseNode {
		type: string;
		start: number;
		end: number;
	}

	export interface Fragment {
		type: 'Fragment';
		nodes: Array<
			Text | Tag | ElementLike | Block | Comment
		>;
	}

	export interface Root extends BaseNode {
		type: 'Root';
		/**
		 * Inline options provided by `<svelte:options>` — these override options passed to `compile(...)`
		 */
		options: SvelteOptions | null;
		fragment: Fragment;
		/** The parsed `<style>` element, if exists */
		css: AST.CSS.StyleSheet | null;
		/** The parsed `<script>` element, if exists */
		instance: Script | null;
		/** The parsed `<script module>` element, if exists */
		module: Script | null;
		/** Comments found in <script> and {expressions} */
		comments: JSComment[];
	}

	export interface SvelteOptions {
		// start/end info (needed for warnings and for our Prettier plugin)
		start: number;
		end: number;
		// options
		runes?: boolean;
		immutable?: boolean;
		accessors?: boolean;
		preserveWhitespace?: boolean;
		namespace?: Namespace;
		css?: 'injected';
		customElement?: {
			tag?: string;
			shadow?:
				| 'open'
				| 'none'
				| ObjectExpression
				| undefined;
			props?: Record<
				string,
				{
					attribute?: string;
					reflect?: boolean;
					type?:
						| 'Array'
						| 'Boolean'
						| 'Number'
						| 'Object'
						| 'String';
				}
			>;
			/**
			 * Is of type
			 * ```ts
			 * (ceClass: new () => HTMLElement) => new () => HTMLElement
			 * ```
			 */
			extend?: ArrowFunctionExpression | Identifier;
		};
		attributes: Attribute[];
	}

	/** Static text */
	export interface Text extends BaseNode {
		type: 'Text';
		/** Text with decoded HTML entities */
		data: string;
		/** The original text, with undecoded HTML entities */
		raw: string;
	}

	/** A (possibly reactive) template expression — `{...}` */
	export interface ExpressionTag extends BaseNode {
		type: 'ExpressionTag';
		expression: Expression;
	}

	/** A (possibly reactive) HTML template expression — `{@html ...}` */
	export interface HtmlTag extends BaseNode {
		type: 'HtmlTag';
		expression: Expression;
	}

	/** An HTML comment */
	// TODO rename to disambiguate
	export interface Comment extends BaseNode {
		type: 'Comment';
		/** the contents of the comment */
		data: string;
	}

	/** A `{@const ...}` tag */
	export interface ConstTag extends BaseNode {
		type: 'ConstTag';
		declaration: VariableDeclaration & {
			declarations: [
				VariableDeclarator & {
					id: Pattern;
					init: Expression;
				}
			];
		};
	}

	/** A `{let ...}` or `{const ...}` tag */
	export interface DeclarationTag extends BaseNode {
		type: 'DeclarationTag';
		declaration: VariableDeclaration;
	}

	/** A `{@debug ...}` tag */
	export interface DebugTag extends BaseNode {
		type: 'DebugTag';
		identifiers: Identifier[];
	}

	/** A `{@render foo(...)} tag */
	export interface RenderTag extends BaseNode {
		type: 'RenderTag';
		expression:
			| SimpleCallExpression
			| (ChainExpression & {
					expression: SimpleCallExpression;
			  });
	}

	/** A `{@attach foo(...)} tag */
	export interface AttachTag extends BaseNode {
		type: 'AttachTag';
		expression: Expression;
	}

	/** An `animate:` directive */
	export interface AnimateDirective extends BaseAttribute {
		type: 'AnimateDirective';
		/** The 'x' in `animate:x` */
		name: string;
		/** The y in `animate:x={y}` */
		expression: null | Expression;
	}

	/** A `bind:` directive */
	export interface BindDirective extends BaseAttribute {
		type: 'BindDirective';
		/** The 'x' in `bind:x` */
		name: string;
		/** The y in `bind:x={y}` */
		expression:
			| Identifier
			| MemberExpression
			| SequenceExpression;
	}

	/** A `class:` directive */
	export interface ClassDirective extends BaseAttribute {
		type: 'ClassDirective';
		/** The 'x' in `class:x` */
		name: 'class';
		/** The 'y' in `class:x={y}`, or the `x` in `class:x` */
		expression: Expression;
	}

	/** A `let:` directive */
	export interface LetDirective extends BaseAttribute {
		type: 'LetDirective';
		/** The 'x' in `let:x` */
		name: string;
		/** The 'y' in `let:x={y}` */
		expression:
			| null
			| Identifier
			| ArrayExpression
			| ObjectExpression;
	}

	/** An `on:` directive */
	export interface OnDirective extends BaseAttribute {
		type: 'OnDirective';
		/** The 'x' in `on:x` */
		name: string;
		/** The 'y' in `on:x={y}` */
		expression: null | Expression;
		modifiers: Array<
			| 'capture'
			| 'nonpassive'
			| 'once'
			| 'passive'
			| 'preventDefault'
			| 'self'
			| 'stopImmediatePropagation'
			| 'stopPropagation'
			| 'trusted'
		>;
	}

	/** A `style:` directive */
	export interface StyleDirective extends BaseAttribute {
		type: 'StyleDirective';
		/** The 'x' in `style:x` */
		name: string;
		/** The 'y' in `style:x={y}` */
		value:
			| true
			| ExpressionTag
			| Array<ExpressionTag | Text>;
		modifiers: Array<'important'>;
	}

	// TODO have separate in/out/transition directives
	/** A `transition:`, `in:` or `out:` directive */
	export interface TransitionDirective extends BaseAttribute {
		type: 'TransitionDirective';
		/** The 'x' in `transition:x` */
		name: string;
		/** The 'y' in `transition:x={y}` */
		expression: null | Expression;
		modifiers: Array<'local' | 'global'>;
		/** True if this is a `transition:` or `in:` directive */
		intro: boolean;
		/** True if this is a `transition:` or `out:` directive */
		outro: boolean;
	}

	/** A `use:` directive */
	export interface UseDirective extends BaseAttribute {
		type: 'UseDirective';
		/** The 'x' in `use:x` */
		name: string;
		/** The 'y' in `use:x={y}` */
		expression: null | Expression;
	}

	export interface BaseElement extends BaseNode {
		name: string;
		name_loc: SourceLocation;
		attributes: Array<
			Attribute | SpreadAttribute | Directive | AttachTag
		>;
		fragment: Fragment;
	}

	export interface Component extends BaseElement {
		type: 'Component';
	}

	export interface TitleElement extends BaseElement {
		type: 'TitleElement';
		name: 'title';
	}

	export interface SlotElement extends BaseElement {
		type: 'SlotElement';
		name: 'slot';
	}

	export interface RegularElement extends BaseElement {
		type: 'RegularElement';
	}

	export interface SvelteBody extends BaseElement {
		type: 'SvelteBody';
		name: 'svelte:body';
	}

	export interface SvelteComponent extends BaseElement {
		type: 'SvelteComponent';
		name: 'svelte:component';
		expression: Expression;
	}

	export interface SvelteDocument extends BaseElement {
		type: 'SvelteDocument';
		name: 'svelte:document';
	}

	export interface SvelteElement extends BaseElement {
		type: 'SvelteElement';
		name: 'svelte:element';
		tag: Expression;
	}

	export interface SvelteFragment extends BaseElement {
		type: 'SvelteFragment';
		name: 'svelte:fragment';
	}

	export interface SvelteBoundary extends BaseElement {
		type: 'SvelteBoundary';
		name: 'svelte:boundary';
	}

	export interface SvelteHead extends BaseElement {
		type: 'SvelteHead';
		name: 'svelte:head';
	}

	/** This is only an intermediate representation while parsing, it doesn't exist in the final AST */
	export interface SvelteOptionsRaw extends BaseElement {
		type: 'SvelteOptions';
		name: 'svelte:options';
	}

	export interface SvelteSelf extends BaseElement {
		type: 'SvelteSelf';
		name: 'svelte:self';
	}

	export interface SvelteWindow extends BaseElement {
		type: 'SvelteWindow';
		name: 'svelte:window';
	}

	/** An `{#each ...}` block */
	export interface EachBlock extends BaseNode {
		type: 'EachBlock';
		expression: Expression;
		/** The `entry` in `{#each item as entry}`. `null` if `as` part is omitted */
		context: Pattern | null;
		body: Fragment;
		fallback?: Fragment;
		index?: string;
		key?: Expression;
	}

	/** An `{#if ...}` block */
	export interface IfBlock extends BaseNode {
		type: 'IfBlock';
		elseif: boolean;
		test: Expression;
		consequent: Fragment;
		alternate: Fragment | null;
	}

	/** An `{#await ...}` block */
	export interface AwaitBlock extends BaseNode {
		type: 'AwaitBlock';
		expression: Expression;
		// TODO can/should we move these inside the ThenBlock and CatchBlock?
		/** The resolved value inside the `then` block */
		value: Pattern | null;
		/** The rejection reason inside the `catch` block */
		error: Pattern | null;
		pending: Fragment | null;
		then: Fragment | null;
		catch: Fragment | null;
	}

	export interface KeyBlock extends BaseNode {
		type: 'KeyBlock';
		expression: Expression;
		fragment: Fragment;
	}

	export interface SnippetBlock extends BaseNode {
		type: 'SnippetBlock';
		expression: Identifier;
		parameters: Pattern[];
		typeParams?: string;
		body: Fragment;
	}

	export interface BaseAttribute extends BaseNode {
		name: string;
		name_loc: SourceLocation | null;
	}

	export interface Attribute extends BaseAttribute {
		type: 'Attribute';
		/**
		 * Quoted/string values are represented by an array, even if they contain a single expression like `"{x}"`
		 */
		value:
			| true
			| ExpressionTag
			| Array<Text | ExpressionTag>;
	}

	export interface SpreadAttribute extends BaseNode {
		type: 'SpreadAttribute';
		expression: Expression;
	}

	export interface Script extends BaseNode {
		type: 'Script';
		context: 'default' | 'module';
		content: Program;
		attributes: Attribute[];
	}

	export interface JSComment {
		type: 'Line' | 'Block';
		value: string;
		start: number;
		end: number;
		loc: {
			start: { line: number; column: number };
			end: { line: number; column: number };
		};
	}

	export type AttributeLike =
		| Attribute
		| SpreadAttribute
		| Directive;

	export type Directive =
		| AST.AnimateDirective
		| AST.BindDirective
		| AST.ClassDirective
		| AST.LetDirective
		| AST.OnDirective
		| AST.StyleDirective
		| AST.TransitionDirective
		| AST.UseDirective;

	export type Block =
		| AST.EachBlock
		| AST.IfBlock
		| AST.AwaitBlock
		| AST.KeyBlock
		| AST.SnippetBlock;

	export type ElementLike =
		| AST.Component
		| AST.TitleElement
		| AST.SlotElement
		| AST.RegularElement
		| AST.SvelteBody
		| AST.SvelteBoundary
		| AST.SvelteComponent
		| AST.SvelteDocument
		| AST.SvelteElement
		| AST.SvelteFragment
		| AST.SvelteHead
		| AST.SvelteOptionsRaw
		| AST.SvelteSelf
		| AST.SvelteWindow
		| AST.SvelteBoundary;

	export type Tag =
		| AST.AttachTag
		| AST.ConstTag
		| AST.DeclarationTag
		| AST.DebugTag
		| AST.ExpressionTag
		| AST.HtmlTag
		| AST.RenderTag;

	export type TemplateNode =
		| AST.Root
		| AST.Text
		| Tag
		| ElementLike
		| AST.Attribute
		| AST.SpreadAttribute
		| Directive
		| AST.AttachTag
		| AST.Comment
		| Block;

	export type SvelteNode =
		| Node
		| TemplateNode
		| AST.Fragment
		| _CSS.Node
		| Script;

	export type { _CSS as CSS };
}
````

## CompileError[](#CompileError)

```
interface CompileError extends ICompileDiagnostic {}
```

## CompileOptions[](#CompileOptions)

```
interface CompileOptions extends ModuleCompileOptions {/*…*/}
```

```
name?: string;
```

Sets the name of the resulting JavaScript class (though the compiler will rename it if it would otherwise conflict with other variables in scope). If unspecified, will be inferred from `filename`

```
customElement?: boolean | ((options: { filename: string }) => boolean);
```

* default `false`

If `true`, tells the compiler to generate a custom element constructor instead of a regular Svelte component.

You can also pass a function that receives `{ filename }` and returns a boolean.

```
accessors?: boolean;
```

* default `false`
* deprecated This will have no effect in runes mode

If `true`, getters and setters will be created for the component’s props. If `false`, they will only be created for readonly exported values (i.e. those declared with `const`, `class` and `function`). If compiling with `customElement: true` this option defaults to `true`.

```
namespace?: Namespace;
```

* default `'html'`

The namespace of the element; e.g., `"html"`, `"svg"`, `"mathml"`.

```
immutable?: boolean;
```

* default `false`
* deprecated This will have no effect in runes mode

If `true`, tells the compiler that you promise not to mutate any objects. This allows it to be less conservative about checking whether values have changed.

```
css?: 'injected' | 'external' | ((options: { filename: string }) => 'injected' | 'external');
```

* `'injected'`: styles will be included in the `head` when using `render(...)`, and injected into the document (if not already present) when the component mounts. For components compiled as custom elements, styles are injected to the shadow root.
* `'external'`: the CSS will only be returned in the `css` field of the compilation result. Most Svelte bundler plugins will set this to `'external'` and use the CSS that is statically generated for better performance, as it will result in smaller JavaScript bundles and the output can be served as cacheable `.css` files. This is always `'injected'` when compiling with `customElement` mode.

You can also pass a function that receives `{ filename }` and returns either `'injected'` or `'external'`.

```
cssHash?: CssHashGetter;
```

* default `undefined`

A function that takes a `{ hash, css, name, filename }` argument and returns the string that is used as a classname for scoped CSS. It defaults to returning `svelte-${hash(filename ?? css)}`.

```
preserveComments?: boolean;
```

* default `false`

If `true`, your HTML comments will be preserved in the output. By default, they are stripped out.

```
preserveWhitespace?: boolean;
```

* default `false`

If `true`, whitespace inside and between elements is kept as you typed it, rather than removed or collapsed to a single space where possible.

```
fragments?: 'html' | 'tree';
```

* default `'html'`
* available since v5.33

Which strategy to use when cloning DOM fragments:

* `html` populates a `<template>` with `innerHTML` and clones it. This is faster, but cannot be used if your app’s [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP) includes [`require-trusted-types-for 'script'`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy/require-trusted-types-for)
* `tree` creates the fragment one element at a time and *then* clones it. This is slower, but works everywhere

```
runes?: boolean | undefined | ((options: { filename: string }) => boolean | undefined);
```

* default `undefined`

Set to `true` to force the compiler into runes mode, even if there are no indications of runes usage. Set to `false` to force the compiler into ignoring runes, even if there are indications of runes usage. Set to `undefined` (the default) to infer runes mode from the component code. Is always `true` for JS/TS modules compiled with Svelte. Will be `true` by default in Svelte 6. Note that setting this to `true` in your `svelte.config.js` will force runes mode for your entire project, including components in `node_modules`, which is likely not what you want. If you’re using Vite, consider using [dynamicCompileOptions](https://github.com/sveltejs/vite-plugin-svelte/blob/main/docs/config.md#dynamiccompileoptions) instead.

```
discloseVersion?: boolean;
```

* default `true`

If `true`, exposes the Svelte major version in the browser by adding it to a `Set` stored in the global `window.__svelte.v`.

```
compatibility?: {/*…*/};
```

* deprecated Use these only as a temporary solution before migrating your code

```
componentApi?: 4 | 5;
```

* default `5`

Applies a transformation so that the default export of Svelte files can still be instantiated the same way as in Svelte 4 — as a class when compiling for the browser (as though using `createClassComponent(MyComponent, {...})` from `svelte/legacy`) or as an object with a `.render(...)` method when compiling for the server

```
sourcemap?: object | string;
```

* default `null`

An initial sourcemap that will be merged into the final output sourcemap. This is usually the preprocessor sourcemap.

```
outputFilename?: string;
```

* default `null`

Used for your JavaScript sourcemap.

```
cssOutputFilename?: string;
```

* default `null`

Used for your CSS sourcemap.

```
hmr?: boolean;
```

* default `false`

If `true`, compiles components with hot reloading support.

```
modernAst?: boolean;
```

* default `false`

If `true`, returns the modern version of the AST. Will become `true` by default in Svelte 6, and the option will be removed in Svelte 7.

## CompileResult[](#CompileResult)

The return value of `compile` from `svelte/compiler`

```
interface CompileResult {/*…*/}
```

```
js: {/*…*/};
```

The compiled JavaScript

```
code: string;
```

The generated code

```
map: SourceMap;
```

A source map

```
css: null | {/*…*/};
```

The compiled CSS

```
code: string;
```

The generated code

```
map: SourceMap;
```

A source map

```
hasGlobal: boolean;
```

Whether or not the CSS includes global rules

```
warnings: Warning[];
```

An array of warning objects that were generated during compilation. Each warning has several properties:

* `code` is a string identifying the category of warning
* `message` describes the issue in human-readable terms
* `start` and `end`, if the warning relates to a specific location, are objects with `line`, `column` and `character` properties

```
metadata: {/*…*/};
```

Metadata about the compiled component

```
runes: boolean;
```

Whether the file was compiled in runes mode, either because of an explicit option or inferred from usage. For `compileModule`, this is always `true`

```
ast: any;
```

The AST

## MarkupPreprocessor[](#MarkupPreprocessor)

A markup preprocessor that takes a string of code and returns a processed version.

```
type MarkupPreprocessor = (options: {
	/**
	 * The whole Svelte file content
	 */
	content: string;
	/**
	 * The filename of the Svelte file
	 */
	filename?: string;
}) => Processed | void | Promise<Processed | void>;
```

## ModuleCompileOptions[](#ModuleCompileOptions)

```
interface ModuleCompileOptions {/*…*/}
```

```
dev?: boolean;
```

* default `false`

If `true`, causes extra code to be added that will perform runtime checks and provide debugging information during development.

```
generate?: 'client' | 'server' | false;
```

* default `'client'`

If `"client"`, Svelte emits code designed to run in the browser. If `"server"`, Svelte emits code suitable for server-side rendering. If `false`, nothing is generated. Useful for tooling that is only interested in warnings.

```
filename?: string;
```

Used for debugging hints and sourcemaps. Your bundler plugin will set it automatically.

```
rootDir?: string;
```

* default `process.cwd() on node-like environments, undefined elsewhere`

Used for ensuring filenames don’t leak filesystem information. Your bundler plugin will set it automatically.

```
warningFilter?: (warning: Warning) => boolean;
```

A function that gets a `Warning` as an argument and returns a boolean. Use this to filter out warnings. Return `true` to keep the warning, `false` to discard it.

```
experimental?: {/*…*/};
```

* available since v5.36

Experimental options

```
async?: boolean;
```

* available since v5.36

Allow `await` keyword in deriveds, template expressions, and the top level of components

## Preprocessor[](#Preprocessor)

A script/style preprocessor that takes a string of code and returns a processed version.

```
type Preprocessor = (options: {
	/**
	 * The script/style tag content
	 */
	content: string;
	/**
	 * The attributes on the script/style tag
	 */
	attributes: Record<string, string | boolean>;
	/**
	 * The whole Svelte file content
	 */
	markup: string;
	/**
	 * The filename of the Svelte file
	 */
	filename?: string;
}) => Processed | void | Promise<Processed | void>;
```

## PreprocessorGroup[](#PreprocessorGroup)

A preprocessor group is a set of preprocessors that are applied to a Svelte file.

```
interface PreprocessorGroup {/*…*/}
```

```
name?: string;
```

Name of the preprocessor. Will be a required option in the next major version

```
markup?: MarkupPreprocessor;
```

```
style?: Preprocessor;
```

```
script?: Preprocessor;
```

## Processed[](#Processed)

The result of a preprocessor run. If the preprocessor does not return a result, it is assumed that the code is unchanged.

```
interface Processed {/*…*/}
```

```
code: string;
```

The new code

```
map?: string | object;
```

A source map mapping back to the original code

```
dependencies?: string[];
```

A list of additional files to watch for changes

```
attributes?: Record<string, string | boolean>;
```

Only for script/style preprocessors: The updated attributes to set on the tag. If undefined, attributes stay unchanged.

```
toString?: () => string;
```

## Warning[](#Warning)

```
interface Warning extends ICompileDiagnostic {}
```

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/98-reference/21-svelte-compiler.md) [llms.txt](/docs/svelte/svelte-compiler/llms.txt)

previous next

[svelte/attachments](/docs/svelte/svelte-attachments) [svelte/easing](/docs/svelte/svelte-easing)

----
url: https://svelte.dev/docs/svelte/svelte-reactivity/llms.txt
----

````
Svelte provides reactive versions of various built-ins like [`Map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map), [`Set`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set) and [`URL`](https://developer.mozilla.org/en-US/docs/Web/API/URL) that can be used just like their native counterparts, as well as a handful of additional utilities for handling reactivity.



```js
// @noErrors
import {
	MediaQuery,
	SvelteDate,
	SvelteMap,
	SvelteSet,
	SvelteURL,
	SvelteURLSearchParams,
	createSubscriber
} from 'svelte/reactivity';
```

## MediaQuery

<blockquote class="since note">

Available since 5.7.0

</blockquote>

Creates a media query and provides a `current` property that reflects whether or not it matches.

Use it carefully — during server-side rendering, there is no way to know what the correct value should be, potentially causing content to change upon hydration.
If you can use the media query in CSS to achieve the same effect, do that.

```svelte
<script>
	import { MediaQuery } from 'svelte/reactivity';

	const large = new MediaQuery('min-width: 800px');
</script>

<h1>{large.current ? 'large screen' : 'small screen'}</h1>
```

<div class="ts-block">

```dts
class MediaQuery extends ReactiveValue<boolean> {/*…*/}
```

<div class="ts-block-property">

```dts
constructor(query: string, fallback?: boolean | undefined);
```

<div class="ts-block-property-details">

<div class="ts-block-property-bullets">

- `query` A media query string
- `fallback` Fallback value for the server

</div>

</div>
</div></div>



## SvelteDate

A reactive version of the built-in [`Date`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) object.
Reading the date (whether with methods like `date.getTime()` or `date.toString()`, or via things like [`Intl.DateTimeFormat`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat))
in an [effect](/docs/svelte/$effect) or [derived](/docs/svelte/$derived)
will cause it to be re-evaluated when the value of the date changes.

```svelte
<script>
	import { SvelteDate } from 'svelte/reactivity';

	const date = new SvelteDate();

	const formatter = new Intl.DateTimeFormat(undefined, {
	  hour: 'numeric',
	  minute: 'numeric',
	  second: 'numeric'
	});

	$effect(() => {
		const interval = setInterval(() => {
			date.setTime(Date.now());
		}, 1000);

		return () => {
			clearInterval(interval);
		};
	});
</script>

<p>The time is {formatter.format(date)}</p>
```

<div class="ts-block">

```dts
class SvelteDate extends Date {/*…*/}
```

<div class="ts-block-property">

```dts
constructor(...params: any[]);
```

<div class="ts-block-property-details"></div>
</div></div>



## SvelteMap

A reactive version of the built-in [`Map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) object.
Reading contents of the map (by iterating, or by reading `map.size` or calling `map.get(...)` or `map.has(...)` as in the tic-tac-toe example
will cause it to be re-evaluated as necessary when the map is updated.

Note that values in a reactive map are _not_ made [deeply reactive](/docs/svelte/$state#Deep-state).

```svelte
<script>
	import { SvelteMap } from 'svelte/reactivity';
	import { result } from './game.js';

	let board = new SvelteMap();
	let player = $state('x');
	let winner = $derived(result(board));

	function reset() {
		player = 'x';
		board.clear();
	}
</script>

<div class="board">
	{#each Array(9), i}
		<button
			disabled={board.has(i) || winner}
			onclick={() => {
				board.set(i, player);
				player = player === 'x' ? 'o' : 'x';
			}}
		>{board.get(i)}</button>
	{/each}
</div>

{#if winner}
	<p>{winner} wins!</p>
	<button onclick={reset}>reset</button>
{:else}
	<p>{player} is next</p>
{/if}
```

<div class="ts-block">

```dts
class SvelteMap<K, V> extends Map<K, V> {/*…*/}
```

<div class="ts-block-property">

```dts
constructor(value?: Iterable<readonly [K, V]> | null | undefined);
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
getOrInsert(key: K, value: V): V;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
getOrInsertComputed(key: K, callbackFn: (key: K) => V): V;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
set(key: K, value: V): this;
```

<div class="ts-block-property-details"></div>
</div></div>



## SvelteSet

A reactive version of the built-in [`Set`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set) object.
Reading contents of the set (by iterating, or by reading `set.size` or calling `set.has(...)` as in the example
will cause it to be re-evaluated as necessary when the set is updated.

Note that values in a reactive set are _not_ made [deeply reactive](/docs/svelte/$state#Deep-state).

```svelte
<script>
	import { SvelteSet } from 'svelte/reactivity';
	let monkeys = new SvelteSet();

	function toggle(monkey) {
		if (monkeys.has(monkey)) {
			monkeys.delete(monkey);
		} else {
			monkeys.add(monkey);
		}
	}
</script>

{#each ['🙈', '🙉', '🙊'] as monkey}
	<button onclick={() => toggle(monkey)}>{monkey}</button>
{/each}

<button onclick={() => monkeys.clear()}>clear</button>

{#if monkeys.has('🙈')}<p>see no evil</p>{/if}
{#if monkeys.has('🙉')}<p>hear no evil</p>{/if}
{#if monkeys.has('🙊')}<p>speak no evil</p>{/if}
```

<div class="ts-block">

```dts
class SvelteSet<T> extends Set<T> {/*…*/}
```

<div class="ts-block-property">

```dts
constructor(value?: Iterable<T> | null | undefined);
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
add(value: T): this;
```

<div class="ts-block-property-details"></div>
</div></div>



## SvelteURL

A reactive version of the built-in [`URL`](https://developer.mozilla.org/en-US/docs/Web/API/URL) object.
Reading properties of the URL (such as `url.href` or `url.pathname`) in an [effect](/docs/svelte/$effect) or [derived](/docs/svelte/$derived)
will cause it to be re-evaluated as necessary when the URL changes.

The `searchParams` property is an instance of [SvelteURLSearchParams](/docs/svelte/svelte-reactivity#SvelteURLSearchParams).

Example:

```svelte
<script>
	import { SvelteURL } from 'svelte/reactivity';

	const url = new SvelteURL('https://example.com/path');
</script>

<!-- changes to these... -->
<input bind:value={url.protocol} />
<input bind:value={url.hostname} />
<input bind:value={url.pathname} />

<hr />

<!-- will update `href` and vice versa -->
<input bind:value={url.href} size="65" />
```

<div class="ts-block">

```dts
class SvelteURL extends URL {/*…*/}
```

<div class="ts-block-property">

```dts
get searchParams(): SvelteURLSearchParams;
```

<div class="ts-block-property-details"></div>
</div></div>



## SvelteURLSearchParams

A reactive version of the built-in [`URLSearchParams`](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams) object.
Reading its contents (by iterating, or by calling `params.get(...)` or `params.getAll(...)` as in the example
will cause it to be re-evaluated as necessary when the params are updated.

```svelte
<script>
	import { SvelteURLSearchParams } from 'svelte/reactivity';

	const params = new SvelteURLSearchParams('message=hello');

	let key = $state('key');
	let value = $state('value');
</script>

<input bind:value={key} />
<input bind:value={value} />
<button onclick={() => params.append(key, value)}>append</button>

<p>?{params.toString()}</p>

{#each params as [key, value]}
	<p>{key}: {value}</p>
{/each}
```

<div class="ts-block">

```dts
class SvelteURLSearchParams extends URLSearchParams {/*…*/}
```

<div class="ts-block-property">

```dts
[REPLACE](params: URLSearchParams): void;
```

<div class="ts-block-property-details"></div>
</div></div>



## createSubscriber

<blockquote class="since note">

Available since 5.7.0

</blockquote>

Returns a `subscribe` function that integrates external event-based systems with Svelte's reactivity.
It's particularly useful for integrating with web APIs like `MediaQuery`, `IntersectionObserver`, or `WebSocket`.

If `subscribe` is called inside an effect (including indirectly, for example inside a getter),
the `start` callback will be called with an `update` function. Whenever `update` is called, the effect re-runs.

If `start` returns a cleanup function, it will be called when the effect is destroyed.

If `subscribe` is called in multiple effects, `start` will only be called once as long as the effects
are active, and the returned teardown function will only be called when all effects are destroyed.

It's best understood with an example. Here's an implementation of [`MediaQuery`](/docs/svelte/svelte-reactivity#MediaQuery):

```js
// @errors: 7031
import { createSubscriber } from 'svelte/reactivity';
import { on } from 'svelte/events';

export class MediaQuery {
	#query;
	#subscribe;

	constructor(query) {
		this.#query = window.matchMedia(`(${query})`);

		this.#subscribe = createSubscriber((update) => {
			// when the `change` event occurs, re-run any effects that read `this.current`
			const off = on(this.#query, 'change', update);

			// stop listening when all the effects are destroyed
			return () => off();
		});
	}

	get current() {
		// This makes the getter reactive, if read in an effect
		this.#subscribe();

		// Return the current state of the query, whether or not we're in an effect
		return this.#query.matches;
	}
}
```

<div class="ts-block">

```dts
function createSubscriber(
	start: (update: () => void) => (() => void) | void
): () => void;
```

</div>
````

----
url: https://svelte.dev/docs/svelte/faq
----

[Skip to main content](#main)

## I’m new to Svelte. Where should I start?[](#I'm-new-to-Svelte.-Where-should-I-start)

We think the best way to get started is playing through the interactive [tutorial](/tutorial). Each step there is mainly focused on one specific aspect and is easy to follow. You’ll be editing and running real Svelte components right in your browser.

Five to ten minutes should be enough to get you up and running. An hour and a half should get you through the entire tutorial.

## Where can I get support?[](#Where-can-I-get-support)

If your question is about certain syntax, the [reference docs](/docs/svelte) are a good place to start.

Stack Overflow is a popular forum to ask code-level questions or if you’re stuck with a specific error. Read through the existing questions tagged with [Svelte](https://stackoverflow.com/questions/tagged/svelte+or+svelte-3) or [ask your own](https://stackoverflow.com/questions/ask?tags=svelte)!

There are online forums and chats which are a great place for discussion about best practices, application architecture or just to get to know fellow Svelte users. [Our Discord](/chat) or [the Reddit channel](https://www.reddit.com/r/sveltejs/) are examples of that. If you have an answerable code-level question, Stack Overflow is usually a better fit.

## Are there any third-party resources?[](#Are-there-any-third-party-resources)

Svelte Society maintains a [list of books and videos](https://sveltesociety.dev/collection/a-list-of-books-and-courses-ac01dd10363184fa).

## How can I get VS Code to syntax-highlight my .svelte files?[](#How-can-I-get-VS-Code-to-syntax-highlight-my-.svelte-files)

There is an [official VS Code extension for Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode).

## Is there a tool to automatically format my .svelte files?[](#Is-there-a-tool-to-automatically-format-my-.svelte-files)

You can use prettier with the [prettier-plugin-svelte](https://www.npmjs.com/package/prettier-plugin-svelte) plugin.

## How do I document my components?[](#How-do-I-document-my-components)

In editors which use the Svelte Language Server you can document Components, functions and exports using specially formatted comments.

````
<script>
	/** What should we call the user? */
	export let name = 'world';
</script>

<!--
@component
Here's some documentation for this component.
It will show up on hover.

- You can use markdown here.
- You can also use code blocks here.
- Usage:
  ```svelte
  <main name="Arethra">
  ```
-->
<main>
	<h1>
		Hello, {name}
	</h1>
</main>
````

Note: The `@component` is necessary in the HTML comment which describes your component.

## Does Svelte scale?[](#Does-Svelte-scale)

There will be a blog post about this eventually, but in the meantime, check out [this issue](https://github.com/sveltejs/svelte/issues/2546).

## Is there a UI component library?[](#Is-there-a-UI-component-library)

There are several [UI component libraries](/packages#component-libraries) as well as standalone components listed on [the packages page](/packages).

## How do I test Svelte apps?[](#How-do-I-test-Svelte-apps)

How your application is structured and where logic is defined will determine the best way to ensure it is properly tested. It is important to note that not all logic belongs within a component — this includes concerns such as data transformation, cross-component state management, and logging, among others. Remember that the Svelte library has its own test suite, so you do not need to write tests to validate implementation details provided by Svelte.

A Svelte application will typically have three different types of tests: Unit, Component, and End-to-End (E2E).

*Unit Tests*: Focus on testing business logic in isolation. Often this is validating individual functions and edge cases. By minimizing the surface area of these tests they can be kept lean and fast, and by extracting as much logic as possible from your Svelte components more of your application can be covered using them. When creating a new SvelteKit project, you will be asked whether you would like to setup [Vitest](https://vitest.dev/) for unit testing. There are a number of other test runners that could be used as well.

*Component Tests*: Validating that a Svelte component mounts and interacts as expected throughout its lifecycle requires a tool that provides a Document Object Model (DOM). Components can be compiled (since Svelte is a compiler and not a normal library) and mounted to allow asserting against element structure, listeners, state, and all the other capabilities provided by a Svelte component. Tools for component testing range from an in-memory implementation like jsdom paired with a test runner like [Vitest](https://vitest.dev/) to solutions that leverage an actual browser to provide a visual testing capability such as [Playwright](https://playwright.dev/docs/test-components) or [Cypress](https://www.cypress.io/).

*End-to-End Tests*: To ensure your users are able to interact with your application it is necessary to test it as a whole in a manner as close to production as possible. This is done by writing end-to-end (E2E) tests which load and interact with a deployed version of your application in order to simulate how the user will interact with your application. When creating a new SvelteKit project, you will be asked whether you would like to setup [Playwright](https://playwright.dev/) for end-to-end testing. There are many other E2E test libraries available for use as well.

Some resources for getting started with testing:

* [Svelte docs on testing](/docs/svelte/testing)
* [Setup Vitest using the Svelte CLI](/docs/cli/vitest)
* [Svelte Testing Library](https://testing-library.com/docs/svelte-testing-library/example/)
* [Svelte Component Testing in Cypress](https://docs.cypress.io/guides/component-testing/svelte/overview)
* [Example using uvu test runner with JSDOM](https://github.com/lukeed/uvu/tree/master/examples/svelte)
* [Test Svelte components using Vitest & Playwright](https://davipon.hashnode.dev/test-svelte-component-using-vitest-playwright)
* [Component testing with WebdriverIO](https://webdriver.io/docs/component-testing/svelte)

## Is there a router?[](#Is-there-a-router)

The official routing library is [SvelteKit](/docs/kit). SvelteKit provides a filesystem router, server-side rendering (SSR), and hot module reloading (HMR) in one easy-to-use package. It shares similarities with Next.js for React and Nuxt.js for Vue. SvelteKit also supports hash-based routing for client-side applications.

However, you can use any router library. A sampling of available routers are highlighted [on the packages page](/packages#routing).

## How do I write a mobile app with Svelte?[](#How-do-I-write-a-mobile-app-with-Svelte)

While most mobile apps are written without using JavaScript, if you’d like to leverage your existing Svelte components and knowledge of Svelte when building mobile apps, you can turn a [SvelteKit SPA](https://kit.svelte.dev/docs/single-page-apps) into a mobile app with [Tauri](https://v2.tauri.app/start/frontend/sveltekit/) or [Capacitor](https://capacitorjs.com/solution/svelte). Mobile features like the camera, geolocation, and push notifications are available via plugins for both platforms.

You can also write apps in Svelte that compiles to native components by using [Symbiote Native](https://docs.symbiote-native.dev/), which leverages the infrastructure provided by React Native.

Work has been completed towards [custom renderer support in Svelte 5](https://github.com/sveltejs/svelte/issues/15470), but this feature is not yet merged. The custom rendering API will allow support in additional mobile frameworks like Lynx JS and Svelte Native. Symbiote Native will also adopt this API. Svelte Native was an option available for Svelte 4, but Svelte 5 does not currently support it. Svelte Native lets you write NativeScript apps using Svelte components that contain [NativeScript UI components](https://docs.nativescript.org/ui/) rather than DOM elements.

## Can I tell Svelte not to remove my unused styles?[](#Can-I-tell-Svelte-not-to-remove-my-unused-styles)

No. Svelte removes the styles from the component and warns you about them in order to prevent issues that would otherwise arise.

Svelte’s component style scoping works by generating a class unique to the given component, adding it to the relevant elements in the component that are under Svelte’s control, and then adding it to each of the selectors in that component’s styles. When the compiler can’t see what elements a style selector applies to, there would be two bad options for keeping it:

* If it keeps the selector and adds the scoping class to it, the selector will likely not match the expected elements in the component, and they definitely won’t if they were created by a child component or `{@html ...}`.
* If it keeps the selector without adding the scoping class to it, the given style will become a global style, affecting your entire page.

If you need to style something that Svelte can’t identify at compile time, you will need to explicitly opt into global styles by using `:global(...)`. But also keep in mind that you can wrap `:global(...)` around only part of a selector. `.foo :global(.bar) { ... }` will style any `.bar` elements that appear within the component’s `.foo` elements. As long as there’s some parent element in the current component to start from, partially global selectors like this will almost always be able to get you what you want.

## Is Svelte v2 still available?[](#Is-Svelte-v2-still-available)

New features aren’t being added to it, and bugs will probably only be fixed if they are extremely nasty or present some sort of security vulnerability.

The documentation is still available [here](https://v2.svelte.dev/guide).

## How do I do hot module reloading?[](#How-do-I-do-hot-module-reloading)

We recommend using [SvelteKit](/docs/kit), which supports HMR out of the box and is built on top of [Vite](https://vitejs.dev/) and [svelte-hmr](https://github.com/sveltejs/svelte-hmr). There are also community plugins for [rollup](https://github.com/rixo/rollup-plugin-svelte-hot) and [webpack](https://github.com/sveltejs/svelte-loader).

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/07-misc/99-faq.md) [llms.txt](/docs/svelte/faq/llms.txt)

previous next

[Svelte 5 migration guide](/docs/svelte/v5-migration-guide) [svelte](/docs/svelte/svelte)

----
url: https://svelte.dev/docs/svelte/legacy-svelte-self
----

[Skip to main content](#main)

The `<svelte:self>` element allows a component to include itself, recursively.

It cannot appear at the top level of your markup; it must be inside an if or each block or passed to a component’s slot to prevent an infinite loop.

```
<script>
	export let count;
</script>

{#if count > 0}
	<p>counting down... {count}</p>
	<svelte:self count={count - 1} />
{:else}
	<p>lift-off!</p>
{/if}
```

> This concept is obsolete, as components can import themselves:
>
> App
>
> ```
> <script>
> 	import Self from './App.svelte'
> 	export let count;
> </script>
>
> {#if count > 0}
> 	<p>counting down... {count}</p>
> 	<Self count={count - 1} />
> {:else}
> 	<p>lift-off!</p>
> {/if}
> ```
>
> ```
> <script lang="ts">
> 	import Self from './App.svelte'
> 	export let count;
> </script>
>
> {#if count > 0}
> 	<p>counting down... {count}</p>
> 	<Self count={count - 1} />
> {:else}
> 	<p>lift-off!</p>
> {/if}
> ```

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/99-legacy/31-legacy-svelte-self.md) [llms.txt](/docs/svelte/legacy-svelte-self/llms.txt)

previous next

[\<svelte:component>](/docs/svelte/legacy-svelte-component) [Imperative component API](/docs/svelte/legacy-component-api)

----
url: https://svelte.dev/docs/svelte/svelte-legacy/llms.txt
----

````
This module provides various functions for use during the migration, since some features can't be replaced one to one with new features. All imports are marked as deprecated and should be migrated away from over time.



```js
// @noErrors
import {
	asClassComponent,
	createBubbler,
	createClassComponent,
	handlers,
	nonpassive,
	once,
	passive,
	preventDefault,
	run,
	self,
	stopImmediatePropagation,
	stopPropagation,
	trusted
} from 'svelte/legacy';
```

## asClassComponent

<blockquote class="tag deprecated note">

Use this only as a temporary solution to migrate your imperative component code to Svelte 5.

</blockquote>

Takes the component function and returns a Svelte 4 compatible component constructor.

<div class="ts-block">

```dts
function asClassComponent<
	Props extends Record<string, any>,
	Exports extends Record<string, any>,
	Events extends Record<string, any>,
	Slots extends Record<string, any>
>(
	component:
		| SvelteComponent<Props, Events, Slots>
		| Component<Props>
): ComponentType<
	SvelteComponent<Props, Events, Slots> & Exports
>;
```

</div>



## createBubbler

<blockquote class="tag deprecated note">

Use this only as a temporary solution to migrate your automatically delegated events in Svelte 5.

</blockquote>

Function to create a `bubble` function that mimic the behavior of `on:click` without handler available in svelte 4.

<div class="ts-block">

```dts
function createBubbler(): (
	type: string
) => (event: Event) => boolean;
```

</div>



## createClassComponent

<blockquote class="tag deprecated note">

Use this only as a temporary solution to migrate your imperative component code to Svelte 5.

</blockquote>

Takes the same options as a Svelte 4 component and the component function and returns a Svelte 4 compatible component.

<div class="ts-block">

```dts
function createClassComponent<
	Props extends Record<string, any>,
	Exports extends Record<string, any>,
	Events extends Record<string, any>,
	Slots extends Record<string, any>
>(
	options: ComponentConstructorOptions<Props> & {
		component:
			| ComponentType<SvelteComponent<Props, Events, Slots>>
			| Component<Props>;
	}
): SvelteComponent<Props, Events, Slots> & Exports;
```

</div>



## handlers

Function to mimic the multiple listeners available in svelte 4

<div class="ts-block">

```dts
function handlers(
	...handlers: EventListener[]
): EventListener;
```

</div>



## nonpassive

Substitute for the `nonpassive` event modifier, implemented as an action

<div class="ts-block">

```dts
function nonpassive(
	node: HTMLElement,
	[event, handler]: [
		event: string,
		handler: () => EventListener
	]
): void;
```

</div>



## once

Substitute for the `once` event modifier

<div class="ts-block">

```dts
function once(
	fn: (event: Event, ...args: Array<unknown>) => void
): (event: Event, ...args: unknown[]) => void;
```

</div>



## passive

Substitute for the `passive` event modifier, implemented as an action

<div class="ts-block">

```dts
function passive(
	node: HTMLElement,
	[event, handler]: [
		event: string,
		handler: () => EventListener
	]
): void;
```

</div>



## preventDefault

Substitute for the `preventDefault` event modifier

<div class="ts-block">

```dts
function preventDefault(
	fn: (event: Event, ...args: Array<unknown>) => void
): (event: Event, ...args: unknown[]) => void;
```

</div>



## run

<blockquote class="tag deprecated note">

Use this only as a temporary solution to migrate your component code to Svelte 5.

</blockquote>

Runs the given function once immediately on the server, and works like `$effect.pre` on the client.

<div class="ts-block">

```dts
function run(fn: () => void | (() => void)): void;
```

</div>



## self

Substitute for the `self` event modifier

<div class="ts-block">

```dts
function self(
	fn: (event: Event, ...args: Array<unknown>) => void
): (event: Event, ...args: unknown[]) => void;
```

</div>



## stopImmediatePropagation

Substitute for the `stopImmediatePropagation` event modifier

<div class="ts-block">

```dts
function stopImmediatePropagation(
	fn: (event: Event, ...args: Array<unknown>) => void
): (event: Event, ...args: unknown[]) => void;
```

</div>



## stopPropagation

Substitute for the `stopPropagation` event modifier

<div class="ts-block">

```dts
function stopPropagation(
	fn: (event: Event, ...args: Array<unknown>) => void
): (event: Event, ...args: unknown[]) => void;
```

</div>



## trusted

Substitute for the `trusted` event modifier

<div class="ts-block">

```dts
function trusted(
	fn: (event: Event, ...args: Array<unknown>) => void
): (event: Event, ...args: unknown[]) => void;
```

</div>



## LegacyComponentType

Support using the component as both a class and function during the transition period

<div class="ts-block">

```dts
type LegacyComponentType = {
	new (o: ComponentConstructorOptions): SvelteComponent;
	(
		...args: Parameters<Component<Record<string, any>>>
	): ReturnType<
		Component<Record<string, any>, Record<string, any>>
	>;
};
```

</div>
````

----
url: https://svelte.dev/docs/svelte/svelte/llms.txt
----

````
```js
// @noErrors
import {
	SvelteComponent,
	SvelteComponentTyped,
	afterUpdate,
	beforeUpdate,
	createContext,
	createEventDispatcher,
	createRawSnippet,
	flushSync,
	fork,
	getAbortSignal,
	getAllContexts,
	getContext,
	hasContext,
	hydratable,
	hydrate,
	mount,
	onDestroy,
	onMount,
	setContext,
	settled,
	tick,
	unmount,
	untrack
} from 'svelte';
```

## SvelteComponent

This was the base class for Svelte components in Svelte 4. Svelte 5+ components
are completely different under the hood. For typing, use `Component` instead.
To instantiate components, use `mount` instead.
See [migration guide](/docs/svelte/v5-migration-guide#Components-are-no-longer-classes) for more info.

<div class="ts-block">

```dts
class SvelteComponent<
	Props extends Record<string, any> = Record<string, any>,
	Events extends Record<string, any> = any,
	Slots extends Record<string, any> = any
> {/*…*/}
```

<div class="ts-block-property">

```dts
static element?: typeof HTMLElement;
```

<div class="ts-block-property-details">

The custom element version of the component. Only present if compiled with the `customElement` compiler option

</div>
</div>

<div class="ts-block-property">

```dts
[prop: string]: any;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
constructor(options: ComponentConstructorOptions<Properties<Props, Slots>>);
```

<div class="ts-block-property-details">

<div class="ts-block-property-bullets">

- <span class="tag deprecated">deprecated</span> This constructor only exists when using the `asClassComponent` compatibility helper, which
is a stop-gap solution. Migrate towards using `mount` instead. See
[migration guide](https://svelte.dev/docs/svelte/v5-migration-guide#Components-are-no-longer-classes) for more info.

</div>

</div>
</div>

<div class="ts-block-property">

```dts
$destroy(): void;
```

<div class="ts-block-property-details">

<div class="ts-block-property-bullets">

- <span class="tag deprecated">deprecated</span> This method only exists when using one of the legacy compatibility helpers, which
is a stop-gap solution. See [migration guide](https://svelte.dev/docs/svelte/v5-migration-guide#Components-are-no-longer-classes)
for more info.

</div>

</div>
</div>

<div class="ts-block-property">

```dts
$on<K extends Extract<keyof Events, string>>(
	type: K,
	callback: (e: Events[K]) => void
): () => void;
```

<div class="ts-block-property-details">

<div class="ts-block-property-bullets">

- <span class="tag deprecated">deprecated</span> This method only exists when using one of the legacy compatibility helpers, which
is a stop-gap solution. See [migration guide](https://svelte.dev/docs/svelte/v5-migration-guide#Components-are-no-longer-classes)
for more info.

</div>

</div>
</div>

<div class="ts-block-property">

```dts
$set(props: Partial<Props>): void;
```

<div class="ts-block-property-details">

<div class="ts-block-property-bullets">

- <span class="tag deprecated">deprecated</span> This method only exists when using one of the legacy compatibility helpers, which
is a stop-gap solution. See [migration guide](https://svelte.dev/docs/svelte/v5-migration-guide#Components-are-no-longer-classes)
for more info.

</div>

</div>
</div></div>



## SvelteComponentTyped

<blockquote class="tag deprecated note">

Use `Component` instead. See [migration guide](/docs/svelte/v5-migration-guide#Components-are-no-longer-classes) for more information.

</blockquote>

<div class="ts-block">

```dts
class SvelteComponentTyped<
	Props extends Record<string, any> = Record<string, any>,
	Events extends Record<string, any> = any,
	Slots extends Record<string, any> = any
> extends SvelteComponent<Props, Events, Slots> {}
```

</div>



## afterUpdate

<blockquote class="tag deprecated note">

Use [`$effect`](/docs/svelte/$effect) instead

</blockquote>

Schedules a callback to run immediately after the component has been updated.

The first time the callback runs will be after the initial `onMount`.

In runes mode use `$effect` instead.

<div class="ts-block">

```dts
function afterUpdate(fn: () => void): void;
```

</div>



## beforeUpdate

<blockquote class="tag deprecated note">

Use [`$effect.pre`](/docs/svelte/$effect#$effect.pre) instead

</blockquote>

Schedules a callback to run immediately before the component is updated after any state change.

The first time the callback runs will be before the initial `onMount`.

In runes mode use `$effect.pre` instead.

<div class="ts-block">

```dts
function beforeUpdate(fn: () => void): void;
```

</div>



## createContext

<blockquote class="since note">

Available since 5.40.0

</blockquote>

Returns a `[get, set, has]` triplet of functions for working with context in a type-safe way.

`get` will throw an error if `set` has not yet been called in the current component or any of
its ancestors.

<div class="ts-block">

```dts
function createContext<T>(): [
	() => T,
	(context: T) => T,
	() => boolean
];
```

</div>



## createEventDispatcher

<blockquote class="tag deprecated note">

Use callback props and/or the `$host()` rune instead — see [migration guide](/docs/svelte/v5-migration-guide#Event-changes-Component-events)

</blockquote>

Creates an event dispatcher that can be used to dispatch [component events](/docs/svelte/legacy-on#Component-events).
Event dispatchers are functions that can take two arguments: `name` and `detail`.

Component events created with `createEventDispatcher` create a
[CustomEvent](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent).
These events do not [bubble](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Events#Event_bubbling_and_capture).
The `detail` argument corresponds to the [CustomEvent.detail](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/detail)
property and can contain any type of data.

The event dispatcher can be typed to narrow the allowed event names and the type of the `detail` argument:
```ts
const dispatch = createEventDispatcher<{
 loaded: null; // does not take a detail argument
 change: string; // takes a detail argument of type string, which is required
 optional: number | null; // takes an optional detail argument of type number
}>();
```

<div class="ts-block">

```dts
function createEventDispatcher<
	EventMap extends Record<string, any> = any
>(): EventDispatcher<EventMap>;
```

</div>



## createRawSnippet

Create a snippet programmatically

<div class="ts-block">

```dts
function createRawSnippet<Params extends unknown[]>(
	fn: (...params: Getters<Params>) => {
		render: () => string;
		setup?: (element: Element) => void | (() => void);
	}
): Snippet<Params>;
```

</div>



## flushSync

Synchronously flush any pending updates.
Returns void if no callback is provided, otherwise returns the result of calling the callback.

<div class="ts-block">

```dts
function flushSync<T = void>(fn?: (() => T) | undefined): T;
```

</div>



## fork

<blockquote class="since note">

Available since 5.42

</blockquote>

Creates a 'fork', in which state changes are evaluated but not applied to the DOM.
This is useful for speculatively loading data (for example) when you suspect that
the user is about to take some action.

Frameworks like SvelteKit can use this to preload data when the user touches or
hovers over a link, making any subsequent navigation feel instantaneous.

The `fn` parameter is a synchronous function that modifies some state. The
state changes will be reverted after the fork is initialised, then reapplied
if and when the fork is eventually committed.

When it becomes clear that a fork will _not_ be committed (e.g. because the
user navigated elsewhere), it must be discarded to avoid leaking memory.

<div class="ts-block">

```dts
function fork(fn: () => void): Fork;
```

</div>



## getAbortSignal

Returns an [`AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal) that aborts when the current [derived](/docs/svelte/$derived) or [effect](/docs/svelte/$effect) re-runs or is destroyed.

Must be called while a derived or effect is running.

```svelte
<script>
	import { getAbortSignal } from 'svelte';

	let { id } = $props();

	async function getData(id) {
		const response = await fetch(`/items/${id}`, {
			signal: getAbortSignal()
		});

		return await response.json();
	}

	const data = $derived(await getData(id));
</script>
```

<div class="ts-block">

```dts
function getAbortSignal(): AbortSignal;
```

</div>



## getAllContexts

Retrieves the whole context map that belongs to the current component, including entries
inherited from its ancestors. Must be called during component initialisation. Useful, for
example, if you programmatically create a component and want to pass the existing context to it.

<div class="ts-block">

```dts
function getAllContexts<
	T extends Map<any, any> = Map<any, any>
>(): T;
```

</div>



## getContext

Retrieves the context set with the specified `key` in the current component or any of its
ancestors. If multiple components set the same key, the value from the closest one is returned.
A `setContext` call in the current component is only visible to `getContext` calls that run after it.
Must be called during component initialisation.

[`createContext`](/docs/svelte/svelte#createContext) is a type-safe alternative.

<div class="ts-block">

```dts
function getContext<T>(key: any): T;
```

</div>



## hasContext

Checks whether a given `key` has been set in the context of the current component or any of
its ancestors. Must be called during component initialisation.

<div class="ts-block">

```dts
function hasContext(key: any): boolean;
```

</div>



## hydratable

<div class="ts-block">

```dts
function hydratable<T>(key: string, fn: () => T): T;
```

</div>



## hydrate

Hydrates a component on the given target and returns the exports and potentially the props (if compiled with `accessors: true`) of the component

<div class="ts-block">

```dts
function hydrate<
	Props extends Record<string, any>,
	Exports extends Record<string, any>
>(
	component:
		| ComponentType<SvelteComponent<Props>>
		| Component<Props, Exports, any>,
	options: {} extends Props
		? {
				target: Document | Element | ShadowRoot;
				props?: Props;
				events?: Record<string, (e: any) => any>;
				context?: Map<any, any>;
				intro?: boolean;
				recover?: boolean;
				transformError?: (error: unknown) => unknown;
			}
		: {
				target: Document | Element | ShadowRoot;
				props: Props;
				events?: Record<string, (e: any) => any>;
				context?: Map<any, any>;
				intro?: boolean;
				recover?: boolean;
				transformError?: (error: unknown) => unknown;
			}
): Exports;
```

</div>



## mount

Mounts a component to the given target and returns the exports and potentially the props (if compiled with `accessors: true`) of the component.
Transitions will play during the initial render unless the `intro` option is set to `false`.

<div class="ts-block">

```dts
function mount<
	Props extends Record<string, any>,
	Exports extends Record<string, any>
>(
	component:
		| ComponentType<SvelteComponent<Props>>
		| Component<Props, Exports, any>,
	options: MountOptions<Props>
): Exports;
```

</div>



## onDestroy

Schedules a callback to run immediately before the component is unmounted.

Out of `onMount`, `beforeUpdate`, `afterUpdate` and `onDestroy`, this is the
only one that runs inside a server-side component.

<div class="ts-block">

```dts
function onDestroy(fn: () => any): void;
```

</div>



## onMount

`onMount`, like [`$effect`](/docs/svelte/$effect), schedules a function to run as soon as the component has been mounted to the DOM.
Unlike `$effect`, the provided function only runs once.

It must be called during the component's initialisation (but doesn't need to live _inside_ the component;
it can be called from an external module). If a function is returned _synchronously_ from `onMount`,
it will be called when the component is unmounted.

`onMount` functions do not run during [server-side rendering](/docs/svelte/svelte-server#render).

<div class="ts-block">

```dts
function onMount<T>(
	fn: () =>
		| NotFunction<T>
		| Promise<NotFunction<T>>
		| (() => any)
): void;
```

</div>



## setContext

Associates an arbitrary `context` object with the current component and the specified `key`
and returns that object. The context is then available to the component itself and all of its
descendants (including slotted content) with `getContext`.

Like lifecycle functions, this must be called during component initialisation.

[`createContext`](/docs/svelte/svelte#createContext) is a type-safe alternative.

<div class="ts-block">

```dts
function setContext<T>(key: any, context: T): T;
```

</div>



## settled

<blockquote class="since note">

Available since 5.36

</blockquote>

Returns a promise that resolves once any state changes, and asynchronous work resulting from them,
have resolved and the DOM has been updated

<div class="ts-block">

```dts
function settled(): Promise<void>;
```

</div>



## tick

Returns a promise that resolves once any pending state changes have been applied.

<div class="ts-block">

```dts
function tick(): Promise<void>;
```

</div>



## unmount

Unmounts a component that was previously mounted using `mount` or `hydrate`.

Since 5.13.0, if `options.outro` is `true`, [transitions](/docs/svelte/transition) will play before the component is removed from the DOM.

Returns a `Promise` that resolves after transitions have completed if `options.outro` is true, or immediately otherwise (prior to 5.13.0, returns `void`).

```js
// @errors: 7031
import { mount, unmount } from 'svelte';
import App from './App.svelte';

const app = mount(App, { target: document.body });

// later...
unmount(app, { outro: true });
```

<div class="ts-block">

```dts
function unmount(
	component: Record<string, any>,
	options?:
		| {
				outro?: boolean;
		  }
		| undefined
): Promise<void>;
```

</div>



## untrack

When used inside a [`$derived`](/docs/svelte/$derived) or [`$effect`](/docs/svelte/$effect),
any state read inside `fn` will not be treated as a dependency.

```ts
$effect(() => {
	// this will run when `data` changes, but not when `time` changes
	save(data, {
		timestamp: untrack(() => time)
	});
});
```

<div class="ts-block">

```dts
function untrack<T>(fn: () => T): T;
```

</div>



## Component

Can be used to create strongly typed Svelte components.

#### Example:

You have component library on npm called `component-library`, from which
you export a component called `MyComponent`. For Svelte+TypeScript users,
you want to provide typings. Therefore you create a `index.d.ts`:
```ts
import type { Component } from 'svelte';
export declare const MyComponent: Component<{ foo: string }> {}
```
Typing this makes it possible for IDEs like VS Code with the Svelte extension
to provide intellisense and to use the component like this in a Svelte file
with TypeScript:
```svelte
<script lang="ts">
	import { MyComponent } from "component-library";
</script>
<MyComponent foo={'bar'} />
```

<div class="ts-block">

```dts
interface Component<
	Props extends Record<string, any> = {},
	Exports extends Record<string, any> = {},
	Bindings extends keyof Props | '' = string
> {/*…*/}
```

<div class="ts-block-property">

```dts
(
	this: void,
	internals: ComponentInternals,
	props: Props
): {
	/**
	 * @deprecated This method only exists when using one of the legacy compatibility helpers, which
	 * is a stop-gap solution. See [migration guide](https://svelte.dev/docs/svelte/v5-migration-guide#Components-are-no-longer-classes)
	 * for more info.
	 */
	$on?(type: string, callback: (e: any) => void): () => void;
	/**
	 * @deprecated This method only exists when using one of the legacy compatibility helpers, which
	 * is a stop-gap solution. See [migration guide](https://svelte.dev/docs/svelte/v5-migration-guide#Components-are-no-longer-classes)
	 * for more info.
	 */
	$set?(props: Partial<Props>): void;
} & Exports;
```

<div class="ts-block-property-details">

<div class="ts-block-property-bullets">

- `internal` An internal object used by Svelte. Do not use or modify.
- `props` The props passed to the component.

</div>

</div>
</div>

<div class="ts-block-property">

```dts
element?: typeof HTMLElement;
```

<div class="ts-block-property-details">

The custom element version of the component. Only present if compiled with the `customElement` compiler option

</div>
</div></div>

## ComponentConstructorOptions

<blockquote class="tag deprecated note">

In Svelte 4, components are classes. In Svelte 5, they are functions.
Use `mount` instead to instantiate components.
See [migration guide](/docs/svelte/v5-migration-guide#Components-are-no-longer-classes)
for more info.

</blockquote>

<div class="ts-block">

```dts
interface ComponentConstructorOptions<
	Props extends Record<string, any> = Record<string, any>
> {/*…*/}
```

<div class="ts-block-property">

```dts
target: Element | Document | ShadowRoot;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
anchor?: Element;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
props?: Props;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
context?: Map<any, any>;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
hydrate?: boolean;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
intro?: boolean;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
recover?: boolean;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
sync?: boolean;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
idPrefix?: string;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
$$inline?: boolean;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
transformError?: (error: unknown) => unknown;
```

<div class="ts-block-property-details"></div>
</div></div>

## ComponentEvents

<blockquote class="tag deprecated note">

The new `Component` type does not have a dedicated Events type. Use `ComponentProps` instead.

</blockquote>

<div class="ts-block">

```dts
type ComponentEvents<Comp extends SvelteComponent> =
	Comp extends SvelteComponent<any, infer Events>
		? Events
		: never;
```

</div>

## ComponentInternals

Internal implementation details that vary between environments

<div class="ts-block">

```dts
type ComponentInternals = Branded<{}, 'ComponentInternals'>;
```

</div>

## ComponentProps

Convenience type to get the props the given component expects.

Example: Ensure a variable contains the props expected by `MyComponent`:

```ts
import type { ComponentProps } from 'svelte';
import MyComponent from './MyComponent.svelte';

// Errors if these aren't the correct props expected by MyComponent.
const props: ComponentProps<typeof MyComponent> = { foo: 'bar' };
```

> [!NOTE] In Svelte 4, you would do `ComponentProps<MyComponent>` because `MyComponent` was a class.

Example: A generic function that accepts some component and infers the type of its props:

```ts
import type { Component, ComponentProps } from 'svelte';
import MyComponent from './MyComponent.svelte';

function withProps<TComponent extends Component<any>>(
	component: TComponent,
	props: ComponentProps<TComponent>
) {};

// Errors if the second argument is not the correct props expected by the component in the first argument.
withProps(MyComponent, { foo: 'bar' });
```

<div class="ts-block">

```dts
type ComponentProps<
	Comp extends SvelteComponent | Component<any, any>
> =
	Comp extends SvelteComponent<infer Props>
		? Props
		: Comp extends Component<infer Props, any>
			? Props
			: never;
```

</div>

## ComponentType

<blockquote class="tag deprecated note">

This type is obsolete when working with the new `Component` type.

</blockquote>

<div class="ts-block">

```dts
type ComponentType<
	Comp extends SvelteComponent = SvelteComponent
> = (new (
	options: ComponentConstructorOptions<
		Comp extends SvelteComponent<infer Props>
			? Props
			: Record<string, any>
	>
) => Comp) & {
	/** The custom element version of the component. Only present if compiled with the `customElement` compiler option */
	element?: typeof HTMLElement;
};
```

</div>

## EventDispatcher

<div class="ts-block">

```dts
interface EventDispatcher<
	EventMap extends Record<string, any>
> {/*…*/}
```

<div class="ts-block-property">

```dts
<Type extends keyof EventMap>(
	...args: null extends EventMap[Type]
		? [type: Type, parameter?: EventMap[Type] | null | undefined, options?: DispatchOptions]
		: undefined extends EventMap[Type]
			? [type: Type, parameter?: EventMap[Type] | null | undefined, options?: DispatchOptions]
			: [type: Type, parameter: EventMap[Type], options?: DispatchOptions]
): boolean;
```

<div class="ts-block-property-details"></div>
</div></div>

## Fork

<blockquote class="since note">

Available since 5.42

</blockquote>

Represents work that is happening off-screen, such as data being preloaded
in anticipation of the user navigating

<div class="ts-block">

```dts
interface Fork {/*…*/}
```

<div class="ts-block-property">

```dts
commit(): Promise<void>;
```

<div class="ts-block-property-details">

Commit the fork. The promise will resolve once the state change has been applied

</div>
</div>

<div class="ts-block-property">

```dts
discard(): void;
```

<div class="ts-block-property-details">

Discard the fork

</div>
</div></div>

## MountOptions

Defines the options accepted by the `mount()` function.

<div class="ts-block">

```dts
type MountOptions<
	Props extends Record<string, any> = Record<string, any>
> = {
	/**
	 * Target element where the component will be mounted.
	 */
	target: Document | Element | ShadowRoot;
	/**
	 * Optional node inside `target`. When specified, it is used to render the component immediately before it.
	 */
	anchor?: Node;
	/**
	 * Allows the specification of events.
	 * @deprecated Use callback props instead.
	 */
	events?: Record<string, (e: any) => any>;
	/**
	 * Can be accessed via `getContext()` at the component level.
	 */
	context?: Map<any, any>;
	/**
	 * Whether or not to play transitions on initial render.
	 * @default true
	 */
	intro?: boolean;
	/**
	 * A function that transforms errors caught by error boundaries before they are passed to the `failed` snippet.
	 * Defaults to the identity function.
	 */
	transformError?: (
		error: unknown
	) => unknown | Promise<unknown>;
} & ({} extends Props
	? {
			/**
			 * Component properties.
			 */
			props?: Props;
		}
	: {
			/**
			 * Component properties.
			 */
			props: Props;
		});
```

</div>

## Snippet

The type of a `#snippet` block. You can use it to (for example) express that your component expects a snippet of a certain type:
```ts
let { banner }: { banner: Snippet<[{ text: string }]> } = $props();
```
You can only call a snippet through the `{@render ...}` tag.

See the [snippet documentation](/docs/svelte/snippet) for more info.

<div class="ts-block">

```dts
interface Snippet<Parameters extends unknown[] = []> {/*…*/}
```

<div class="ts-block-property">

```dts
(
	this: void,
	// this conditional allows tuples but not arrays. Arrays would indicate a
	// rest parameter type, which is not supported. If rest parameters are added
	// in the future, the condition can be removed.
	...args: number extends Parameters['length'] ? never : Parameters
): {
	'{@render ...} must be called with a Snippet': "import type { Snippet } from 'svelte'";
} & typeof SnippetReturn;
```

<div class="ts-block-property-details"></div>
</div></div>
````

----
url: https://svelte.dev/docs/svelte
----

[Skip to main content](#main)

Svelte is a framework for building user interfaces on the web. It uses a compiler to turn declarative components written in HTML, CSS and JavaScript...

App

```
<script>
	function greet() {
		alert('Welcome to Svelte!');
	}
</script>

<button onclick={greet}>click me</button>

<style>
	button {
		font-size: 2em;
	}
</style>
```

```
<script lang="ts">
	function greet() {
		alert('Welcome to Svelte!');
	}
</script>

<button onclick={greet}>click me</button>

<style>
	button {
		font-size: 2em;
	}
</style>
```

...into lean, tightly optimized JavaScript.

You can use it to build anything on the web, from standalone components to ambitious full stack apps (using Svelte’s companion application framework, [SvelteKit](../kit)) and everything in between.

These pages serve as reference documentation. If you’re new to Svelte, we recommend starting with the [interactive tutorial](/tutorial) and coming back here when you have questions.

You can also try Svelte online in the [playground](/playground) or, if you need a more fully-featured environment, on [StackBlitz](https://sveltekit.new).

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/01-introduction/01-overview.md) [llms.txt](/docs/svelte/overview/llms.txt)

previous next

[Getting started](/docs/svelte/getting-started)

----
url: https://svelte.dev/docs/svelte/legacy-component-api/llms.txt
----

````
In Svelte 3 and 4, the API for interacting with a component is different than in Svelte 5. Note that this page does _not_ apply to legacy mode components in a Svelte 5 application.

## Creating a component

```ts
// @noErrors
const component = new Component(options);
```

A client-side component — that is, a component compiled with `generate: 'dom'` (or the `generate` option left unspecified) is a JavaScript class.

```ts
// @noErrors
import App from './App.svelte';

const app = new App({
	target: document.body,
	props: {
		// assuming App.svelte contains something like
		// `export let answer`:
		answer: 42
	}
});
```

The following initialisation options can be provided:

| option    | default     | description                                                                                          |
| --------- | ----------- | ---------------------------------------------------------------------------------------------------- |
| `target`  | **none**    | An `HTMLElement` or `ShadowRoot` to render to. This option is required                               |
| `anchor`  | `null`      | A child of `target` to render the component immediately before                                       |
| `props`   | `{}`        | An object of properties to supply to the component                                                   |
| `context` | `new Map()` | A `Map` of root-level context key-value pairs to supply to the component                             |
| `hydrate` | `false`     | See below                                                                                            |
| `intro`   | `false`     | If `true`, will play transitions on initial render, rather than waiting for subsequent state changes |

Existing children of `target` are left where they are.

The `hydrate` option instructs Svelte to upgrade existing DOM (usually from server-side rendering) rather than creating new elements. It will only work if the component was compiled with the [`hydratable: true` option](/docs/svelte-compiler#compile). Hydration of `<head>` elements only works properly if the server-side rendering code was also compiled with `hydratable: true`, which adds a marker to each element in the `<head>` so that the component knows which elements it's responsible for removing during hydration.

Whereas children of `target` are normally left alone, `hydrate: true` will cause any children to be removed. For that reason, the `anchor` option cannot be used alongside `hydrate: true`.

The existing DOM doesn't need to match the component — Svelte will 'repair' the DOM as it goes.

```ts
/// file: index.js
// @noErrors
import App from './App.svelte';

const app = new App({
	target: document.querySelector('#server-rendered-html'),
	hydrate: true
});
```

> [!NOTE]
> In Svelte 5+, use [`mount`](svelte#mount) instead

## `$set`

```ts
// @noErrors
component.$set(props);
```

Programmatically sets props on an instance. `component.$set({ x: 1 })` is equivalent to `x = 1` inside the component's `<script>` block.

Calling this method schedules an update for the next microtask — the DOM is _not_ updated synchronously.

```ts
// @noErrors
component.$set({ answer: 42 });
```

> [!NOTE]
> In Svelte 5+, use `$state` instead to create a component props and update that
>
> ```js
> // @noErrors
> let props = $state({ answer: 42 });
> const component = mount(Component, { props });
> // ...
> props.answer = 24;
> ```

## `$on`

```ts
// @noErrors
component.$on(ev, callback);
```

Causes the `callback` function to be called whenever the component dispatches an `event`.

A function is returned that will remove the event listener when called.

```ts
// @noErrors
const off = component.$on('selected', (event) => {
	console.log(event.detail.selection);
});

off();
```

> [!NOTE]
> In Svelte 5+, pass callback props instead

## `$destroy`

```js
// @noErrors
component.$destroy();
```

Removes a component from the DOM and triggers any `onDestroy` handlers.

> [!NOTE]
> In Svelte 5+, use [`unmount`](svelte#unmount) instead

## Component props

```js
// @noErrors
component.prop;
```

```js
// @noErrors
component.prop = value;
```

If a component is compiled with `accessors: true`, each instance will have getters and setters corresponding to each of the component's props. Setting a value will cause a _synchronous_ update, rather than the default async update caused by `component.$set(...)`.

By default, `accessors` is `false`, unless you're compiling as a custom element.

```js
// @noErrors
console.log(component.count);
component.count += 1;
```

> [!NOTE]
> In Svelte 5+, this concept is obsolete. If you want to make properties accessible from the outside, `export` them

## Server-side component API

```js
// @noErrors
const result = Component.render(...)
```

Unlike client-side components, server-side components don't have a lifespan after you render them — their whole job is to create some HTML and CSS. For that reason, the API is somewhat different.

A server-side component exposes a `render` method that can be called with optional props. It returns an object with `head`, `html`, and `css` properties, where `head` contains the contents of any `<svelte:head>` elements encountered.

You can import a Svelte component directly into Node using `svelte/register`.

```js
// @noErrors
require('svelte/register');

const App = require('./App.svelte').default;

const { head, html, css } = App.render({
	answer: 42
});
```

The `.render()` method accepts the following parameters:

| parameter | default | description                                        |
| --------- | ------- | -------------------------------------------------- |
| `props`   | `{}`    | An object of properties to supply to the component |
| `options` | `{}`    | An object of options                               |

The `options` object takes in the following options:

| option    | default     | description                                                              |
| --------- | ----------- | ------------------------------------------------------------------------ |
| `context` | `new Map()` | A `Map` of root-level context key-value pairs to supply to the component |

```js
// @noErrors
const { head, html, css } = App.render(
	// props
	{ answer: 42 },
	// options
	{
		context: new Map([['context-key', 'context-value']])
	}
);
```

> [!NOTE]
> In Svelte 5+, use [`render`](svelte-server#render) instead
````

----
url: https://svelte.dev/docs/svelte/$derived
----

[Skip to main content](#main)

Derived state is declared with the `$derived` rune:

```
<script>
	let count = $state(0);
	let doubled = $derived(count * 2);
</script>

<button onclick={() => count++}>
	{doubled}
</button>

<p>{count} doubled is {doubled}</p>
```

The expression inside `$derived(...)` should be free of side-effects. Svelte will disallow state changes (e.g. `count++`) inside derived expressions.

As with `$state`, you can mark class fields as `$derived`.

> 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[](#$derived.by)

Sometimes you need to create complex derivations that don’t fit inside a short expression. In these cases, you can use `$derived.by` which accepts a function as its argument.

```
<script>
	let numbers = $state([1, 2, 3]);
	let total = $derived.by(() => {
		let total = 0;
		for (const n of numbers) {
			total += n;
		}
		return total;
	});
</script>

<button onclick={() => numbers.push(numbers.length + 1)}>
	{numbers.join(' + ')} = {total}
</button>
```

In essence, `$derived(expression)` is equivalent to `$derived.by(() => expression)`.

## Understanding dependencies[](#Understanding-dependencies)

Anything read synchronously inside the `$derived` expression (or `$derived.by` function body) is considered a *dependency* of the derived state. When the state changes, the derived will be marked as *dirty* and recalculated when it is next read.

In addition, if an expression contains an [`await`](await-expressions), Svelte transforms it such that any state *after* the `await` is also tracked — in other words, in a case like this...

```
let totallet total: number = $derivedfunction $derived<number>(expression: number): number
namespace $derived

Declares derived state, i.e. one that depends on other state variables.
The expression inside $derived(...) should be free of side-effects.




Example:



let double = $derived(count * 2);

{@link https://svelte.dev/docs/svelte/$derived Documentation}


expression 

The derived state expression


(await alet a: Promise<number> + blet b: number);
```

...both `a` and `b` are tracked, even though `b` is only read once `a` has resolved, after the initial execution. (This does not apply to `await` in functions that are called by the expression, only the expression itself.)

To exempt a piece of state from being treated as a dependency, use [`untrack`](svelte#untrack).

## Overriding derived values[](#Overriding-derived-values)

Derived expressions are recalculated when their dependencies change, but you can temporarily override their values by reassigning them (unless they are declared with `const`). This can be useful for things like *optimistic UI*, where a value is derived from the ‘source of truth’ (such as data from your server) but you’d like to show immediate feedback to the user:

```
<script>
	let { post, like } = $props();

	let likes = $derived(post.likes);

	async function onclick() {
		// increment the `likes` count immediately...
		likes += 1;

		// and tell the server, which will eventually update `post`
		try {
			await like();
		} catch {
			// failed! roll back the change
			likes -= 1;
		}
	}
</script>

<button {onclick}>🧡 {likes}</button>
```

> Prior to Svelte 5.25, deriveds were read-only.

## Deriveds and reactivity[](#Deriveds-and-reactivity)

Unlike `$state`, which converts objects and arrays to [deeply reactive proxies]($state#Deep-state), `$derived` values are left as-is. For example, [in a case like this](/playground/untitled#H4sIAAAAAAAAE4VU22rjMBD9lUHd3aaQi9PdstS1A3t5XvpQ2Ic4D7I1iUUV2UjjNMX431eS7TRdSosxgjMzZ45mjt0yzffIYibvy0ojFJWqDKCQVBk2ZVup0LJ43TJ6rn2aBxw-FP2o67k9oCKP5dziW3hRaUJNjoYltjCyplWmM1JIIAn3FlL4ZIkTTtYez6jtj4w8WwyXv9GiIXiQxLVs9pfTMR7EuoSLIuLFbX7Z4930bZo_nBrD1bs834tlfvsBz9_SyX6PZXu9XaL4gOWn4sXjeyzftv4ZWfyxubpzxzg6LfD4MrooxELEosKCUPigQCMPKCZh0OtQE1iSxcsmdHuBvCiHZXALLXiN08EL3RRkaJ_kDVGle0HcSD5TPEeVtj67O4Nrg9aiSNtBY5oODJkrL5QsHtN2cgXp6nSJMWzpWWGasdlsGEMbzi5jPr5KFr0Ep7pdeM2-TCelCddIhDxAobi1jqF3cMaC1RKp64bAW9iFAmXGIHfd4wNXDabtOLN53w8W53VvJoZLh7xk4Rr3CoL-UNoLhWHrT1JQGcM17u96oES5K-kc2XOzkzqGCKL5De79OUTyyrg1zgwXsrEx3ESfx4Bz0M5UjVMHB24mw9SuXtXFoN13fYKOM1tyUT3FbvbWmSWCZX2Er-41u5xPoml45svRahl9Wb9aasbINJixDZwcPTbyTLZSUsAvrg_cPuCR7s782_WU8343Y72Qtlb8OYatwuOQvuN13M_hJKNfxann1v1U_B1KZ_D_mzhzhz24fw85CSz2irtN9w9HshBK7AQAAA==)...

```
let itemslet items: any[] = $statefunction $state<never[]>(initial: never[]): never[] (+1 overload)
namespace $state

Declares reactive state.




Example:



let count = $state(0);

{@link https://svelte.dev/docs/svelte/$state Documentation}


initial 

The initial value


([ /*...*/ ]);

let indexlet index: number = $statefunction $state<0>(initial: 0): 0 (+1 overload)
namespace $state

Declares reactive state.




Example:



let count = $state(0);

{@link https://svelte.dev/docs/svelte/$state Documentation}


initial 

The initial value


(0);
let selectedlet selected: any = $derivedfunction $derived<any>(expression: any): any
namespace $derived

Declares derived state, i.e. one that depends on other state variables.
The expression inside $derived(...) should be free of side-effects.




Example:



let double = $derived(count * 2);

{@link https://svelte.dev/docs/svelte/$derived Documentation}


expression 

The derived state expression


(itemslet items: any[][indexlet index: number]);
```

...you can change (or `bind:` to) properties of `selected` and it will affect the underlying `items` array. If `items` was *not* deeply reactive, mutating `selected` would have no effect.

## Destructuring[](#Destructuring)

If you use destructuring with a `$derived` declaration, the resulting variables will all be reactive — this...

```
let { alet a: number, blet b: number, clet c: number } = $derivedfunction $derived<{
    a: number;
    b: number;
    c: number;
}>(expression: {
    a: number;
    b: number;
    c: number;
}): {
    a: number;
    b: number;
    c: number;
}
namespace $derived

Declares derived state, i.e. one that depends on other state variables.
The expression inside $derived(...) should be free of side-effects.




Example:



let double = $derived(count * 2);

{@link https://svelte.dev/docs/svelte/$derived Documentation}


expression 

The derived state expression


(stufffunction stuff(): {
    a: number;
    b: number;
    c: number;
}());
```

...is roughly equivalent to this:

```
let _stufflet _stuff: {
    a: number;
    b: number;
    c: number;
} = $derivedfunction $derived<{
    a: number;
    b: number;
    c: number;
}>(expression: {
    a: number;
    b: number;
    c: number;
}): {
    a: number;
    b: number;
    c: number;
}
namespace $derived

Declares derived state, i.e. one that depends on other state variables.
The expression inside $derived(...) should be free of side-effects.




Example:



let double = $derived(count * 2);

{@link https://svelte.dev/docs/svelte/$derived Documentation}


expression 

The derived state expression


(stufffunction stuff(): {
    a: number;
    b: number;
    c: number;
}());
let alet a: number = $derivedfunction $derived<number>(expression: number): number
namespace $derived

Declares derived state, i.e. one that depends on other state variables.
The expression inside $derived(...) should be free of side-effects.




Example:



let double = $derived(count * 2);

{@link https://svelte.dev/docs/svelte/$derived Documentation}


expression 

The derived state expression


(_stufflet _stuff: {
    a: number;
    b: number;
    c: number;
}.a(property) a: number);
let blet b: number = $derivedfunction $derived<number>(expression: number): number
namespace $derived

Declares derived state, i.e. one that depends on other state variables.
The expression inside $derived(...) should be free of side-effects.




Example:



let double = $derived(count * 2);

{@link https://svelte.dev/docs/svelte/$derived Documentation}


expression 

The derived state expression


(_stufflet _stuff: {
    a: number;
    b: number;
    c: number;
}.b(property) b: number);
let clet c: number = $derivedfunction $derived<number>(expression: number): number
namespace $derived

Declares derived state, i.e. one that depends on other state variables.
The expression inside $derived(...) should be free of side-effects.




Example:



let double = $derived(count * 2);

{@link https://svelte.dev/docs/svelte/$derived Documentation}


expression 

The derived state expression


(_stufflet _stuff: {
    a: number;
    b: number;
    c: number;
}.c(property) c: number);
```

## Update propagation[](#Update-propagation)

Svelte uses something called *push-pull reactivity* — when state is updated, everything that depends on the state (whether directly or indirectly) is immediately notified of the change (the ‘push’), but derived values are not re-evaluated until they are actually read (the ‘pull’).

If the new value of a derived is referentially identical to its previous value, downstream updates will be skipped. In other words, Svelte will only update the text inside the button when `large` changes, not when `count` changes, even though `large` depends on `count`:

```
<script>
	let count = $state(0);
	let large = $derived(count > 10);
</script>

<button onclick={() => count++}>
	{large}
</button>
```

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/02-runes/03-$derived.md) [llms.txt](/docs/svelte/$derived/llms.txt)

previous next

[$state](/docs/svelte/$state) [$effect](/docs/svelte/$effect)

----
url: https://svelte.dev/docs/svelte/svelte-reactivity-window
----

[Skip to main content](#main)

This module exports reactive versions of various `window` values, each of which has a reactive `current` property that you can reference in reactive contexts (templates, [deriveds]($derived) and [effects]($effect)) without using [`<svelte:window>`](svelte-window) bindings or manually creating your own event listeners.

```
<script>
	import { innerWidth, innerHeight } from 'svelte/reactivity/window';
</script>

<p>{innerWidth.current}x{innerHeight.current}</p>
```

```
import {
	devicePixelRatio(alias) const devicePixelRatio: {
    readonly current: number | undefined;
}
import devicePixelRatio

devicePixelRatio.current is a reactive view of window.devicePixelRatio. On the server it is undefined.
Note that behaviour differs between browsers — on Chrome it will respond to the current zoom level,
on Firefox and Safari it won't.




5.11.0


reference,
	innerHeight(alias) const innerHeight: ReactiveValue<number | undefined>
import innerHeight

innerHeight.current is a reactive view of window.innerHeight. On the server it is undefined.




5.11.0


reference,
	innerWidth(alias) const innerWidth: ReactiveValue<number | undefined>
import innerWidth

innerWidth.current is a reactive view of window.innerWidth. On the server it is undefined.




5.11.0


reference,
	online(alias) const online: ReactiveValue<boolean | undefined>
import online

online.current is a reactive view of navigator.onLine. On the server it is undefined.




5.11.0


reference,
	outerHeight(alias) const outerHeight: ReactiveValue<number | undefined>
import outerHeight

outerHeight.current is a reactive view of window.outerHeight. On the server it is undefined.




5.11.0


reference,
	outerWidth(alias) const outerWidth: ReactiveValue<number | undefined>
import outerWidth

outerWidth.current is a reactive view of window.outerWidth. On the server it is undefined.




5.11.0


reference,
	screenLeft(alias) const screenLeft: ReactiveValue<number | undefined>
import screenLeft

screenLeft.current is a reactive view of window.screenLeft. It is updated inside a requestAnimationFrame callback. On the server it is undefined.




5.11.0


reference,
	screenTop(alias) const screenTop: ReactiveValue<number | undefined>
import screenTop

screenTop.current is a reactive view of window.screenTop. It is updated inside a requestAnimationFrame callback. On the server it is undefined.




5.11.0


reference,
	scrollX(alias) const scrollX: ReactiveValue<number | undefined>
import scrollX

scrollX.current is a reactive view of window.scrollX. On the server it is undefined.




5.11.0


reference,
	scrollY(alias) const scrollY: ReactiveValue<number | undefined>
import scrollY

scrollY.current is a reactive view of window.scrollY. On the server it is undefined.




5.11.0


reference
} from 'svelte/reactivity/window';
```

## devicePixelRatio[](#devicePixelRatio)

> Available since 5.11.0

`devicePixelRatio.current` is a reactive view of `window.devicePixelRatio`. On the server it is `undefined`. Note that behaviour differs between browsers — on Chrome it will respond to the current zoom level, on Firefox and Safari it won’t.

```
const devicePixelRatio: {
	get current(): number | undefined;
};
```

## innerHeight[](#innerHeight)

> Available since 5.11.0

`innerHeight.current` is a reactive view of `window.innerHeight`. On the server it is `undefined`.

```
const innerHeight: ReactiveValue<number | undefined>;
```

## innerWidth[](#innerWidth)

> Available since 5.11.0

`innerWidth.current` is a reactive view of `window.innerWidth`. On the server it is `undefined`.

```
const innerWidth: ReactiveValue<number | undefined>;
```

## online[](#online)

> Available since 5.11.0

`online.current` is a reactive view of `navigator.onLine`. On the server it is `undefined`.

```
const online: ReactiveValue<boolean | undefined>;
```

## outerHeight[](#outerHeight)

> Available since 5.11.0

`outerHeight.current` is a reactive view of `window.outerHeight`. On the server it is `undefined`.

```
const outerHeight: ReactiveValue<number | undefined>;
```

## outerWidth[](#outerWidth)

> Available since 5.11.0

`outerWidth.current` is a reactive view of `window.outerWidth`. On the server it is `undefined`.

```
const outerWidth: ReactiveValue<number | undefined>;
```

## screenLeft[](#screenLeft)

> Available since 5.11.0

`screenLeft.current` is a reactive view of `window.screenLeft`. It is updated inside a `requestAnimationFrame` callback. On the server it is `undefined`.

```
const screenLeft: ReactiveValue<number | undefined>;
```

## screenTop[](#screenTop)

> Available since 5.11.0

`screenTop.current` is a reactive view of `window.screenTop`. It is updated inside a `requestAnimationFrame` callback. On the server it is `undefined`.

```
const screenTop: ReactiveValue<number | undefined>;
```

## scrollX[](#scrollX)

> Available since 5.11.0

`scrollX.current` is a reactive view of `window.scrollX`. On the server it is `undefined`.

```
const scrollX: ReactiveValue<number | undefined>;
```

## scrollY[](#scrollY)

> Available since 5.11.0

`scrollY.current` is a reactive view of `window.scrollY`. On the server it is `undefined`.

```
const scrollY: ReactiveValue<number | undefined>;
```

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/98-reference/21-svelte-reactivity-window.md) [llms.txt](/docs/svelte/svelte-reactivity-window/llms.txt)

previous next

[svelte/motion](/docs/svelte/svelte-motion) [svelte/reactivity](/docs/svelte/svelte-reactivity)

----
url: https://svelte.dev/docs/svelte/@const
----

[Skip to main content](#main)

> `{@const x = y}` is legacy syntax — use [`{const x = $derived(y)}`](declaration-tags) instead

The `{@const ...}` tag defines a local constant.

```
{#each boxes as box}
	{@const area = box.width * box.height}
	{box.width} * {box.height} = {area}
{/each}
```

`{@const}` is only allowed as an immediate child of a block — `{#if ...}`, `{#each ...}`, `{#snippet ...}` and so on — a `<Component />` or a `<svelte:boundary>`.

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/03-template-syntax/10-@const.md) [llms.txt](/docs/svelte/@const/llms.txt)

previous next

[{@attach ...}](/docs/svelte/@attach) [{@debug ...}](/docs/svelte/@debug)

----
url: https://svelte.dev/docs/svelte/scoped-styles
----

[Skip to main content](#main)

Svelte components can include a `<style>` element containing CSS that belongs to the component. This CSS is *scoped* by default, meaning that styles will not apply to any elements on the page outside the component in question.

This works by adding a class to affected elements, which is based on a hash of the component styles (e.g. `svelte-123xyz`).

```
<style>
	p {
		/* this will only affect <p> elements in this component */
		color: burlywood;
	}
</style>
```

## Specificity[](#Specificity)

Each scoped selector receives a [specificity](https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity) increase of 0-1-0, as a result of the scoping class (e.g. `.svelte-123xyz`) being added to the selector. This means that (for example) a `p` selector defined in a component will take precedence over a `p` selector defined in a global stylesheet, even if the global stylesheet is loaded later.

In some cases, the scoping class must be added to a selector multiple times, but after the first occurrence it is added with `:where(.svelte-xyz123)` in order to not increase specificity further.

## Scoped keyframes[](#Scoped-keyframes)

If a component defines `@keyframes`, the name is scoped to the component using the same hashing approach. Any `animation` rules in the component will be similarly adjusted:

```
<style>
	.bouncy {
		animation: bounce 10s;
	}

	/* these keyframes are only accessible inside this component */
	@keyframes bounce {
		/* ... */
	}
</style>
```

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/04-styling/01-scoped-styles.md) [llms.txt](/docs/svelte/scoped-styles/llms.txt)

previous next

[await](/docs/svelte/await-expressions) [Global styles](/docs/svelte/global-styles)

----
url: https://svelte.dev/docs/svelte/svelte-head/llms.txt
----

````
```svelte
<svelte:head>...</svelte:head>
```

This element makes it possible to insert elements into `document.head`. During server-side rendering, `head` content is exposed separately to the main `body` content.

As with `<svelte:window>`, `<svelte:document>` and `<svelte:body>`, this element may only appear at the top level of your component and must never be inside a block or element.

```svelte
<svelte:head>
	<title>Hello world!</title>
	<meta name="description" content="This is where the description goes for SEO" />
</svelte:head>
```
````

----
url: https://svelte.dev/docs/svelte/$host/llms.txt
----

````
When compiling a component as a [custom element](custom-elements), the `$host` rune provides access to the host element, allowing you to (for example) dispatch custom events (demo:

<!-- prettier-ignore -->
```svelte
/// file: Stepper.svelte
<svelte:options customElement="my-stepper" />

<script>
	function dispatch(type) {
		+++$host()+++.dispatchEvent(new CustomEvent(type));
	}
</script>

<button onclick={() => dispatch('decrement')}>decrement</button>
<button onclick={() => dispatch('increment')}>increment</button>
```

<!-- prettier-ignore -->
```svelte
/// file: App.svelte
<script>
	import './Stepper.svelte';

	let count = $state(0);
</script>

<my-stepper
	ondecrement={() => count -= 1}
	onincrement={() => count += 1}
></my-stepper>

<p>count: {count}</p>
```
````

----
url: https://svelte.dev/docs/svelte/@attach
----

[Skip to main content](#main)

Attachments are functions that run in an [effect]($effect) when an element is mounted to the DOM or when [state]($state) read inside the function updates.

Optionally, they can return a function that is called before the attachment re-runs, or after the element is later removed from the DOM.

> Attachments are available in Svelte 5.29 and newer.

App

```
<script>
	/** @type {import('svelte/attachments').Attachment} */
	function myAttachment(element) {
		console.log(element.nodeName); // 'DIV'

		return () => {
			console.log('cleaning up');
		};
	}
</script>

<div {@attach myAttachment}>...</div>
```

```
<script lang="ts">
	import type { Attachment } from 'svelte/attachments';

	const myAttachment: Attachment = (element) => {
		console.log(element.nodeName); // 'DIV'

		return () => {
			console.log('cleaning up');
		};
	};
</script>

<div {@attach myAttachment}>...</div>
```

An element can have any number of attachments.

## Attachment factories[](#Attachment-factories)

A useful pattern is for a function, such as `tooltip` in this example, to *return* an attachment ([demo](/playground/untitled#H4sIAAAAAAAAE3VT0XLaMBD8lavbDiaNCUlbHhTItG_5h5AH2T5ArdBppDOEMv73SkbGJGnH47F9t3un3TsfMyO3mInsh2SW1Sa7zlZKo8_E0zHjg42pGAjxBPxp7cTvUHOMldLjv-IVGUbDoUw295VTlh-WZslqa8kxsLL2ACtHWxh175NffnQfAAGikSGxYQGfPEvGfPSIWtOH0TiBVo2pWJEBJtKhQp4YYzjG9JIdcuMM5IZqHMPioY8vOSA997zQoevf4a7heO7cdp34olRiTGr07OhwH1IdoO2A7dLMbwahZq6MbRhKZWqxk7rBxTGVbuHmhCgb5qDgmIx_J6XtHHukHTrYYqx_YpzYng8aO4RYayql7hU-1ZJl0akqHBE_D9KLolwL-Dibzc7iSln9XjtqTF1UpMkJ2EmXR-BgQErsN4pxIJKr0RVO1qrxAqaTO4fbc9bKulZm3cfDY3aZDgvFGErWjmzhN7KmfX5rXyDeX8Pt1mU-hXjdBOrtuB97vK4GPUtmJ41XcRMEGDLD8do0nJ73zhUhSlyRw0t3vPqD8cjfLs-axiFgNBrkUd9Ulp50c-GLxlXAVlJX-ffpZyiSn7H0eLCUySZQcQdXlxj4El0Yv_FZvIKElqqGTruVLhzu7VRKCh22_5toOyxsWqLwwzK-cCbYNdg-hy-p9D7sbiZWUnts_wLUOF3CJgQAAA==)):

App

```
<script>
	import tippy from 'tippy.js';

	let content = $state('Hello!');

	/**
	 * @param {string} content
	 * @returns {import('svelte/attachments').Attachment}
	 */
	function tooltip(content) {
		return (element) => {
			const tooltip = tippy(element, { content });
			return tooltip.destroy;
		};
	}
</script>

<input bind:value={content} />

<button {@attach tooltip(content)}>
	Hover me
</button>
```

```
<script lang="ts">
	import tippy from 'tippy.js';
	import type { Attachment } from 'svelte/attachments';

	let content = $state('Hello!');

	function tooltip(content: string): Attachment {
		return (element) => {
			const tooltip = tippy(element, { content });
			return tooltip.destroy;
		};
	}
</script>

<input bind:value={content} />

<button {@attach tooltip(content)}>
	Hover me
</button>
```

Since the `tooltip(content)` expression runs inside an [effect]($effect), the attachment will be destroyed and recreated whenever `content` changes. The same thing would happen for any state read *inside* the attachment function when it first runs. (If this isn’t what you want, see [Controlling when attachments re-run](#Controlling-when-attachments-re-run).)

## Inline attachments[](#Inline-attachments)

Attachments can also be created inline ([demo](/playground/untitled#H4sIAAAAAAAAE71Wf3OaWBT9KoyTTnW3MS-I3dYmnWXVtnRAazRJzbozRSQEApiRhwKO333vuY8m225m_9yZGOT9OPfcc84D943UTfxGr_G7K6Xr3TVeNW7D2M8avT_3DVk-YAoDNF4vNB8e2tnWjyXGlm7mPzfurVPpp5JgGmeZtwkf5PtFupCxLzVvHa832rl2lElX-s2Xm2DZFNqp_hs-rZetd4v07ORpT3qmQHu7MF2td0BZp8k6z_xkvfXP902_pZ2_1_aYWEiqm0kN8I4r79qbdZ6umnq3q_2iNf22F4dE6qt2oimwdpim_uY6XMm7Fuo-IQT_iTD_CeGTHwZ38ieIJUFQRxirR1Xf39Dw0X5z0I72Af4tD61vvPNwWKQnqmfPTbduhsEd2J3vO_oBd3dc6fF2X7umNdWGf0vBRhSS6qoV7cCXfTXWfKmvWG61_si_vfU92Wz-E4RhsLhNIYinsox9QKGVd8-tuACCeKXRX12P-T_eKf7fhTq0Hvt-f3ailtSeoxJHRo1-58NoPe1UiBc1hkL8Yeh45y_vQ3mcuNl9T8s3cXPRWLnS7YWJG_gn2Tb4tUjid8jua-PVl08j_ab8I14mH8Llx0s5Tz5Err4ql52r_GYg0mVy1bEGZuD0ze64b5TWYFiM-16wSuJ4JT5vfVpDcztrcG_YkRU4s6HxufzDWF4XuVeJ1P10IbzBemt3Vp1V2e04ZXfrJd7Wicyd039brRIv_RIVu_nXi7X1cfL2sy66ztToUp1TO7qJ7NlwZ0f30pld5qNSVE5o6PbMojFHjgZB7oSicPpGteyLclQap7SvY0dXtM_LR1NT2JFHey3aaxa0VxCeYJ7RMHemoiCcgPZV9pR7o7kgcOjeGliYk9hjDZx8FAq6enwlTPSZj_vYPw9Il64dXdIY8ZmapzwfEd8-1ZyaxWhqkIZOibXUd-6Upqi1pD4uMicCV1GA_7zi73UN8BaF4sC8peJtMjfmjbHZBFwq5ov50qRaE0l96NZggnW4KqypYRAW-uhSz9ADvklwJF2J-5W0Z5fQPBhDX92R6I_0IFxRgDftge4l4dP-gH1hjD7uqU6fsOEZ9UNrCdPB-nys6uXgY6O3ZMd9sy5T9PghqrWHdjo4jB51CgLiKJaDYYA-7WgYONf1FbjkI-mE3EAfUY_rijfuJ_CVPaR50oe9JF7Q0pI8Dw3osxxYHdYPGbp2CnwHF8KvwJv2wEv0Z3ilQI6U9uwbZxbYJXvEmjjQjjCHkvNLvNg3yhzXQd1olamsT4IRrZmX0MUDpwL7R8zzHj7pSh9hPHFSHjLezKqAST51uC5zmtQ87skDUaneLokT5RbXkPWSYz53Abgjc8_o4KFGUZ-Hgv2Z1l5OTYM9D-HfUD0L-EwxH5wRnIG61gS-khfgY1bq7IAP_DA4l5xRuh9xlm8yGjutc8t-wHtkhWv3hc7aqGwiK5KzgvM5xRkZYn193uEln-su55j1GaIv7oM4iPrsVHiG0Dx7TR9-1lBfqFdwfvSd5LNL5xyZVp5NoHFZ57FkfiF6vKs4k5zvIfrX5xX6MXmt0gM5MTu8DjnhukrHHzTRd3jm0dma0_f_x5cxP9f4jBdqHvmbq2fUjzqcKh2Cp-yWj9ntcHanXmBXxhu7Q--eyjhfNFpaV7zgz4nWEUb7zUOhpevjjf_gu_KZ99pxFlZ-T3sttkmYqrco_26q35v0Ewzv5EZPbnL_8BfduWGMnyyN3q0bZ_7hb_7KG_L4CQAA)):

App

```
<canvas
	width={32}
	height={32}
	{@attach (canvas) => {
		const context = canvas.getContext('2d');

		$effect(() => {
			context.fillStyle = color;
			context.fillRect(0, 0, canvas.width, canvas.height);
		});
	}}
></canvas>
```

> The nested effect runs whenever `color` changes, while the outer effect (where `canvas.getContext(...)` is called) only runs once, since it doesn’t read any reactive state.

## Conditional attachments[](#Conditional-attachments)

Falsy values like `false` or `undefined` are treated as no attachment, enabling conditional usage:

```
<div {@attach enabled && myAttachment}>...</div>
```

## Passing attachments to components[](#Passing-attachments-to-components)

When used on a component, `{@attach ...}` will create a prop whose key is a [`Symbol`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol). If the component then [spreads](/tutorial/svelte/spread-props) props onto an element, the element will receive those attachments.

This allows you to create *wrapper components* that augment elements ([demo](/playground/untitled#H4sIAAAAAAAAE3VUS3ObMBD-KxvajnFqsJM2PhA7TXrKob31FjITAbKtRkiMtDhJPfz3LiAMdpxhGJvdb1_fPnaeYjn3Iu-WIbJ04028lZDcetHDzsO3olbVApI74F1RhHbLJdayhFl-Sp5qhVwhufEWNjWiwJtYxSjyQhsEFEXxBiujcxg1_8O_dnQ9APwsEbVyiHDafjrvDZCgkiO4MLCEzxYZcn90z6XUZ6OxA61KlaIgV6i1pFC-sxjDrlbHaDiWRoGvdMbHsLzp5DES0mJnRxGaRBvcBHb7yFUTCQeunEWYcYtGv12TqgFUDbCK1WLaM6IWQhUlQiJUFm2ZLPly51xXMG0Rjoyd69C7UqqG2nu95QZyXvtvLVpri2-SN4hoLXXCZFfhQ8aQBU1VgdEaH_vSgyBZR_BpPp_vi0tY-rw2ulRZkGqpTQRbZvwa2BPgFC8bgbw31CbjJjAsE6WNYBZeGp7vtQXLMqHWnZx-5kM1TR5ycpkZXQR2wzL94l8Ur1C_3-g168SfQf1MyfRi3LW9fs77emJEw5QV9SREoLTq06tcczq7d6xEUcJX2vAhO1b843XK34e5unZEMBr15ekuKEusluWAF8lXhE2ZTP2r2RcIHJ-163FPKerCgYJLOB9i4GvNwviI5-gAQiFFBk3tBTOU3HFXEk0R8o86WvUD64aINhv5K3oRmpJXkw8uxMG6Hh6JY9X7OwGSqfUy9tDG3sHNoEi0d_d_fv9qndxRU0VClFqo3KVo3U655Hnt1PXB3Qra2Y2QGdEwgTAMCxopsoxOe6SD0gD8movDhT0LAnhqlE8gVCpLWnRoV7OJCkFAwEXitrYL1W7p7pbiE_P7XH6E_rihODm5s52XtiH9Ekaw0VgI9exadWL1uoEYjPtg2672k5szsxbKyWB2fdT0w5Y_0hcT8oXOlRetmLS8-g-6TLXXQgYAAA==)):

Button

```
<script>
	/** @type {import('svelte/elements').HTMLButtonAttributes} */
	let { children, ...props } = $props();
</script>

<!-- `props` includes attachments -->
<button {...props}>
	{@render children?.()}
</button>
```

```
<script lang="ts">
	import type { HTMLButtonAttributes } from 'svelte/elements';

	let { children, ...props }: HTMLButtonAttributes = $props();
</script>

<!-- `props` includes attachments -->
<button {...props}>
	{@render children?.()}
</button>
```

App

```
<script>
	import tippy from 'tippy.js';
	import Button from './Button.svelte';

	let content = $state('Hello!');

	/**
	 * @param {string} content
	 * @returns {import('svelte/attachments').Attachment}
	 */
	function tooltip(content) {
		return (element) => {
			const tooltip = tippy(element, { content });
			return tooltip.destroy;
		};
	}
</script>

<input bind:value={content} />

<Button {@attach tooltip(content)}>
	Hover me
</Button>
```

```
<script lang="ts">
	import tippy from 'tippy.js';
	import Button from './Button.svelte';
	import type { Attachment } from 'svelte/attachments';

	let content = $state('Hello!');

	function tooltip(content: string): Attachment {
		return (element) => {
			const tooltip = tippy(element, { content });
			return tooltip.destroy;
		};
	}
</script>

<input bind:value={content} />

<Button {@attach tooltip(content)}>
	Hover me
</Button>
```

## Controlling when attachments re-run[](#Controlling-when-attachments-re-run)

Attachments, unlike [actions](use), are fully reactive: `{@attach foo(bar)}` will re-run on changes to `foo` *or* `bar` (or any state read inside `foo`):

```
function foofunction foo(bar: any): (node: any) => void(bar(parameter) bar: any) {
	return (node(parameter) node: any) => {
		veryExpensiveSetupWorkany(node(parameter) node: any);
		updateany(node(parameter) node: any, bar(parameter) bar: any);
	};
}
```

In the rare case that this is a problem (for example, if `foo` does expensive and unavoidable setup work) consider passing the data inside a function and reading it in a child effect:

```
function foofunction foo(getBar: any): (node: any) => void(getBar(parameter) getBar: any) {
	return (node(parameter) node: any) => {
		veryExpensiveSetupWorkany(node(parameter) node: any);

		$effectfunction $effect(fn: () => void | (() => void)): void
namespace $effect

Runs code when a component is mounted to the DOM, and then whenever its dependencies change, i.e. $state or $derived values.
The timing of the execution is after the DOM has been updated.




Example:



$effect(() => console.log('The count is now ' + count));

If you return a function from the effect, it will be called right before the effect is run again, or when the component is unmounted.




Does not run during server-side rendering.




{@link https://svelte.dev/docs/svelte/$effect Documentation}


fn 

The function to execute


(() => {
			updateany(node(parameter) node: any, getBar(parameter) getBar: any());
		});
	}
}
```

## Creating attachments programmatically[](#Creating-attachments-programmatically)

To add attachments to an object that will be spread onto a component or element, use [`createAttachmentKey`](svelte-attachments#createAttachmentKey).

## Converting actions to attachments[](#Converting-actions-to-attachments)

If you’re using a library that only provides actions, you can convert them to attachments with [`fromAction`](svelte-attachments#fromAction), allowing you to (for example) use them with components.

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/03-template-syntax/09-@attach.md) [llms.txt](/docs/svelte/@attach/llms.txt)

previous next

[{@html ...}](/docs/svelte/@html) [{@const ...}](/docs/svelte/@const)

----
url: https://svelte.dev/docs/svelte/transition
----

[Skip to main content](#main)

A *transition* is triggered by an element entering or leaving the DOM as a result of a state change.

When a block (such as an `{#if ...}` block) is transitioning out, all elements inside it, including those that do not have their own transitions, are kept in the DOM until every transition in the block has been completed.

The `transition:` directive indicates a *bidirectional* transition, which means it can be smoothly reversed while the transition is in progress.

```
<script>
	import { fade } from 'svelte/transition';

	let visible = $state(false);
</script>

<button onclick={() => visible = !visible}>toggle</button>

{#if visible}
	<div transition:fade>fades in and out</div>
{/if}
```

## Local vs global[](#Local-vs-global)

Transitions are local by default. Local transitions only play when the block they belong to is created or destroyed, *not* when parent blocks are created or destroyed.

```
{#if x}
	{#if y}
		<p transition:fade>fades in and out only when y changes</p>

		<p transition:fade|global>fades in and out when x or y change</p>
	{/if}
{/if}
```

## Built-in transitions[](#Built-in-transitions)

A selection of built-in transitions can be imported from the [`svelte/transition`](svelte-transition) module.

## Transition parameters[](#Transition-parameters)

Transitions can have parameters.

(The double `{{curlies}}` aren’t a special syntax; this is an object literal inside an expression tag.)

```
{#if visible}
	<div transition:fade={{ duration: 2000 }}>fades in and out over two seconds</div>
{/if}
```

## Accessibility[](#Accessibility)

Transitions are driven by the [Web Animations API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API) rather than by CSS. A global `@media (prefers-reduced-motion: reduce)` rule that zeroes `transition-duration` and `animation-duration` therefore has no effect on them.

Use [`prefersReducedMotion`](svelte-motion#prefersReducedMotion) to adjust (or completely disable) the transition accordingly for devices who request reduced motion.

## Custom transition functions[](#Custom-transition-functions)

```
transitionany = (node(parameter) node: HTMLElement: HTMLElementinterface HTMLElement

The HTMLElement interface represents any HTML element. Some elements directly implement this interface, while others implement it via an interface that inherits it.




MDN Reference


, params(parameter) params: any: any, options(parameter) options: {
    direction: "in" | "out" | "both";
}: { direction(property) direction: "in" | "out" | "both": 'in' | 'out' | 'both' }) => {
	delayany?: numberany,
	durationany?: numberany,
	easingany?: (t(parameter) t: number: number) => numberany,
	cssany?: (t(parameter) t: number: number, u(parameter) u: number: number) => stringany,
	tickany?: (t(parameter) t: number: number, u(parameter) u: number: number) => void
}
```

Transitions can use custom functions. If the returned object has a `css` function, Svelte will generate keyframes for a [web animation](https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API).

The `t` argument passed to `css` is a value between `0` and `1` after the `easing` function has been applied. *In* transitions run from `0` to `1`, *out* transitions run from `1` to `0` — in other words, `1` is the element’s natural state, as though no transition had been applied. The `u` argument is equal to `1 - t`.

The function is called repeatedly *before* the transition begins, with different `t` and `u` arguments.

App

```
<script>
	import { elasticOut } from 'svelte/easing';

	/** @type {boolean} */
	export let visible;

	/**
	 * @param {HTMLElement} node
	 * @param {{ delay?: number, duration?: number, easing?: (t: number) => number }} params
	 */
	function whoosh(node, params) {
		const existingTransform = getComputedStyle(node).transform.replace('none', '');

		return {
			delay: params.delay || 0,
			duration: params.duration || 400,
			easing: params.easing || elasticOut,
			css: (t, u) => `transform: ${existingTransform} scale(${t})`
		};
	}
</script>

{#if visible}
	<div in:whoosh>whooshes in</div>
{/if}
```

```
<script lang="ts">
	import { elasticOut } from 'svelte/easing';
	export let visible: boolean;

	function whoosh(node: HTMLElement, params: { delay?: number, duration?: number, easing?: (t: number) => number }) {
		const existingTransform = getComputedStyle(node).transform.replace('none', '');

		return {
			delay: params.delay || 0,
			duration: params.duration || 400,
			easing: params.easing || elasticOut,
			css: (t, u) => `transform: ${existingTransform} scale(${t})`
		};
	}
</script>

{#if visible}
	<div in:whoosh>whooshes in</div>
{/if}
```

A custom transition function can also return a `tick` function, which is called *during* the transition with the same `t` and `u` arguments.

> If it’s possible to use `css` instead of `tick`, do so — web animations can run off the main thread, preventing jank on slower devices.

App

```
<script>
	export let visible = false;

	/**
	 * @param {HTMLElement} node
	 * @param {{ speed?: number }} params
	 */
	function typewriter(node, { speed = 1 }) {
		const valid = node.childNodes.length === 1 && node.childNodes[0].nodeType === Node.TEXT_NODE;

		if (!valid) {
			throw new Error(`This transition only works on elements with a single text node child`);
		}

		const text = node.textContent;
		const duration = text.length / (speed * 0.01);

		return {
			duration,
			tick: (t) => {
				const i = ~~(text.length * t);
				node.textContent = text.slice(0, i);
			}
		};
	}
</script>

{#if visible}
	<p in:typewriter={{ speed: 1 }}>The quick brown fox jumps over the lazy dog</p>
{/if}
```

```
<script lang="ts">
	export let visible = false;

	function typewriter(node: HTMLElement, { speed = 1 }: { speed?: number }) {
		const valid = node.childNodes.length === 1 && node.childNodes[0].nodeType === Node.TEXT_NODE;

		if (!valid) {
			throw new Error(`This transition only works on elements with a single text node child`);
		}

		const text = node.textContent;
		const duration = text.length / (speed * 0.01);

		return {
			duration,
			tick: (t) => {
				const i = ~~(text.length * t);
				node.textContent = text.slice(0, i);
			}
		};
	}
</script>

{#if visible}
	<p in:typewriter={{ speed: 1 }}>The quick brown fox jumps over the lazy dog</p>
{/if}
```

If a transition returns a function instead of a transition object, the function will be called in the next microtask. This allows multiple transitions to coordinate, making [crossfade effects](/tutorial/deferred-transitions) possible.

Transition functions also receive a third argument, `options`, which contains information about the transition.

Available values in the `options` object are:

* `direction` - one of `in`, `out`, or `both` depending on the type of transition

## Transition events[](#Transition-events)

An element with transitions will dispatch the following events in addition to any standard DOM events:

* `introstart`
* `introend`
* `outrostart`
* `outroend`

```
{#if visible}
	<p
		transition:fly={{ y: 200, duration: 2000 }}
		onintrostart={() => (status = 'intro started')}
		onoutrostart={() => (status = 'outro started')}
		onintroend={() => (status = 'intro ended')}
		onoutroend={() => (status = 'outro ended')}
	>
		Flies in and out
	</p>
{/if}
```

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/03-template-syntax/14-transition.md) [llms.txt](/docs/svelte/transition/llms.txt)

previous next

[use:](/docs/svelte/use) [in: and out:](/docs/svelte/in-and-out)

----
url: https://svelte.dev/docs/svelte/testing
----

[Skip to main content](#main)

Testing helps you write and maintain your code and guard against regressions. Testing frameworks help you with that, allowing you to describe assertions or expectations about how your code should behave. Svelte is unopinionated about which testing framework you use — you can write unit tests, integration tests, and end-to-end tests using solutions like [Vitest](https://vitest.dev/), [Jasmine](https://jasmine.github.io/), [Cypress](https://www.cypress.io/) and [Playwright](https://playwright.dev/).

## Unit and component tests with Vitest[](#Unit-and-component-tests-with-Vitest)

Unit tests allow you to test small isolated parts of your code. Integration tests allow you to test parts of your application to see if they work together. If you’re using Vite (including via SvelteKit), we recommend using [Vitest](https://vitest.dev/). You can use the Svelte CLI to [setup Vitest](/docs/cli/vitest) either during project creation or later on.

To setup Vitest manually, first install it:

```
npm install -D vitest
```

Then adjust your `vite.config.js`:

vite.config

```
import { defineConfig(alias) function defineConfig(config: UserConfig): UserConfig (+4 overloads)
import defineConfig } from 'vitest/config';

export default defineConfig(alias) defineConfig(config: UserConfig): UserConfig (+4 overloads)
import defineConfig({
	// ...
	// Tell Vitest to use the `browser` entry points in `package.json` files, even though it's running in Node
	resolve(property) resolve?: AllResolveOptions | undefined: processnamespace process
var process: NodeJS.Process.env(property) NodeJS.Process.env: NodeJS.ProcessEnv

The process.env property returns an object containing the user environment.
See environ(7).




An example of this object looks like:



{
  TERM: 'xterm-256color',
  SHELL: '/usr/local/bin/bash',
  USER: 'maciej',
  PATH: '~/.bin/:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin',
  PWD: '/Users/maciej',
  EDITOR: 'vim',
  SHLVL: '1',
  HOME: '/Users/maciej',
  LOGNAME: 'maciej',
  _: '/usr/local/bin/node'
}

It is possible to modify this object, but such modifications will not be
reflected outside the Node.js process, or (unless explicitly requested)
to other Worker threads.
In other words, the following example would not work:



node -e 'process.env.foo = "bar"' &#x26;&#x26; echo $foo

While the following will:



import { env } from 'node:process';

env.foo = 'bar';
console.log(env.foo);

Assigning a property on process.env will implicitly convert the value
to a string. This behavior is deprecated. Future versions of Node.js may
throw an error when the value is not a string, number, or boolean.



import { env } from 'node:process';

env.test = null;
console.log(env.test);
// => 'null'
env.test = undefined;
console.log(env.test);
// => 'undefined'

Use delete to delete a property from process.env.



import { env } from 'node:process';

env.TEST = 1;
delete env.TEST;
console.log(env.TEST);
// => undefined

On Windows operating systems, environment variables are case-insensitive.



import { env } from 'node:process';

env.TEST = 1;
console.log(env.test);
// => 1

Unless explicitly specified when creating a Worker instance,
each Worker thread has its own copy of process.env, based on its
parent thread's process.env, or whatever was specified as the env option
to the Worker constructor. Changes to process.env will not be visible
across Worker threads, and only the main thread can make changes that
are visible to the operating system or to native add-ons. On Windows, a copy of process.env on a Worker instance operates in a case-sensitive manner
unlike the main thread.




The process.env property returns an object containing the user environment.
See environ(7).




An example of this object looks like:



{
  "TERM": "xterm-256color",
  "SHELL": "/usr/local/bin/bash",
  "USER": "maciej",
  "PATH": "~/.bin/:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin",
  "PWD": "/Users/maciej",
  "EDITOR": "vim",
  "SHLVL": "1",
  "HOME": "/Users/maciej",
  "LOGNAME": "maciej",
  "_": "/usr/local/bin/node"
}

It is possible to modify this object, but such modifications will not be
reflected outside the Node.js process, or (unless explicitly requested)
to other Worker threads.
In other words, the following example would not work:



node -e 'process.env.foo = "bar"' &#x26;&#x26; echo $foo

While the following will:



import { env } from 'node:process';

env.foo = 'bar';
console.log(env.foo);

Assigning a property on process.env will implicitly convert the value
to a string. This behavior is deprecated. Future versions of Node.js may
throw an error when the value is not a string, number, or boolean.



import { env } from 'node:process';

env.test = null;
console.log(env.test);
// => 'null'
env.test = undefined;
console.log(env.test);
// => 'undefined'

Use delete to delete a property from process.env.



import { env } from 'node:process';

env.TEST = 1;
delete env.TEST;
console.log(env.TEST);
// => undefined

On Windows operating systems, environment variables are case-insensitive.



import { env } from 'node:process';

env.TEST = 1;
console.log(env.test);
// => 1

Unless explicitly specified when creating a Worker instance,
each Worker thread has its own copy of process.env, based on its
parent thread's process.env, or whatever was specified as the env option
to the Worker constructor. Changes to process.env will not be visible
across Worker threads, and only the main thread can make changes that
are visible to the operating system or to native add-ons. On Windows, a copy of process.env on a Worker instance operates in a case-sensitive manner
unlike the main thread.




v0.1.27




v0.1.27


.VITESTstring | undefined
		? {
				conditions(property) EnvironmentResolveOptions.conditions?: string[] | undefined: ['browser']
			}
		: undefinedvar undefined
});
```

> If loading the browser version of all your packages is undesirable, because (for example) you also test backend libraries, [you may need to resort to an alias configuration](https://github.com/testing-library/svelte-testing-library/issues/222#issuecomment-1909993331)

You can now write unit tests for code inside your `.js/.ts` files:

multiplier.svelte.test

```
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);
});
```

multiplier.svelte

```
/**
 * @param {number} initial
 * @param {number} k
 */
export function multiplierfunction multiplier(initial: number, k: number): {
    readonly value: number;
    set: (c: number) => void;
}initialk(initial(parameter) initial: numberinitial, k(parameter) k: numberk) {
	let countlet count: number = $statefunction $state<number>(initial: number): number (+1 overload)
namespace $state

Declares reactive state.




Example:



let count = $state(0);

{@link https://svelte.dev/docs/svelte/$state Documentation}


initial 

The initial value


(initial(parameter) initial: numberinitial);

	return {
		get value(getter) value: number() {
			return countlet count: number * k(parameter) k: numberk;
		},
		/** @param {number} c */
		set(property) set: (c: number) => voidc: (c(parameter) c: numberc) => {
			countlet count: number = c(parameter) c: numberc;
		}
	};
}
```

```
export function multiplierfunction multiplier(initial: number, k: number): {
    readonly value: number;
    set: (c: number) => void;
}(initial(parameter) initial: number: number, k(parameter) k: number: number) {
	let countlet count: number = $statefunction $state<number>(initial: number): number (+1 overload)
namespace $state

Declares reactive state.




Example:



let count = $state(0);

{@link https://svelte.dev/docs/svelte/$state Documentation}


initial 

The initial value


(initial(parameter) initial: number);

	return {
		get value(getter) value: number() {
			return countlet count: number * k(parameter) k: number;
		},

		set(property) set: (c: number) => void: (c(parameter) c: number: number) => {
			countlet count: number = c(parameter) c: number;
		}
	};
}
```

### Using runes inside your test files[](#Unit-and-component-tests-with-Vitest-Using-runes-inside-your-test-files)

Since Vitest processes your test files the same way as your source files, you can use runes inside your tests as long as the filename includes `.svelte`:

multiplier.svelte.test

```
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);
});
```

multiplier.svelte

```
/**
 * @param {() => number} getCount
 * @param {number} k
 */
export function multiplierfunction multiplier(getCount: () => number, k: number): {
    readonly value: number;
}getCountk(getCount(parameter) getCount: () => numbergetCount, k(parameter) k: numberk) {
	return {
		get value(getter) value: number() {
			return getCount(parameter) getCount: () => numbergetCount() * k(parameter) k: numberk;
		}
	};
}
```

```
export function multiplierfunction multiplier(getCount: () => number, k: number): {
    readonly value: number;
}(getCount(parameter) getCount: () => number: () => number, k(parameter) k: number: number) {
	return {
		get value(getter) value: number() {
			return getCount(parameter) getCount: () => number() * k(parameter) k: number;
		}
	};
}
```

If the code being tested uses effects, you need to wrap the test inside `$effect.root`:

logger.svelte.test

```
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);

		// logger uses an $effect to log updates of its input
		let log = logger(() => count);

		// effects normally run after a microtask,
		// use flushSync to execute all pending effects synchronously
		flushSync();
		expect(log).toEqual([0]);

		count = 1;
		flushSync();

		expect(log).toEqual([0, 1]);
	});

	cleanup();
});
```

logger.svelte

```
/**
 * @param {() => any} getValue
 */
export function loggerfunction logger(getValue: () => any): any[]getValue(getValue(parameter) getValue: () => anygetValue) {
	/** @type {any[]} */
	let loglet log: any[]

{any[]}


 = [];

	$effectfunction $effect(fn: () => void | (() => void)): void
namespace $effect

Runs code when a component is mounted to the DOM, and then whenever its dependencies change, i.e. $state or $derived values.
The timing of the execution is after the DOM has been updated.




Example:



$effect(() => console.log('The count is now ' + count));

If you return a function from the effect, it will be called right before the effect is run again, or when the component is unmounted.




Does not run during server-side rendering.




{@link https://svelte.dev/docs/svelte/$effect Documentation}


fn 

The function to execute


(() => {
		loglet log: any[]

{any[]}


.push(method) Array<any>.push(...items: any[]): number

Appends new elements to the end of an array, and returns the new length of the array.


items 

New elements to add to the array.


(getValue(parameter) getValue: () => anygetValue());
	});

	return loglet log: any[]

{any[]}


;
}
```

```
export function loggerfunction logger(getValue: () => any): any[](getValue(parameter) getValue: () => any: () => any) {
	let loglet log: any[]: any[] = [];

	$effectfunction $effect(fn: () => void | (() => void)): void
namespace $effect

Runs code when a component is mounted to the DOM, and then whenever its dependencies change, i.e. $state or $derived values.
The timing of the execution is after the DOM has been updated.




Example:



$effect(() => console.log('The count is now ' + count));

If you return a function from the effect, it will be called right before the effect is run again, or when the component is unmounted.




Does not run during server-side rendering.




{@link https://svelte.dev/docs/svelte/$effect Documentation}


fn 

The function to execute


(() => {
		loglet log: any[].push(method) Array<any>.push(...items: any[]): number

Appends new elements to the end of an array, and returns the new length of the array.


items 

New elements to add to the array.


(getValue(parameter) getValue: () => any());
	});

	return loglet log: any[];
}
```

### Component testing[](#Unit-and-component-tests-with-Vitest-Component-testing)

It is possible to test your components in isolation, which allows you to render them in a browser (real or simulated), simulate behavior, and make assertions, without spinning up your whole app.

> Before writing component tests, think about whether you actually need to test the component, or if it’s more about the logic *inside* the component. If so, consider extracting out that logic to test it in isolation, without the overhead of a component.

To get started, install jsdom (a library that shims DOM APIs):

```
npm install -D jsdom
```

Then adjust your `vite.config.js`:

vite.config

```
import { defineConfig(alias) function defineConfig(config: UserConfig): UserConfig (+4 overloads)
import defineConfig } from 'vitest/config';

export default defineConfig(alias) defineConfig(config: UserConfig): UserConfig (+4 overloads)
import defineConfig({
	plugins(property) UserConfig.plugins?: PluginOption[] | undefined

Array of vite plugins to use.


: [
		/* ... */
	],
	test(property) UserConfig.test?: InlineConfig | undefined

Options for Vitest


: {
		// If you are testing components client-side, you need to set up a DOM environment.
		// If not all your files should have this environment, you can use a
		// `// @vitest-environment jsdom` comment at the top of the test files instead.
		environment(property) InlineConfig.environment?: VitestEnvironment | undefined

Running environment




Supports 'node', 'jsdom', 'happy-dom', 'edge-runtime'




If used unsupported string, will try to load the package vitest-environment-${env}




'node'


: 'jsdom'
	},
	// Tell Vitest to use the `browser` entry points in `package.json` files, even though it's running in Node
	resolve(property) resolve?: AllResolveOptions | undefined: processnamespace process
var process: NodeJS.Process.env(property) NodeJS.Process.env: NodeJS.ProcessEnv

The process.env property returns an object containing the user environment.
See environ(7).




An example of this object looks like:



{
  TERM: 'xterm-256color',
  SHELL: '/usr/local/bin/bash',
  USER: 'maciej',
  PATH: '~/.bin/:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin',
  PWD: '/Users/maciej',
  EDITOR: 'vim',
  SHLVL: '1',
  HOME: '/Users/maciej',
  LOGNAME: 'maciej',
  _: '/usr/local/bin/node'
}

It is possible to modify this object, but such modifications will not be
reflected outside the Node.js process, or (unless explicitly requested)
to other Worker threads.
In other words, the following example would not work:



node -e 'process.env.foo = "bar"' &#x26;&#x26; echo $foo

While the following will:



import { env } from 'node:process';

env.foo = 'bar';
console.log(env.foo);

Assigning a property on process.env will implicitly convert the value
to a string. This behavior is deprecated. Future versions of Node.js may
throw an error when the value is not a string, number, or boolean.



import { env } from 'node:process';

env.test = null;
console.log(env.test);
// => 'null'
env.test = undefined;
console.log(env.test);
// => 'undefined'

Use delete to delete a property from process.env.



import { env } from 'node:process';

env.TEST = 1;
delete env.TEST;
console.log(env.TEST);
// => undefined

On Windows operating systems, environment variables are case-insensitive.



import { env } from 'node:process';

env.TEST = 1;
console.log(env.test);
// => 1

Unless explicitly specified when creating a Worker instance,
each Worker thread has its own copy of process.env, based on its
parent thread's process.env, or whatever was specified as the env option
to the Worker constructor. Changes to process.env will not be visible
across Worker threads, and only the main thread can make changes that
are visible to the operating system or to native add-ons. On Windows, a copy of process.env on a Worker instance operates in a case-sensitive manner
unlike the main thread.




The process.env property returns an object containing the user environment.
See environ(7).




An example of this object looks like:



{
  "TERM": "xterm-256color",
  "SHELL": "/usr/local/bin/bash",
  "USER": "maciej",
  "PATH": "~/.bin/:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin",
  "PWD": "/Users/maciej",
  "EDITOR": "vim",
  "SHLVL": "1",
  "HOME": "/Users/maciej",
  "LOGNAME": "maciej",
  "_": "/usr/local/bin/node"
}

It is possible to modify this object, but such modifications will not be
reflected outside the Node.js process, or (unless explicitly requested)
to other Worker threads.
In other words, the following example would not work:



node -e 'process.env.foo = "bar"' &#x26;&#x26; echo $foo

While the following will:



import { env } from 'node:process';

env.foo = 'bar';
console.log(env.foo);

Assigning a property on process.env will implicitly convert the value
to a string. This behavior is deprecated. Future versions of Node.js may
throw an error when the value is not a string, number, or boolean.



import { env } from 'node:process';

env.test = null;
console.log(env.test);
// => 'null'
env.test = undefined;
console.log(env.test);
// => 'undefined'

Use delete to delete a property from process.env.



import { env } from 'node:process';

env.TEST = 1;
delete env.TEST;
console.log(env.TEST);
// => undefined

On Windows operating systems, environment variables are case-insensitive.



import { env } from 'node:process';

env.TEST = 1;
console.log(env.test);
// => 1

Unless explicitly specified when creating a Worker instance,
each Worker thread has its own copy of process.env, based on its
parent thread's process.env, or whatever was specified as the env option
to the Worker constructor. Changes to process.env will not be visible
across Worker threads, and only the main thread can make changes that
are visible to the operating system or to native add-ons. On Windows, a copy of process.env on a Worker instance operates in a case-sensitive manner
unlike the main thread.




v0.1.27




v0.1.27


.VITESTstring | undefined
		? {
				conditions(property) EnvironmentResolveOptions.conditions?: string[] | undefined: ['browser']
			}
		: undefinedvar undefined
});
```

After that, you can create a test file in which you import the component to test, interact with it programmatically and write expectations about the results:

component.test

```
import { flushSync(alias) function flushSync<T = void>(fn?: (() => T) | undefined): T
import flushSync

Synchronously flush any pending updates.
Returns void if no callback is provided, otherwise returns the result of calling the callback.


reference, mount(alias) function mount<Props extends Record<string, any>, Exports extends Record<string, any>>(component: ComponentType<SvelteComponent<Props>> | Component<Props, Exports, any>, options: MountOptions<Props>): Exports
import mount

Mounts a component to the given target and returns the exports and potentially the props (if compiled with accessors: true) of the component.
Transitions will play during the initial render unless the intro option is set to false.


reference, unmount(alias) function unmount(component: Record<string, any>, options?: {
    outro?: boolean;
} | undefined): Promise<void>
import unmount

Unmounts a component that was previously mounted using mount or hydrate.




Since 5.13.0, if options.outro is true, transitions will play before the component is removed from the DOM.




Returns a Promise that resolves after transitions have completed if options.outro is true, or immediately otherwise (prior to 5.13.0, returns void).



import { mount, unmount } from 'svelte';
import App from './App.svelte';

const app = mount(App, { target: document.body });

// later...
unmount(app, { outro: true });
reference } from 'svelte';
import { expect(alias) const expect: ExpectStatic
import expect, test(alias) const test: TestAPI
import test

Defines a test case with a given name and test function. The test function can optionally be configured with test options.


name 


The name of the test or a function that will be used as a test name.



optionsOrFn 


Optional. The test options or the test function if no explicit name is provided.



optionsOrTest 


Optional. The test function or options, depending on the previous parameters.





{Error} If called inside another test function.



// Define a simple test
test('should add two numbers', () => {
  expect(add(1, 2)).toBe(3);
});
// Define a test with options
test('should subtract two numbers', { retry: 3 }, () => {
  expect(subtract(5, 2)).toBe(3);
});
 } from 'vitest';
import Component(alias) type Component = SvelteComponent<Record<string, any>, any, any>
(alias) const Component: LegacyComponentType
import Component from './Component.svelte';

test(alias) test<object>(name: string | Function, fn?: TestFunction<object> | undefined, options?: number): void (+1 overload)
import test

Defines a test case with a given name and test function. The test function can optionally be configured with test options.


name 


The name of the test or a function that will be used as a test name.



optionsOrFn 


Optional. The test options or the test function if no explicit name is provided.



optionsOrTest 


Optional. The test function or options, depending on the previous parameters.





{Error} If called inside another test function.



// Define a simple test
test('should add two numbers', () => {
  expect(add(1, 2)).toBe(3);
});
// Define a test with options
test('should subtract two numbers', { retry: 3 }, () => {
  expect(subtract(5, 2)).toBe(3);
});
('Component', () => {
	// Instantiate the component using Svelte's `mount` API
	const componentconst component: {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<string, any> = mount(alias) mount<Record<string, any>, {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<string, any>>(component: ComponentType<SvelteComponent<Record<string, any>, any, any>> | Component<Record<string, any>, {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<string, any>, any>, options: MountOptions<...>): {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<...>
import mount

Mounts a component to the given target and returns the exports and potentially the props (if compiled with accessors: true) of the component.
Transitions will play during the initial render unless the intro option is set to false.


reference(Component(alias) const Component: LegacyComponentType
import Component, {
		target(property) target: Document | Element | ShadowRoot

Target element where the component will be mounted.


: documentvar document: Document

window.document returns a reference to the document contained in the window.




MDN Reference


.body(property) Document.body: HTMLElement

The Document.body property represents the  or  node of the current document, or null if no such element exists.




MDN Reference


, // `document` exists because of jsdom
		props(property) props?: Record<string, any> | undefined

Component properties.


: { initial(property) initial: number: 0 }
	});

	expect(alias) expect<string>(actual: string, message?: string): Assertion<string> (+1 overload)
import expect(documentvar document: Document

window.document returns a reference to the document contained in the window.




MDN Reference


.body(property) Document.body: HTMLElement

The Document.body property represents the  or  node of the current document, or null if no such element exists.




MDN Reference


.innerHTML(property) Element.innerHTML: string

The innerHTML property of the Element interface gets or sets the HTML or XML markup contained within the element, omitting any shadow roots in both cases.




MDN Reference


).toBe(property) JestAssertion<string>.toBe: <string>(expected: string) => void

Checks that a value is what you expect. It calls Object.is to compare values.
Don't use toBe with floating-point numbers.




expect(result).toBe(42);
expect(status).toBe(true);


('<button>0</button>');

	// Click the button, then flush the changes so you can synchronously write expectations
	documentvar document: Document

window.document returns a reference to the document contained in the window.




MDN Reference


.body(property) Document.body: HTMLElement

The Document.body property represents the  or  node of the current document, or null if no such element exists.




MDN Reference


.querySelector(method) ParentNode.querySelector<"button">(selectors: "button"): HTMLButtonElement | null (+4 overloads)

Returns the first element that is a descendant of node that matches selectors.




MDN Reference


('button')?.click(method) HTMLElement.click(): void

The HTMLElement.click() method simulates a mouse click on an element. When called on an element, the element's click event is fired (unless its disabled attribute is set).




MDN Reference


();
	flushSync(alias) flushSync<void>(fn?: (() => void) | undefined): void
import flushSync

Synchronously flush any pending updates.
Returns void if no callback is provided, otherwise returns the result of calling the callback.


reference();

	expect(alias) expect<string>(actual: string, message?: string): Assertion<string> (+1 overload)
import expect(documentvar document: Document

window.document returns a reference to the document contained in the window.




MDN Reference


.body(property) Document.body: HTMLElement

The Document.body property represents the  or  node of the current document, or null if no such element exists.




MDN Reference


.innerHTML(property) Element.innerHTML: string

The innerHTML property of the Element interface gets or sets the HTML or XML markup contained within the element, omitting any shadow roots in both cases.




MDN Reference


).toBe(property) JestAssertion<string>.toBe: <string>(expected: string) => void

Checks that a value is what you expect. It calls Object.is to compare values.
Don't use toBe with floating-point numbers.




expect(result).toBe(42);
expect(status).toBe(true);


('<button>1</button>');

	// Remove the component from the DOM
	unmount(alias) unmount(component: Record<string, any>, options?: {
    outro?: boolean;
} | undefined): Promise<void>
import unmount

Unmounts a component that was previously mounted using mount or hydrate.




Since 5.13.0, if options.outro is true, transitions will play before the component is removed from the DOM.




Returns a Promise that resolves after transitions have completed if options.outro is true, or immediately otherwise (prior to 5.13.0, returns void).



import { mount, unmount } from 'svelte';
import App from './App.svelte';

const app = mount(App, { target: document.body });

// later...
unmount(app, { outro: true });
reference(componentconst component: {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<string, any>);
});
```

While the process is very straightforward, it is also low level and somewhat brittle, as the precise structure of your component may change frequently. Tools like [@testing-library/svelte](https://testing-library.com/docs/svelte-testing-library/intro/) can help streamline your tests. The above test could be rewritten like this:

component.test

```
import { render(alias) function render<C extends Component<any, any, string> | SvelteComponent<any, any, any>, Q extends Queries = typeof import(".pnpm/@testing-library+dom@10.4.1/node_modules/@testing-library/dom/types/queries")>(Component: ComponentImport<C>, options?: ComponentOptions<C>, renderOptions?: RenderOptions<Q>): RenderResult<C, Q>
import render

Render a component into the document.


{import('@testing-library/svelte-core/types').Component} 

C


{DomTestingLibrary.Queries} 

[Q=typeof DomTestingLibrary.queries]


Component 


The component to render.



options 


Customize how Svelte renders the component.



renderOptions 


Customize how Testing Library sets up the document and binds queries.





The rendered component and bound testing functions.


, screen(alias) const screen: Screen<typeof import(".pnpm/@testing-library+dom@10.4.1/node_modules/@testing-library/dom/types/queries")>
import screen } from '@testing-library/svelte';
import userEvent(alias) const userEvent: {
    readonly setup: typeof setupMain;
    readonly clear: typeof clear;
    readonly click: typeof click;
    readonly copy: typeof copy;
    readonly cut: typeof cut;
    readonly dblClick: typeof dblClick;
    readonly deselectOptions: typeof deselectOptions;
    readonly hover: typeof hover;
    readonly keyboard: typeof keyboard;
    ... 7 more ...;
    readonly tab: typeof tab;
}
import userEvent from '@testing-library/user-event';
import { expect(alias) const expect: ExpectStatic
import expect, test(alias) const test: TestAPI
import test

Defines a test case with a given name and test function. The test function can optionally be configured with test options.


name 


The name of the test or a function that will be used as a test name.



optionsOrFn 


Optional. The test options or the test function if no explicit name is provided.



optionsOrTest 


Optional. The test function or options, depending on the previous parameters.





{Error} If called inside another test function.



// Define a simple test
test('should add two numbers', () => {
  expect(add(1, 2)).toBe(3);
});
// Define a test with options
test('should subtract two numbers', { retry: 3 }, () => {
  expect(subtract(5, 2)).toBe(3);
});
 } from 'vitest';
import Component(alias) type Component = SvelteComponent<Record<string, any>, any, any>
(alias) const Component: LegacyComponentType
import Component from './Component.svelte';

test(alias) test<object>(name: string | Function, fn?: TestFunction<object> | undefined, options?: number): void (+1 overload)
import test

Defines a test case with a given name and test function. The test function can optionally be configured with test options.


name 


The name of the test or a function that will be used as a test name.



optionsOrFn 


Optional. The test options or the test function if no explicit name is provided.



optionsOrTest 


Optional. The test function or options, depending on the previous parameters.





{Error} If called inside another test function.



// Define a simple test
test('should add two numbers', () => {
  expect(add(1, 2)).toBe(3);
});
// Define a test with options
test('should subtract two numbers', { retry: 3 }, () => {
  expect(subtract(5, 2)).toBe(3);
});
('Component', async () => {
	const userconst user: UserEvent = userEvent(alias) const userEvent: {
    readonly setup: typeof setupMain;
    readonly clear: typeof clear;
    readonly click: typeof click;
    readonly copy: typeof copy;
    readonly cut: typeof cut;
    readonly dblClick: typeof dblClick;
    readonly deselectOptions: typeof deselectOptions;
    readonly hover: typeof hover;
    readonly keyboard: typeof keyboard;
    ... 7 more ...;
    readonly tab: typeof tab;
}
import userEvent.setup(property) setup: (options?: Options) => UserEvent

Start a "session" with userEvent.
All APIs returned by this function share an input device state and a default configuration.


();
	render(alias) render<SvelteComponent<Record<string, any>, any, any>, typeof import(".pnpm/@testing-library+dom@10.4.1/node_modules/@testing-library/dom/types/queries")>(Component: ComponentImport<SvelteComponent<Record<string, any>, any, any>>, options?: ComponentOptions<SvelteComponent<Record<string, any>, any, any>> | undefined, renderOptions?: RenderOptions<typeof import(".pnpm/@testing-library+dom@10.4.1/node_modules/@testing-library/dom/types/queries")> | undefined): RenderResult<...>
import render

Render a component into the document.


{import('@testing-library/svelte-core/types').Component} 

C


{DomTestingLibrary.Queries} 

[Q=typeof DomTestingLibrary.queries]


Component 


The component to render.



options 


Customize how Svelte renders the component.



renderOptions 


Customize how Testing Library sets up the document and binds queries.





The rendered component and bound testing functions.


(Component(alias) const Component: LegacyComponentType
import Component);

	const buttonconst button: HTMLElement = screen(alias) const screen: Screen<typeof import(".pnpm/@testing-library+dom@10.4.1/node_modules/@testing-library/dom/types/queries")>
import screen.getByRole(method) getByRole<HTMLElement>(role: ByRoleMatcher, options?: ByRoleOptions | undefined): HTMLElement (+1 overload)('button');
	expect(alias) expect<HTMLElement>(actual: HTMLElement, message?: string): Assertion<HTMLElement> (+1 overload)
import expect(buttonconst button: HTMLElement).toHaveTextContentany(0);

	await userconst user: UserEvent.click(property) click: (element: Element) => Promise<void>(buttonconst button: HTMLElement);
	expect(alias) expect<HTMLElement>(actual: HTMLElement, message?: string): Assertion<HTMLElement> (+1 overload)
import expect(buttonconst button: HTMLElement).toHaveTextContentany(1);
});
```

When writing component tests that involve two-way bindings, context or snippet props, it’s best to create a wrapper component for your specific test and interact with that. `@testing-library/svelte` contains some [examples](https://testing-library.com/docs/svelte-testing-library/example).

## Component tests with Storybook[](#Component-tests-with-Storybook)

[Storybook](https://storybook.js.org) is a tool for developing and documenting UI components, and it can also be used to test your components. They’re run with Vitest’s browser mode, which renders your components in a real browser for the most realistic testing environment.

To get started, first install Storybook ([using Svelte’s CLI](/docs/cli/storybook)) in your project via `npx sv add storybook` and choose the recommended configuration that includes testing features. If you’re already using Storybook, and for more information on Storybook’s testing capabilities, follow the [Storybook testing docs](https://storybook.js.org/docs/writing-tests?renderer=svelte) to get started.

You can create stories for component variations and test interactions with the [play function](https://storybook.js.org/docs/writing-tests/interaction-testing?renderer=svelte#writing-interaction-tests), which allows you to simulate behavior and make assertions using the Testing Library and Vitest APIs. Here’s an example of two stories that can be tested, one that renders an empty LoginForm component and one that simulates a user filling out the form:

LoginForm.stories

```
<script module>
	import { defineMeta } from '@storybook/addon-svelte-csf';
	import { expect, fn } from 'storybook/test';

	import LoginForm from './LoginForm.svelte';

	const { Story } = defineMeta({
		component: LoginForm,
		args: {
			// Pass a mock function to the `onSubmit` prop
			onSubmit: fn(),
		}
	});
</script>

<Story name="Empty Form" />

<Story
	name="Filled Form"
	play={async ({ args, canvas, userEvent }) => {
		// Simulate a user filling out the form
		await userEvent.type(canvas.getByTestId('email'), 'email@provider.com');
		await userEvent.type(canvas.getByTestId('password'), 'a-random-password');
		await userEvent.click(canvas.getByRole('button'));

		// Run assertions
		await expect(args.onSubmit).toHaveBeenCalledTimes(1);
		await expect(canvas.getByText('You’re in!')).toBeInTheDocument();
	}}
/>
```

## End-to-end tests with Playwright[](#End-to-end-tests-with-Playwright)

E2E (short for ‘end to end’) tests allow you to test your full application through the eyes of the user. This section uses [Playwright](https://playwright.dev/) as an example, but you can also use other solutions like [Cypress](https://www.cypress.io/) or [NightwatchJS](https://nightwatchjs.org/).

You can use the Svelte CLI to [setup Playwright](/docs/cli/playwright) either during project creation or later on. You can also [set it up with `npm init playwright`](https://playwright.dev/docs/intro). Additionally, you may also want to install an IDE plugin such as [the VS Code extension](https://playwright.dev/docs/getting-started-vscode) to be able to execute tests from inside your IDE.

If you’ve run `npm init playwright` or are not using Vite, you may need to adjust the Playwright config to tell Playwright what to do before running the tests — mainly starting your application at a certain port. For example:

playwright.config

```
const configconst config: {
    webServer: {
        command: string;
        port: number;
    };
    testDir: string;
    testMatch: RegExp;
} = {
	webServer(property) webServer: {
    command: string;
    port: number;
}: {
		command(property) command: string: 'npm run build && npm run preview',
		port(property) port: number: 4173
	},
	testDir(property) testDir: string: 'tests',
	testMatch(property) testMatch: RegExp: /(.+\.)?(test|spec)\.[jt]s/
};

export default configconst config: {
    webServer: {
        command: string;
        port: number;
    };
    testDir: string;
    testMatch: RegExp;
};
```

You can now start writing tests. These are totally unaware of Svelte as a framework, so you mainly interact with the DOM and write assertions.

tests/hello-world.spec

```
import { expectimport expect, testimport test } from '@playwright/test';

testimport test('home page has expected h1', async ({ page(parameter) page: any }) => {
	await page(parameter) page: any.gotoany('/');
	await expectimport expect(page(parameter) page: any.locatorany('h1')).toBeVisibleany();
});
```

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/07-misc/02-testing.md) [llms.txt](/docs/svelte/testing/llms.txt)

previous next

[Best practices](/docs/svelte/best-practices) [TypeScript](/docs/svelte/typescript)

----
url: https://svelte.dev/docs/svelte/svelte-compiler/llms.txt
----

````
```js
// @noErrors
import {
	VERSION,
	compile,
	compileModule,
	migrate,
	parse,
	parseCss,
	preprocess,
	print,
	walk
} from 'svelte/compiler';
```

## VERSION

The current version, as set in package.json.

<div class="ts-block">

```dts
const VERSION: string;
```

</div>



## compile

`compile` converts your `.svelte` source code into a JavaScript module that exports a component

<div class="ts-block">

```dts
function compile(
	source: string,
	options: CompileOptions
): CompileResult;
```

</div>



## compileModule

`compileModule` takes your JavaScript source code containing runes, and turns it into a JavaScript module.

<div class="ts-block">

```dts
function compileModule(
	source: string,
	options: ModuleCompileOptions
): CompileResult;
```

</div>



## migrate

Does a best-effort migration of Svelte code towards using runes, event attributes and render tags.
May throw an error if the code is too complex to migrate automatically.

<div class="ts-block">

```dts
function migrate(
	source: string,
	{
		filename,
		use_ts
	}?:
		| {
				filename?: string;
				use_ts?: boolean;
		  }
		| undefined
): {
	code: string;
};
```

</div>



## parse

The parse function parses a component, returning only its abstract syntax tree.

The `modern` option (`false` by default in Svelte 5) makes the parser return a modern AST instead of the legacy AST.
`modern` will become `true` by default in Svelte 6, and the option will be removed in Svelte 7.

<div class="ts-block">

```dts
function parse(
	source: string,
	options: {
		filename?: string;
		modern: true;
		loose?: boolean;
	}
): AST.Root;
```

</div>

<div class="ts-block">

```dts
function parse(
	source: string,
	options?:
		| {
				filename?: string;
				modern?: false;
				loose?: boolean;
		  }
		| undefined
): Record<string, any>;
```

</div>



## parseCss

The parseCss function parses a CSS stylesheet, returning its abstract syntax tree.

<div class="ts-block">

```dts
function parseCss(source: string): AST.CSS.StyleSheetFile;
```

</div>



## preprocess

The preprocess function provides convenient hooks for arbitrarily transforming component source code.
For example, it can be used to convert a `<style lang="sass">` block into vanilla CSS.

<div class="ts-block">

```dts
function preprocess(
	source: string,
	preprocessor: PreprocessorGroup | PreprocessorGroup[],
	options?:
		| {
				filename?: string;
		  }
		| undefined
): Promise<Processed>;
```

</div>



## print

`print` converts a Svelte AST node back into Svelte source code.
It is primarily intended for tools that parse and transform components using the compiler’s modern AST representation.

`print(ast)` requires an AST node produced by parse with modern: true, or any sub-node within that modern AST.
The result contains the generated source and a corresponding source map.
The output is valid Svelte, but formatting details such as whitespace or quoting may differ from the original.

<div class="ts-block">

```dts
function print(
	ast: AST.SvelteNode,
	options?: Options | undefined
): {
	code: string;
	map: any;
};
```

</div>



## walk

<blockquote class="tag deprecated note">

Replace this with `import { walk } from 'estree-walker'`

</blockquote>

<div class="ts-block">

```dts
function walk(): never;
```

</div>



## AST

<div class="ts-block">

```dts
namespace AST {
	export interface BaseNode {
		type: string;
		start: number;
		end: number;
	}

	export interface Fragment {
		type: 'Fragment';
		nodes: Array<
			Text | Tag | ElementLike | Block | Comment
		>;
	}

	export interface Root extends BaseNode {
		type: 'Root';
		/**
		 * Inline options provided by `<svelte:options>` — these override options passed to `compile(...)`
		 */
		options: SvelteOptions | null;
		fragment: Fragment;
		/** The parsed `<style>` element, if exists */
		css: AST.CSS.StyleSheet | null;
		/** The parsed `<script>` element, if exists */
		instance: Script | null;
		/** The parsed `<script module>` element, if exists */
		module: Script | null;
		/** Comments found in <script> and {expressions} */
		comments: JSComment[];
	}

	export interface SvelteOptions {
		// start/end info (needed for warnings and for our Prettier plugin)
		start: number;
		end: number;
		// options
		runes?: boolean;
		immutable?: boolean;
		accessors?: boolean;
		preserveWhitespace?: boolean;
		namespace?: Namespace;
		css?: 'injected';
		customElement?: {
			tag?: string;
			shadow?:
				| 'open'
				| 'none'
				| ObjectExpression
				| undefined;
			props?: Record<
				string,
				{
					attribute?: string;
					reflect?: boolean;
					type?:
						| 'Array'
						| 'Boolean'
						| 'Number'
						| 'Object'
						| 'String';
				}
			>;
			/**
			 * Is of type
			 * ```ts
			 * (ceClass: new () => HTMLElement) => new () => HTMLElement
			 * ```
			 */
			extend?: ArrowFunctionExpression | Identifier;
		};
		attributes: Attribute[];
	}

	/** Static text */
	export interface Text extends BaseNode {
		type: 'Text';
		/** Text with decoded HTML entities */
		data: string;
		/** The original text, with undecoded HTML entities */
		raw: string;
	}

	/** A (possibly reactive) template expression — `{...}` */
	export interface ExpressionTag extends BaseNode {
		type: 'ExpressionTag';
		expression: Expression;
	}

	/** A (possibly reactive) HTML template expression — `{@html ...}` */
	export interface HtmlTag extends BaseNode {
		type: 'HtmlTag';
		expression: Expression;
	}

	/** An HTML comment */
	// TODO rename to disambiguate
	export interface Comment extends BaseNode {
		type: 'Comment';
		/** the contents of the comment */
		data: string;
	}

	/** A `{@const ...}` tag */
	export interface ConstTag extends BaseNode {
		type: 'ConstTag';
		declaration: VariableDeclaration & {
			declarations: [
				VariableDeclarator & {
					id: Pattern;
					init: Expression;
				}
			];
		};
	}

	/** A `{let ...}` or `{const ...}` tag */
	export interface DeclarationTag extends BaseNode {
		type: 'DeclarationTag';
		declaration: VariableDeclaration;
	}

	/** A `{@debug ...}` tag */
	export interface DebugTag extends BaseNode {
		type: 'DebugTag';
		identifiers: Identifier[];
	}

	/** A `{@render foo(...)} tag */
	export interface RenderTag extends BaseNode {
		type: 'RenderTag';
		expression:
			| SimpleCallExpression
			| (ChainExpression & {
					expression: SimpleCallExpression;
			  });
	}

	/** A `{@attach foo(...)} tag */
	export interface AttachTag extends BaseNode {
		type: 'AttachTag';
		expression: Expression;
	}

	/** An `animate:` directive */
	export interface AnimateDirective extends BaseAttribute {
		type: 'AnimateDirective';
		/** The 'x' in `animate:x` */
		name: string;
		/** The y in `animate:x={y}` */
		expression: null | Expression;
	}

	/** A `bind:` directive */
	export interface BindDirective extends BaseAttribute {
		type: 'BindDirective';
		/** The 'x' in `bind:x` */
		name: string;
		/** The y in `bind:x={y}` */
		expression:
			| Identifier
			| MemberExpression
			| SequenceExpression;
	}

	/** A `class:` directive */
	export interface ClassDirective extends BaseAttribute {
		type: 'ClassDirective';
		/** The 'x' in `class:x` */
		name: 'class';
		/** The 'y' in `class:x={y}`, or the `x` in `class:x` */
		expression: Expression;
	}

	/** A `let:` directive */
	export interface LetDirective extends BaseAttribute {
		type: 'LetDirective';
		/** The 'x' in `let:x` */
		name: string;
		/** The 'y' in `let:x={y}` */
		expression:
			| null
			| Identifier
			| ArrayExpression
			| ObjectExpression;
	}

	/** An `on:` directive */
	export interface OnDirective extends BaseAttribute {
		type: 'OnDirective';
		/** The 'x' in `on:x` */
		name: string;
		/** The 'y' in `on:x={y}` */
		expression: null | Expression;
		modifiers: Array<
			| 'capture'
			| 'nonpassive'
			| 'once'
			| 'passive'
			| 'preventDefault'
			| 'self'
			| 'stopImmediatePropagation'
			| 'stopPropagation'
			| 'trusted'
		>;
	}

	/** A `style:` directive */
	export interface StyleDirective extends BaseAttribute {
		type: 'StyleDirective';
		/** The 'x' in `style:x` */
		name: string;
		/** The 'y' in `style:x={y}` */
		value:
			| true
			| ExpressionTag
			| Array<ExpressionTag | Text>;
		modifiers: Array<'important'>;
	}

	// TODO have separate in/out/transition directives
	/** A `transition:`, `in:` or `out:` directive */
	export interface TransitionDirective extends BaseAttribute {
		type: 'TransitionDirective';
		/** The 'x' in `transition:x` */
		name: string;
		/** The 'y' in `transition:x={y}` */
		expression: null | Expression;
		modifiers: Array<'local' | 'global'>;
		/** True if this is a `transition:` or `in:` directive */
		intro: boolean;
		/** True if this is a `transition:` or `out:` directive */
		outro: boolean;
	}

	/** A `use:` directive */
	export interface UseDirective extends BaseAttribute {
		type: 'UseDirective';
		/** The 'x' in `use:x` */
		name: string;
		/** The 'y' in `use:x={y}` */
		expression: null | Expression;
	}

	export interface BaseElement extends BaseNode {
		name: string;
		name_loc: SourceLocation;
		attributes: Array<
			Attribute | SpreadAttribute | Directive | AttachTag
		>;
		fragment: Fragment;
	}

	export interface Component extends BaseElement {
		type: 'Component';
	}

	export interface TitleElement extends BaseElement {
		type: 'TitleElement';
		name: 'title';
	}

	export interface SlotElement extends BaseElement {
		type: 'SlotElement';
		name: 'slot';
	}

	export interface RegularElement extends BaseElement {
		type: 'RegularElement';
	}

	export interface SvelteBody extends BaseElement {
		type: 'SvelteBody';
		name: 'svelte:body';
	}

	export interface SvelteComponent extends BaseElement {
		type: 'SvelteComponent';
		name: 'svelte:component';
		expression: Expression;
	}

	export interface SvelteDocument extends BaseElement {
		type: 'SvelteDocument';
		name: 'svelte:document';
	}

	export interface SvelteElement extends BaseElement {
		type: 'SvelteElement';
		name: 'svelte:element';
		tag: Expression;
	}

	export interface SvelteFragment extends BaseElement {
		type: 'SvelteFragment';
		name: 'svelte:fragment';
	}

	export interface SvelteBoundary extends BaseElement {
		type: 'SvelteBoundary';
		name: 'svelte:boundary';
	}

	export interface SvelteHead extends BaseElement {
		type: 'SvelteHead';
		name: 'svelte:head';
	}

	/** This is only an intermediate representation while parsing, it doesn't exist in the final AST */
	export interface SvelteOptionsRaw extends BaseElement {
		type: 'SvelteOptions';
		name: 'svelte:options';
	}

	export interface SvelteSelf extends BaseElement {
		type: 'SvelteSelf';
		name: 'svelte:self';
	}

	export interface SvelteWindow extends BaseElement {
		type: 'SvelteWindow';
		name: 'svelte:window';
	}

	/** An `{#each ...}` block */
	export interface EachBlock extends BaseNode {
		type: 'EachBlock';
		expression: Expression;
		/** The `entry` in `{#each item as entry}`. `null` if `as` part is omitted */
		context: Pattern | null;
		body: Fragment;
		fallback?: Fragment;
		index?: string;
		key?: Expression;
	}

	/** An `{#if ...}` block */
	export interface IfBlock extends BaseNode {
		type: 'IfBlock';
		elseif: boolean;
		test: Expression;
		consequent: Fragment;
		alternate: Fragment | null;
	}

	/** An `{#await ...}` block */
	export interface AwaitBlock extends BaseNode {
		type: 'AwaitBlock';
		expression: Expression;
		// TODO can/should we move these inside the ThenBlock and CatchBlock?
		/** The resolved value inside the `then` block */
		value: Pattern | null;
		/** The rejection reason inside the `catch` block */
		error: Pattern | null;
		pending: Fragment | null;
		then: Fragment | null;
		catch: Fragment | null;
	}

	export interface KeyBlock extends BaseNode {
		type: 'KeyBlock';
		expression: Expression;
		fragment: Fragment;
	}

	export interface SnippetBlock extends BaseNode {
		type: 'SnippetBlock';
		expression: Identifier;
		parameters: Pattern[];
		typeParams?: string;
		body: Fragment;
	}

	export interface BaseAttribute extends BaseNode {
		name: string;
		name_loc: SourceLocation | null;
	}

	export interface Attribute extends BaseAttribute {
		type: 'Attribute';
		/**
		 * Quoted/string values are represented by an array, even if they contain a single expression like `"{x}"`
		 */
		value:
			| true
			| ExpressionTag
			| Array<Text | ExpressionTag>;
	}

	export interface SpreadAttribute extends BaseNode {
		type: 'SpreadAttribute';
		expression: Expression;
	}

	export interface Script extends BaseNode {
		type: 'Script';
		context: 'default' | 'module';
		content: Program;
		attributes: Attribute[];
	}

	export interface JSComment {
		type: 'Line' | 'Block';
		value: string;
		start: number;
		end: number;
		loc: {
			start: { line: number; column: number };
			end: { line: number; column: number };
		};
	}

	export type AttributeLike =
		| Attribute
		| SpreadAttribute
		| Directive;

	export type Directive =
		| AST.AnimateDirective
		| AST.BindDirective
		| AST.ClassDirective
		| AST.LetDirective
		| AST.OnDirective
		| AST.StyleDirective
		| AST.TransitionDirective
		| AST.UseDirective;

	export type Block =
		| AST.EachBlock
		| AST.IfBlock
		| AST.AwaitBlock
		| AST.KeyBlock
		| AST.SnippetBlock;

	export type ElementLike =
		| AST.Component
		| AST.TitleElement
		| AST.SlotElement
		| AST.RegularElement
		| AST.SvelteBody
		| AST.SvelteBoundary
		| AST.SvelteComponent
		| AST.SvelteDocument
		| AST.SvelteElement
		| AST.SvelteFragment
		| AST.SvelteHead
		| AST.SvelteOptionsRaw
		| AST.SvelteSelf
		| AST.SvelteWindow
		| AST.SvelteBoundary;

	export type Tag =
		| AST.AttachTag
		| AST.ConstTag
		| AST.DeclarationTag
		| AST.DebugTag
		| AST.ExpressionTag
		| AST.HtmlTag
		| AST.RenderTag;

	export type TemplateNode =
		| AST.Root
		| AST.Text
		| Tag
		| ElementLike
		| AST.Attribute
		| AST.SpreadAttribute
		| Directive
		| AST.AttachTag
		| AST.Comment
		| Block;

	export type SvelteNode =
		| Node
		| TemplateNode
		| AST.Fragment
		| _CSS.Node
		| Script;

	export type { _CSS as CSS };
}
```

</div>

## CompileError

<div class="ts-block">

```dts
interface CompileError extends ICompileDiagnostic {}
```

</div>

## CompileOptions

<div class="ts-block">

```dts
interface CompileOptions extends ModuleCompileOptions {/*…*/}
```

<div class="ts-block-property">

```dts
name?: string;
```

<div class="ts-block-property-details">

Sets the name of the resulting JavaScript class (though the compiler will rename it if it would otherwise conflict with other variables in scope).
If unspecified, will be inferred from `filename`

</div>
</div>

<div class="ts-block-property">

```dts
customElement?: boolean | ((options: { filename: string }) => boolean);
```

<div class="ts-block-property-details">

<div class="ts-block-property-bullets">

- <span class="tag">default</span> `false`

</div>

If `true`, tells the compiler to generate a custom element constructor instead of a regular Svelte component.

You can also pass a function that receives `{ filename }` and returns a boolean.

</div>
</div>

<div class="ts-block-property">

```dts
accessors?: boolean;
```

<div class="ts-block-property-details">

<div class="ts-block-property-bullets">

- <span class="tag">default</span> `false`
- <span class="tag deprecated">deprecated</span> This will have no effect in runes mode

</div>

If `true`, getters and setters will be created for the component's props. If `false`, they will only be created for readonly exported values (i.e. those declared with `const`, `class` and `function`). If compiling with `customElement: true` this option defaults to `true`.

</div>
</div>

<div class="ts-block-property">

```dts
namespace?: Namespace;
```

<div class="ts-block-property-details">

<div class="ts-block-property-bullets">

- <span class="tag">default</span> `'html'`

</div>

The namespace of the element; e.g., `"html"`, `"svg"`, `"mathml"`.

</div>
</div>

<div class="ts-block-property">

```dts
immutable?: boolean;
```

<div class="ts-block-property-details">

<div class="ts-block-property-bullets">

- <span class="tag">default</span> `false`
- <span class="tag deprecated">deprecated</span> This will have no effect in runes mode

</div>

If `true`, tells the compiler that you promise not to mutate any objects.
This allows it to be less conservative about checking whether values have changed.

</div>
</div>

<div class="ts-block-property">

```dts
css?: 'injected' | 'external' | ((options: { filename: string }) => 'injected' | 'external');
```

<div class="ts-block-property-details">

- `'injected'`: styles will be included in the `head` when using `render(...)`, and injected into the document (if not already present) when the component mounts. For components compiled as custom elements, styles are injected to the shadow root.
- `'external'`: the CSS will only be returned in the `css` field of the compilation result. Most Svelte bundler plugins will set this to `'external'` and use the CSS that is statically generated for better performance, as it will result in smaller JavaScript bundles and the output can be served as cacheable `.css` files.
This is always `'injected'` when compiling with `customElement` mode.

You can also pass a function that receives `{ filename }` and returns either `'injected'` or `'external'`.

</div>
</div>

<div class="ts-block-property">

```dts
cssHash?: CssHashGetter;
```

<div class="ts-block-property-details">

<div class="ts-block-property-bullets">

- <span class="tag">default</span> `undefined`

</div>

A function that takes a `{ hash, css, name, filename }` argument and returns the string that is used as a classname for scoped CSS.
It defaults to returning `svelte-${hash(filename ?? css)}`.

</div>
</div>

<div class="ts-block-property">

```dts
preserveComments?: boolean;
```

<div class="ts-block-property-details">

<div class="ts-block-property-bullets">

- <span class="tag">default</span> `false`

</div>

If `true`, your HTML comments will be preserved in the output. By default, they are stripped out.

</div>
</div>

<div class="ts-block-property">

```dts
preserveWhitespace?: boolean;
```

<div class="ts-block-property-details">

<div class="ts-block-property-bullets">

- <span class="tag">default</span> `false`

</div>

If `true`, whitespace inside and between elements is kept as you typed it, rather than removed or collapsed to a single space where possible.

</div>
</div>

<div class="ts-block-property">

```dts
fragments?: 'html' | 'tree';
```

<div class="ts-block-property-details">

<div class="ts-block-property-bullets">

- <span class="tag">default</span> `'html'`
- <span class="tag since">available since</span> v5.33

</div>

Which strategy to use when cloning DOM fragments:

- `html` populates a `<template>` with `innerHTML` and clones it. This is faster, but cannot be used if your app's [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP) includes [`require-trusted-types-for 'script'`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy/require-trusted-types-for)
- `tree` creates the fragment one element at a time and _then_ clones it. This is slower, but works everywhere

</div>
</div>

<div class="ts-block-property">

```dts
runes?: boolean | undefined | ((options: { filename: string }) => boolean | undefined);
```

<div class="ts-block-property-details">

<div class="ts-block-property-bullets">

- <span class="tag">default</span> `undefined`

</div>

Set to `true` to force the compiler into runes mode, even if there are no indications of runes usage.
Set to `false` to force the compiler into ignoring runes, even if there are indications of runes usage.
Set to `undefined` (the default) to infer runes mode from the component code.
Is always `true` for JS/TS modules compiled with Svelte.
Will be `true` by default in Svelte 6.
Note that setting this to `true` in your `svelte.config.js` will force runes mode for your entire project, including components in `node_modules`,
which is likely not what you want. If you're using Vite, consider using [dynamicCompileOptions](https://github.com/sveltejs/vite-plugin-svelte/blob/main/docs/config.md#dynamiccompileoptions) instead.

</div>
</div>

<div class="ts-block-property">

```dts
discloseVersion?: boolean;
```

<div class="ts-block-property-details">

<div class="ts-block-property-bullets">

- <span class="tag">default</span> `true`

</div>

If `true`, exposes the Svelte major version in the browser by adding it to a `Set` stored in the global `window.__svelte.v`.

</div>
</div>

<div class="ts-block-property">

```dts
compatibility?: {/*…*/};
```

<div class="ts-block-property-details">

<div class="ts-block-property-bullets">

- <span class="tag deprecated">deprecated</span> Use these only as a temporary solution before migrating your code

</div>

<div class="ts-block-property-children"><div class="ts-block-property">

```dts
componentApi?: 4 | 5;
```

<div class="ts-block-property-details">

<div class="ts-block-property-bullets">

- <span class="tag">default</span> `5`

</div>

Applies a transformation so that the default export of Svelte files can still be instantiated the same way as in Svelte 4 —
as a class when compiling for the browser (as though using `createClassComponent(MyComponent, {...})` from `svelte/legacy`)
or as an object with a `.render(...)` method when compiling for the server

</div>
</div></div>

</div>
</div>

<div class="ts-block-property">

```dts
sourcemap?: object | string;
```

<div class="ts-block-property-details">

<div class="ts-block-property-bullets">

- <span class="tag">default</span> `null`

</div>

An initial sourcemap that will be merged into the final output sourcemap.
This is usually the preprocessor sourcemap.

</div>
</div>

<div class="ts-block-property">

```dts
outputFilename?: string;
```

<div class="ts-block-property-details">

<div class="ts-block-property-bullets">

- <span class="tag">default</span> `null`

</div>

Used for your JavaScript sourcemap.

</div>
</div>

<div class="ts-block-property">

```dts
cssOutputFilename?: string;
```

<div class="ts-block-property-details">

<div class="ts-block-property-bullets">

- <span class="tag">default</span> `null`

</div>

Used for your CSS sourcemap.

</div>
</div>

<div class="ts-block-property">

```dts
hmr?: boolean;
```

<div class="ts-block-property-details">

<div class="ts-block-property-bullets">

- <span class="tag">default</span> `false`

</div>

If `true`, compiles components with hot reloading support.

</div>
</div>

<div class="ts-block-property">

```dts
modernAst?: boolean;
```

<div class="ts-block-property-details">

<div class="ts-block-property-bullets">

- <span class="tag">default</span> `false`

</div>

If `true`, returns the modern version of the AST.
Will become `true` by default in Svelte 6, and the option will be removed in Svelte 7.

</div>
</div></div>

## CompileResult

The return value of `compile` from `svelte/compiler`

<div class="ts-block">

```dts
interface CompileResult {/*…*/}
```

<div class="ts-block-property">

```dts
js: {/*…*/};
```

<div class="ts-block-property-details">

The compiled JavaScript

<div class="ts-block-property-children"><div class="ts-block-property">

```dts
code: string;
```

<div class="ts-block-property-details">

The generated code

</div>
</div>
<div class="ts-block-property">

```dts
map: SourceMap;
```

<div class="ts-block-property-details">

A source map

</div>
</div></div>

</div>
</div>

<div class="ts-block-property">

```dts
css: null | {/*…*/};
```

<div class="ts-block-property-details">

The compiled CSS

<div class="ts-block-property-children"><div class="ts-block-property">

```dts
code: string;
```

<div class="ts-block-property-details">

The generated code

</div>
</div>
<div class="ts-block-property">

```dts
map: SourceMap;
```

<div class="ts-block-property-details">

A source map

</div>
</div>
<div class="ts-block-property">

```dts
hasGlobal: boolean;
```

<div class="ts-block-property-details">

Whether or not the CSS includes global rules

</div>
</div></div>

</div>
</div>

<div class="ts-block-property">

```dts
warnings: Warning[];
```

<div class="ts-block-property-details">

An array of warning objects that were generated during compilation. Each warning has several properties:
- `code` is a string identifying the category of warning
- `message` describes the issue in human-readable terms
- `start` and `end`, if the warning relates to a specific location, are objects with `line`, `column` and `character` properties

</div>
</div>

<div class="ts-block-property">

```dts
metadata: {/*…*/};
```

<div class="ts-block-property-details">

Metadata about the compiled component

<div class="ts-block-property-children"><div class="ts-block-property">

```dts
runes: boolean;
```

<div class="ts-block-property-details">

Whether the file was compiled in runes mode, either because of an explicit option or inferred from usage.
For `compileModule`, this is always `true`

</div>
</div></div>

</div>
</div>

<div class="ts-block-property">

```dts
ast: any;
```

<div class="ts-block-property-details">

The AST

</div>
</div></div>

## MarkupPreprocessor

A markup preprocessor that takes a string of code and returns a processed version.

<div class="ts-block">

```dts
type MarkupPreprocessor = (options: {
	/**
	 * The whole Svelte file content
	 */
	content: string;
	/**
	 * The filename of the Svelte file
	 */
	filename?: string;
}) => Processed | void | Promise<Processed | void>;
```

</div>

## ModuleCompileOptions

<div class="ts-block">

```dts
interface ModuleCompileOptions {/*…*/}
```

<div class="ts-block-property">

```dts
dev?: boolean;
```

<div class="ts-block-property-details">

<div class="ts-block-property-bullets">

- <span class="tag">default</span> `false`

</div>

If `true`, causes extra code to be added that will perform runtime checks and provide debugging information during development.

</div>
</div>

<div class="ts-block-property">

```dts
generate?: 'client' | 'server' | false;
```

<div class="ts-block-property-details">

<div class="ts-block-property-bullets">

- <span class="tag">default</span> `'client'`

</div>

If `"client"`, Svelte emits code designed to run in the browser.
If `"server"`, Svelte emits code suitable for server-side rendering.
If `false`, nothing is generated. Useful for tooling that is only interested in warnings.

</div>
</div>

<div class="ts-block-property">

```dts
filename?: string;
```

<div class="ts-block-property-details">

Used for debugging hints and sourcemaps. Your bundler plugin will set it automatically.

</div>
</div>

<div class="ts-block-property">

```dts
rootDir?: string;
```

<div class="ts-block-property-details">

<div class="ts-block-property-bullets">

- <span class="tag">default</span> `process.cwd() on node-like environments, undefined elsewhere`

</div>

Used for ensuring filenames don't leak filesystem information. Your bundler plugin will set it automatically.

</div>
</div>

<div class="ts-block-property">

```dts
warningFilter?: (warning: Warning) => boolean;
```

<div class="ts-block-property-details">

A function that gets a `Warning` as an argument and returns a boolean.
Use this to filter out warnings. Return `true` to keep the warning, `false` to discard it.

</div>
</div>

<div class="ts-block-property">

```dts
experimental?: {/*…*/};
```

<div class="ts-block-property-details">

<div class="ts-block-property-bullets">

- <span class="tag since">available since</span> v5.36

</div>

Experimental options

<div class="ts-block-property-children"><div class="ts-block-property">

```dts
async?: boolean;
```

<div class="ts-block-property-details">

<div class="ts-block-property-bullets">

- <span class="tag since">available since</span> v5.36

</div>

Allow `await` keyword in deriveds, template expressions, and the top level of components

</div>
</div></div>

</div>
</div></div>

## Preprocessor

A script/style preprocessor that takes a string of code and returns a processed version.

<div class="ts-block">

```dts
type Preprocessor = (options: {
	/**
	 * The script/style tag content
	 */
	content: string;
	/**
	 * The attributes on the script/style tag
	 */
	attributes: Record<string, string | boolean>;
	/**
	 * The whole Svelte file content
	 */
	markup: string;
	/**
	 * The filename of the Svelte file
	 */
	filename?: string;
}) => Processed | void | Promise<Processed | void>;
```

</div>

## PreprocessorGroup

A preprocessor group is a set of preprocessors that are applied to a Svelte file.

<div class="ts-block">

```dts
interface PreprocessorGroup {/*…*/}
```

<div class="ts-block-property">

```dts
name?: string;
```

<div class="ts-block-property-details">

Name of the preprocessor. Will be a required option in the next major version

</div>
</div>

<div class="ts-block-property">

```dts
markup?: MarkupPreprocessor;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
style?: Preprocessor;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
script?: Preprocessor;
```

<div class="ts-block-property-details"></div>
</div></div>

## Processed

The result of a preprocessor run. If the preprocessor does not return a result, it is assumed that the code is unchanged.

<div class="ts-block">

```dts
interface Processed {/*…*/}
```

<div class="ts-block-property">

```dts
code: string;
```

<div class="ts-block-property-details">

The new code

</div>
</div>

<div class="ts-block-property">

```dts
map?: string | object;
```

<div class="ts-block-property-details">

A source map mapping back to the original code

</div>
</div>

<div class="ts-block-property">

```dts
dependencies?: string[];
```

<div class="ts-block-property-details">

A list of additional files to watch for changes

</div>
</div>

<div class="ts-block-property">

```dts
attributes?: Record<string, string | boolean>;
```

<div class="ts-block-property-details">

Only for script/style preprocessors: The updated attributes to set on the tag. If undefined, attributes stay unchanged.

</div>
</div>

<div class="ts-block-property">

```dts
toString?: () => string;
```

<div class="ts-block-property-details"></div>
</div></div>

## Warning

<div class="ts-block">

```dts
interface Warning extends ICompileDiagnostic {}
```

</div>
````

----
url: https://svelte.dev/docs/svelte/snippet/llms.txt
----

````
```svelte
<!--- copy: false  --->
{#snippet name()}...{/snippet}
```

```svelte
<!--- copy: false  --->
{#snippet name(param1, param2, paramN)}...{/snippet}
```

Snippets, and [render tags](@render), are a way to create reusable chunks of markup inside your components. Instead of writing duplicative code like this...

```svelte
{#each images as image}
	{#if image.href}
		<a href={image.href}>
			<figure>
				<img src={image.src} alt={image.caption} width={image.width} height={image.height} />
				<figcaption>{image.caption}</figcaption>
			</figure>
		</a>
	{:else}
		<figure>
			<img src={image.src} alt={image.caption} width={image.width} height={image.height} />
			<figcaption>{image.caption}</figcaption>
		</figure>
	{/if}
{/each}
```

...you can write this:

```svelte
{#snippet figure(image)}
	<figure>
		<img src={image.src} alt={image.caption} width={image.width} height={image.height} />
		<figcaption>{image.caption}</figcaption>
	</figure>
{/snippet}

{#each images as image}
	{#if image.href}
		<a href={image.href}>
			{@render figure(image)}
		</a>
	{:else}
		{@render figure(image)}
	{/if}
{/each}
```

Like function declarations, snippets can have an arbitrary number of parameters, which can have default values, and you can destructure each parameter. You cannot use rest parameters, however.

## Snippet scope

Snippets can be declared anywhere inside your component. They can reference values declared outside themselves, for example in the `<script>` tag or in `{#each ...}` blocks...

<!-- codeblock:start {"title":"Snippets"} -->
```svelte
<!--- file: App.svelte --->
<script>
	let { message = `it's great to see you!` } = $props();
</script>

{#snippet hello(name)}
	<p>hello {name}! {message}!</p>
{/snippet}

{@render hello('alice')}
{@render hello('bob')}
```
<!-- codeblock:end -->

...and they are 'visible' to everything in the same lexical scope (i.e. siblings, and children of those siblings):

```svelte
<div>
	{#snippet x()}
		{#snippet y()}...{/snippet}

		<!-- this is fine -->
		{@render y()}
	{/snippet}

	<!-- this will error, as `y` is not in scope -->
	{@render y()}
</div>

<!-- this will also error, as `x` is not in scope -->
{@render x()}
```

Snippets can reference themselves and each other:

<!-- codeblock:start {"title":"Self-referencing snippets"} -->
```svelte
<!--- file: App.svelte --->
{#snippet blastoff()}
	<span>🚀</span>
{/snippet}

{#snippet countdown(n)}
	{#if n > 0}
		<span>{n}...</span>
		{@render countdown(n - 1)}
	{:else}
		{@render blastoff()}
	{/if}
{/snippet}

{@render countdown(10)}
```
<!-- codeblock:end -->

## Passing snippets to components

### Explicit props

Within the template, snippets are values just like any other. As such, they can be passed to components as props:

<!-- codeblock:start {"title":"Explicit snippet props"} -->
```svelte
<!--- file: App.svelte --->
<script>
	import Table from './Table.svelte';

	const fruits = [
		{ name: 'apples', qty: 5, price: 2 },
		{ name: 'bananas', qty: 10, price: 1 },
		{ name: 'cherries', qty: 20, price: 0.5 }
	];
</script>

{#snippet header()}
	<th>fruit</th>
	<th>qty</th>
	<th>price</th>
	<th>total</th>
{/snippet}

{#snippet row(d)}
	<td>{d.name}</td>
	<td>{d.qty}</td>
	<td>{d.price}</td>
	<td>{d.qty * d.price}</td>
{/snippet}

<Table data={fruits} +++{header} {row}+++ />
```

```svelte
<!--- file: Table.svelte --->
<script>
	let { data, header, row } = $props();
</script>

<table>
	{#if header}
		<thead>
			<tr>{@render header()}</tr>
		</thead>
	{/if}

	<tbody>
		{#each data as d}
			<tr>{@render row(d)}</tr>
		{/each}
	</tbody>
</table>

<style>
	table {
		text-align: left;
		border-spacing: 0;
	}

	tbody tr:nth-child(2n+1) {
		background: ButtonFace;
	}

	table :global(th), table :global(td) {
		padding: 0.5em;
	}
</style>
```
<!-- codeblock:end -->

Think about it like passing content instead of data to a component. The concept is similar to slots in web components.

### Implicit props

As an authoring convenience, snippets declared directly _inside_ a component implicitly become props _on_ the component:

<!-- codeblock:start {"title":"Implicit snippet props"} -->
```svelte
<!--- file: App.svelte --->
<script>
	import Table from './Table.svelte';

	const fruits = [
		{ name: 'apples', qty: 5, price: 2 },
		{ name: 'bananas', qty: 10, price: 1 },
		{ name: 'cherries', qty: 20, price: 0.5 }
	];
</script>

<Table data={fruits}>
	{#snippet header()}
		<th>fruit</th>
		<th>qty</th>
		<th>price</th>
		<th>total</th>
	{/snippet}

	{#snippet row(d)}
		<td>{d.name}</td>
		<td>{d.qty}</td>
		<td>{d.price}</td>
		<td>{d.qty * d.price}</td>
	{/snippet}
</Table>
```

```svelte
<!--- file: Table.svelte --->
<script>
	let { data, header, row } = $props();
</script>

<table>
	{#if header}
		<thead>
			<tr>{@render header()}</tr>
		</thead>
	{/if}

	<tbody>
		{#each data as d}
			<tr>{@render row(d)}</tr>
		{/each}
	</tbody>
</table>

<style>
	table {
		text-align: left;
		border-spacing: 0;
	}

	tbody tr:nth-child(2n+1) {
		background: ButtonFace;
	}

	table :global(th), table :global(td) {
		padding: 0.5em;
	}
</style>
```
<!-- codeblock:end -->

### Implicit `children` snippet

Any content inside the component tags that is _not_ a snippet declaration implicitly becomes part of the `children` snippet:

<!-- codeblock:start {"title":"Implicit children snippet","selected":"Button.svelte"} -->
```svelte
<!--- file: App.svelte --->
<script>
	import Button from './Button.svelte';
</script>

<Button>click me</Button>
```

```svelte
<!--- file: Button.svelte --->
<script>
	let { children } = $props();
</script>

<!-- result will be <button>click me</button> -->
<button>{@render children()}</button>
```
<!-- codeblock:end -->

> [!NOTE] Note that you cannot have a prop called `children` if you also have content inside the component — for this reason, you should avoid having props with that name

### Optional snippet props

You can declare snippet props as being optional. You can either use optional chaining to not render anything if the snippet isn't set...

```svelte
<script>
    let { children } = $props();
</script>

{@render children?.()}
```

...or use an `#if` block to render fallback content:

```svelte
<script>
    let { children } = $props();
</script>

{#if children}
    {@render children()}
{:else}
    fallback content
{/if}
```

## Typing snippets

Snippets implement the `Snippet` interface imported from `'svelte'`:

```svelte
<script lang="ts">
	import type { Snippet } from 'svelte';

	interface Props {
		data: any[];
		children: Snippet;
		row: Snippet<[any]>;
	}

	let { data, children, row }: Props = $props();
</script>
```

With this change, red squigglies will appear if you try and use the component without providing a `data` prop and a `row` snippet. Notice that the type argument provided to `Snippet` is a tuple, since snippets can have multiple parameters.

We can tighten things up further by declaring a generic, so that `data` and `row` refer to the same type:

```svelte
<script lang="ts" generics="T">
	import type { Snippet } from 'svelte';

	let {
		data,
		children,
		row
	}: {
		data: T[];
		children: Snippet;
		row: Snippet<[T]>;
	} = $props();
</script>
```

## Exporting snippets

Snippets declared at the top level of a `.svelte` file can be exported from a `<script module>` for use in other components, provided they don't reference any declarations in a non-module `<script>` (whether directly or indirectly, via other snippets):

<!-- codeblock:start {"title":"Exported snippets","selected":"snippets.svelte"} -->
```svelte
<!--- file: App.svelte --->
<script>
	import { add } from './snippets.svelte';
</script>

{@render add(1, 2)}

```

```svelte
<!--- file: snippets.svelte --->
<script module>
	export { add };
</script>

{#snippet add(a, b)}
	{a} + {b} = {a + b}
{/snippet}
```
<!-- codeblock:end -->

> [!NOTE]
> This requires Svelte 5.5.0 or newer

## Programmatic snippets

Snippets can be created programmatically with the [`createRawSnippet`](svelte#createRawSnippet) API. This is intended for advanced use cases.

## Snippets and slots

In Svelte 4, content can be passed to components using [slots](legacy-slots). Snippets are more powerful and flexible, and so slots have been deprecated in Svelte 5.
````

----
url: https://svelte.dev/docs/svelte/legacy-slots
----

[Skip to main content](#main)

In Svelte 5, content can be passed to components in the form of [snippets](snippet) and rendered using [render tags](@render).

In legacy mode, content inside component tags is considered *slotted content*, which can be rendered by the component using a `<slot>` element:

App

```
<script>
	import Modal from './Modal.svelte';
</script>

<Modal>This is some slotted content</Modal>
```

```
<script lang="ts">
	import Modal from './Modal.svelte';
</script>

<Modal>This is some slotted content</Modal>
```

Modal

```
<div class="modal">
	<slot></slot>
</div>
```

> If you want to render a regular `<slot>` element, you can use `<svelte:element this={'slot'} />`.

## Named slots[](#Named-slots)

A component can have *named* slots in addition to the default slot. On the parent side, add a `slot="..."` attribute to an element, component or [`<svelte:fragment>`](legacy-svelte-fragment) directly inside the component tags.

App

```
<script>
	import Modal from './Modal.svelte';

	let open = true;
</script>

{#if open}
	<Modal>
		This is some slotted content

		<div slot="buttons">
			<button on:click={() => open = false}>
				close
			</button>
		</div>
	</Modal>
{/if}
```

```
<script lang="ts">
	import Modal from './Modal.svelte';

	let open = true;
</script>

{#if open}
	<Modal>
		This is some slotted content

		<div slot="buttons">
			<button on:click={() => open = false}>
				close
			</button>
		</div>
	</Modal>
{/if}
```

On the child side, add a corresponding `<slot name="...">` element:

Modal

```
<div class="modal">
	<slot></slot>
	<hr>
	<slot name="buttons"></slot>
</div>
```

## Fallback content[](#Fallback-content)

If no slotted content is provided, a component can define fallback content by putting it inside the `<slot>` element:

```
<slot>
	This will be rendered if no slotted content is provided
</slot>
```

## Passing data to slotted content[](#Passing-data-to-slotted-content)

Slots can be rendered zero or more times and can pass values *back* to the parent using props. The parent exposes the values to the slot template using the `let:` directive.

FancyList

```
<ul>
	{#each items as data}
		<li class="fancy">
			<!-- 'item' here... -->
			<slot item={process(data)} />
		</li>
	{/each}
</ul>
```

App

```
<!-- ...corresponds to 'item' here: -->
<FancyList {items} let:item={processed}>
	<div>{processed.text}</div>
</FancyList>
```

The usual shorthand rules apply — `let:item` is equivalent to `let:item={item}`, and `<slot {item}>` is equivalent to `<slot item={item}>`.

Named slots can also expose values. The `let:` directive goes on the element with the `slot` attribute.

FancyList

```
<ul>
	{#each items as item}
		<li class="fancy">
			<slot name="item" item={process(data)} />
		</li>
	{/each}
</ul>

<slot name="footer" />
```

App

```
<FancyList {items}>
	<div slot="item" let:item>{item.text}</div>
	<p slot="footer">Copyright (c) 2019 Svelte Industries</p>
</FancyList>
```

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/99-legacy/20-legacy-slots.md) [llms.txt](/docs/svelte/legacy-slots/llms.txt)

previous next

[on:](/docs/svelte/legacy-on) [$$slots](/docs/svelte/legacy-$$slots)

----
url: https://svelte.dev/docs/svelte/svelte-boundary
----

[Skip to main content](#main)

```
<svelte:boundary onerror={handler}>...</svelte:boundary>
```

> This feature was added in 5.3.0

Boundaries allow you to ‘wall off’ parts of your app, so that you can:

* provide UI that should be shown when [`await`](await-expressions) expressions are first resolving
* handle errors that occur during rendering or while running effects, and provide UI that should be rendered when an error happens

If a boundary handles an error (with a `failed` snippet or `onerror` handler, or both) its existing content will be removed.

> Errors occurring outside the rendering process (for example, in event handlers or after a `setTimeout` or async work) are *not* caught by error boundaries.

## Properties[](#Properties)

For the boundary to do anything, one or more of the following must be provided.

### pending[](#Properties-pending)

This snippet will be shown when the boundary is first created, and will remain visible until all the [`await`](await-expressions) expressions inside the boundary have resolved ([demo](/playground/untitled#H4sIAAAAAAAAE21QQW6DQAz8ytY9BKQVpFdKkPqDHnorPWzAaSwt3tWugUaIv1eE0KpKD5as8YxnNBOw6RAKKOOAVrA4up5bEy6VGknOyiO3xJ8qMnmPAhpOZDFC8T6BXPyiXADQ258X77P1FWg4moj_4Y1jQZZ49W0CealqruXUcyPkWLVozQXbZDC2R606spYiNo7bqA7qab_fp2paFLUElD6wYhzVa3AdRUySgNHZAVN1qDZaLRHljTp0vSTJ9XJjrSbpX5f0eZXN6zLXXOa_QfmurIVU-moyoyH5ib87o7XuYZfOZe6vnGWmx1uZW7lJOq9upa-sMwuUZdkmmfIbfQ1xZwwaBL8ECgk9zh8axJAdiVsoTsZGnL8Bg4tX_OMBAAA=)):

```
<svelte:boundary>
	<p>{await delayed('hello!')}</p>

	{#snippet pending()}
		<p>loading...</p>
	{/snippet}
</svelte:boundary>
```

The `pending` snippet will *not* be shown for subsequent async updates — for these, you can use [`$effect.pending()`]($effect#$effect.pending).

> During server-side rendering, a boundary with a `pending` snippet renders that snippet and ignores the rest of its content. See [Server-side rendering](await-expressions#Server-side-rendering).

### failed[](#Properties-failed)

If a `failed` snippet is provided, it will be rendered when an error is thrown inside the boundary, with the `error` and a `reset` function that recreates the contents ([demo](/playground/hello-world#H4sIAAAAAAAAE3VRy26DMBD8lS2tFCIh6JkAUlWp39Cq9EBg06CAbdlLArL87zWGKk8ORnhmd3ZnrD1WtOjFXqKO2BDGW96xqpBD5gXerm5QefG39mgQY9EIWHxueRMinLosti0UPsJLzggZKTeilLWgLGc51a3gkuCjKQ7DO7cXZotgJ3kLqzC6hmex1SZnSXTWYHcrj8LJjWTk0PHoZ8VqIdCOKayPykcpuQxAokJaG1dGybYj4gw4K5u6PKTasSbjXKgnIDlA8VvUdo-pzonraBY2bsH7HAl78mKSHZpgIcuHjq9jXSpZSLixRlveKYQUXhQVhL6GPobXAAb7BbNeyvNUs4qfRg3OnELLj5hqH9eQZqCnoBwR9lYcQxuVXeBzc8kMF8yXY4yNJ5oGiUzP_aaf_waTRGJib5_Ad3P_vbCuaYxzeNpbU0eUMPAOKh7Yw1YErgtoXyuYlPLzc10_xo_5A91zkQL_AgAA)):

```
<svelte:boundary>
	<FlakyComponent />

	{#snippet failed(error, reset)}
		<button onclick={reset}>oops! try again</button>
	{/snippet}
</svelte:boundary>
```

> As with [snippets passed to components](snippet#Passing-snippets-to-components), the `failed` snippet can be passed explicitly as a property...
>
> ```
> <svelte:boundary {failed}>...</svelte:boundary>
> ```
>
> ...or implicitly by declaring it directly inside the boundary, as in the example above.

### onerror[](#Properties-onerror)

If an `onerror` function is provided, it will be called with the same two `error` and `reset` arguments. This is useful for tracking the error with an error reporting service...

```
<svelte:boundary onerror={(e) => report(e)}>
	...
</svelte:boundary>
```

...or using `error` and `reset` outside the boundary itself:

```
<script>
	let error = $state(null);
	let reset = $state(() => {});

	function onerror(e, r) {
		error = e;
		reset = r;
	}
</script>

<svelte:boundary {onerror}>
	<FlakyComponent />
</svelte:boundary>

{#if error}
	<button onclick={() => {
		error = null;
		reset();
	}}>
		oops! try again
	</button>
{/if}
```

If an error occurs inside the `onerror` function (or if you rethrow the error), it will be handled by a parent boundary if such exists.

## Using transformError[](#Using-transformError)

By default, error boundaries have no effect on the server — if an error occurs during rendering, the render as a whole will fail.

Since 5.51 you can control this behaviour for boundaries with a `failed` snippet, by calling [`render(...)`](imperative-component-api#render) with a `transformError` function.

> If you’re using Svelte via a framework such as SvelteKit, you most likely don’t have direct access to the `render(...)` call — the framework must configure `transformError` on your behalf. SvelteKit will add support for this in the near future, via the [`handleError`](../kit/hooks#handleError) hook.

The `transformError` function must return a JSON-stringifiable object which will be used to render the `failed` snippet. This object will be serialized and used to hydrate the snippet in the browser:

```
import { render(alias) function render<Comp extends SvelteComponent<any> | Component<any>, Props extends ComponentProps<Comp> = ComponentProps<Comp>>(...args: {} extends Props ? [component: Comp extends SvelteComponent<any> ? ComponentType<Comp> : Comp, options?: {
    props?: Omit<Props, "$$slots" | "$$events">;
    context?: Map<any, any>;
    idPrefix?: string;
    csp?: Csp;
    transformError?: (error: unknown) => unknown | Promise<unknown>;
}] : [component: Comp extends SvelteComponent<any> ? ComponentType<Comp> : Comp, options: {
    props: Omit<Props, "$$slots" | "$$events">;
    context?: Map<any, any>;
    idPrefix?: string;
    csp?: Csp;
    transformError?: (error: unknown) => unknown | Promise<unknown>;
}]): RenderOutput
import render

Only available on the server and when compiling with the server option.
Takes a component and returns an object with body and head properties on it, which you can use to populate the HTML when server-rendering your app.


reference } from 'svelte/server';
import App(alias) type App = SvelteComponent<Record<string, any>, any, any>
(alias) const App: LegacyComponentType
import App from './App.svelte';

const { headconst head: string

HTML that goes into the <head>


, bodyconst body: string

HTML that goes somewhere into the <body>


 } = await render(alias) render<SvelteComponent<Record<string, any>, any, any>, Record<string, any>>(component: ComponentType<SvelteComponent<Record<string, any>, any, any>>, options?: {
    props?: Omit<Record<string, any>, "$$slots" | "$$events"> | undefined;
    context?: Map<any, any>;
    idPrefix?: string;
    csp?: Csp;
    transformError?: ((error: unknown) => unknown | Promise<unknown>) | undefined;
} | undefined): RenderOutput
import render

Only available on the server and when compiling with the server option.
Takes a component and returns an object with body and head properties on it, which you can use to populate the HTML when server-rendering your app.


reference(App(alias) const App: LegacyComponentType
import App, {
	transformError(property) transformError?: ((error: unknown) => unknown | Promise<unknown>) | undefined: (error(parameter) error: unknown) => {
		// log the original error, with the stack trace...
		consolenamespace console
var console: Console

The console module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.




The module exports two specific components:





A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.


A global console instance configured to write to process.stdout and
process.stderr. The global console can be used without importing the node:console module.





Warning: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the note on process I/O for
more information.




Example using the global console:



console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
//   Error: Whoops, something bad happened
//     at [eval]:5:15
//     at Script.runInThisContext (node:vm:132:18)
//     at Object.runInThisContext (node:vm:309:38)
//     at node:internal/process/execution:77:19
//     at [eval]-wrapper:6:22
//     at evalScript (node:internal/process/execution:76:60)
//     at node:internal/main/eval_string:23:3

const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:



const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);

myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err

const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

source


.error(method) Console.error(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stderr with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to printf(3)
(the arguments are all passed to util.format()).



const code = 5;
console.error('error #%d', code);
// Prints: error #5, to stderr
console.error('error', code);
// Prints: error 5, to stderr

If formatting elements (e.g. %d) are not found in the first string then
util.inspect() is called on each argument and the
resulting string values are concatenated. See util.format()
for more information.




v0.1.100


(error(parameter) error: unknown);

		// ...and return a sanitized user-friendly error
		// to display in the `failed` snippet
		return {
			message(property) message: string: 'An error occurred!'
		};
	};
});
```

If `transformError` throws (or rethrows) an error, `render(...)` as a whole will fail with that error.

> Errors that occur during server-side rendering can contain sensitive information in the `message` and `stack`. It’s recommended to redact these rather than sending them unaltered to the browser.

If the boundary has an `onerror` handler, it will be called upon hydration with the deserialized error object.

The [`mount`](imperative-component-api#mount) and [`hydrate`](imperative-component-api#hydrate) functions also accept a `transformError` option, which defaults to the identity function. As with `render`, this function transforms a render-time error before it is passed to a `failed` snippet or `onerror` handler.

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/05-special-elements/01-svelte-boundary.md) [llms.txt](/docs/svelte/svelte-boundary/llms.txt)

previous next

[Nested \<style> elements](/docs/svelte/nested-style-elements) [\<svelte:window>](/docs/svelte/svelte-window)

----
url: https://svelte.dev/docs/svelte/svelte-files
----

[Skip to main content](#main)

Components are the building blocks of Svelte applications. They are written into `.svelte` files, using a superset of HTML.

All three sections — script, styles and markup — are optional.

MyComponent

```
<script module>
	// module-level logic goes here
	// (you will rarely use this)
</script>

<script>
	// instance-level logic goes here
</script>

<!-- markup (zero or more items) goes here -->

<style>
	/* styles go here */
</style>
```

```
<script module>
	// module-level logic goes here
	// (you will rarely use this)
</script>

<script lang="ts">
	// instance-level logic goes here
</script>

<!-- markup (zero or more items) goes here -->

<style>
	/* styles go here */
</style>
```

## \<script>[](#script)

A `<script>` block contains JavaScript (or TypeScript, when adding the `lang="ts"` attribute) that runs when a component instance is created. Variables declared (or imported) at the top level can be referenced in the component’s markup.

In addition to normal JavaScript, you can use *runes* to declare [component props]($props) and add reactivity to your component. Runes are covered in the next section.

## \<script module>[](#script-module)

A `<script>` tag with a `module` attribute runs once when the module first evaluates, rather than for each component instance. Variables declared in this block can be referenced elsewhere in the component, but not vice versa.

```
<script module>
	let total = 0;
</script>

<script>
	total += 1;
	console.log(`instantiated ${total} times`);
</script>
```

You can `export` bindings from this block, and they will become exports of the compiled module. You cannot `export default`, since the default export is the component itself.

> If you are using TypeScript and import such exports from a `module` block into a `.ts` file, make sure to have your editor setup so that TypeScript knows about them. This is the case for our VS Code extension and the IntelliJ plugin, but in other cases you might need to setup our [TypeScript editor plugin](https://www.npmjs.com/package/typescript-svelte-plugin).

> Legacy mode
>
> In Svelte 4, this script tag was created using `<script context="module">`

## \<style>[](#style)

CSS inside a `<style>` block will be scoped to that component.

```
<style>
	p {
		/* this will only affect <p> elements in this component */
		color: burlywood;
	}
</style>
```

For more information, head to the section on [styling](scoped-styles).

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/01-introduction/03-svelte-files.md) [llms.txt](/docs/svelte/svelte-files/llms.txt)

previous next

[Getting started](/docs/svelte/getting-started) [.svelte.js and .svelte.ts files](/docs/svelte/svelte-js-files)

----
url: https://svelte.dev/docs/svelte/@render/llms.txt
----

````
To render a [snippet](snippet), use a `{@render ...}` tag.

```svelte
{#snippet sum(a, b)}
	<p>{a} + {b} = {a + b}</p>
{/snippet}

{@render sum(1, 2)}
{@render sum(3, 4)}
{@render sum(5, 6)}
```

The expression can be an identifier like `sum`, or an arbitrary JavaScript expression:

```svelte
{@render (cool ? coolSnippet : lameSnippet)()}
```

## Optional snippets

If the snippet is potentially undefined — for example, because it's an incoming prop — then you can use optional chaining to only render it when it _is_ defined:

```svelte
{@render children?.()}
```

Alternatively, use an [`{#if ...}`](if) block with an `:else` clause to render fallback content:

```svelte
{#if children}
	{@render children()}
{:else}
	<p>fallback content</p>
{/if}
```
````

----
url: https://svelte.dev/docs/svelte/svelte-action
----

[Skip to main content](#main)

This module provides types for [actions](use), which have been superseded by [attachments](@attach).

## Action[](#Action)

Actions are functions that are called when an element is created. You can use this interface to type such actions. The following example defines an action that only works on `<div>` elements and optionally accepts a parameter which it has a default value for:

```
export const myActionconst myAction: Action<HTMLDivElement, {
    someProperty: boolean;
} | undefined>: Actiontype Action = /*unresolved*/ any<HTMLDivElementinterface HTMLDivElement

The HTMLDivElement interface provides special properties (beyond the regular HTMLElement interface it also has available to it by inheritance) for manipulating 

 elements.




MDN Reference


, { someProperty(property) someProperty: boolean: boolean } | undefined> = (node(parameter) node: any, param(parameter) param: {
    someProperty: boolean;
} = { someProperty(property) someProperty: boolean: true }) => {
	// ...
}
```

`Action<HTMLDivElement>` and `Action<HTMLDivElement, undefined>` both signal that the action accepts no parameters.

You can return an object with methods `update` and `destroy` from the function and type which additional attributes and events it has. See interface `ActionReturn` for more details.

```
interface Action<
	Element = HTMLElement,
	Parameter = undefined,
	Attributes extends Record<string, any> = Record<
		never,
		any
	>
> {/*…*/}
```

```
<Node extends Element>(
	...args: undefined extends Parameter
		? [node: Node, parameter?: Parameter]
		: [node: Node, parameter: Parameter]
): void | ActionReturn<Parameter, Attributes>;
```

## ActionReturn[](#ActionReturn)

Actions can return an object containing the two properties defined in this interface. Both are optional.

* update: An action can have a parameter. This method will be called whenever that parameter changes, immediately after Svelte has applied updates to the markup. `ActionReturn` and `ActionReturn<undefined>` both mean that the action accepts no parameters.
* destroy: Method that is called after the element is unmounted

Additionally, you can specify which additional attributes and events the action enables on the applied element. This applies to TypeScript typings only and has no effect at runtime.

Example usage:

```
interface Attributesinterface Attributes {
	newprop(property) Attributes.newprop?: string | undefined?: string;
	'on:event': (e(parameter) e: CustomEvent<boolean>: CustomEventinterface CustomEvent<T = any>

The CustomEvent interface can be used to attach custom data to an event generated by an application.




MDN Reference


<boolean>) => void;
}

export function myActionfunction myAction(node: HTMLElement, parameter: Parameter): ActionReturn<Parameter, Attributes>(node(parameter) node: HTMLElement: HTMLElementinterface HTMLElement

The HTMLElement interface represents any HTML element. Some elements directly implement this interface, while others implement it via an interface that inherits it.




MDN Reference


, parameter(parameter) parameter: Parameter: Parametertype Parameter = /*unresolved*/ any): ActionReturntype ActionReturn = /*unresolved*/ any<Parametertype Parameter = /*unresolved*/ any, Attributesinterface Attributes> {
	// ...
	return {
		update(property) update: (updatedParameter: any) => void: (updatedParameter(parameter) updatedParameter: any) => {...},
		destroyany: () => {...}
	};
}
```

```
interface ActionReturn<
	Parameter = undefined,
	Attributes extends Record<string, any> = Record<
		never,
		any
	>
> {/*…*/}
```

```
update?: (parameter: Parameter) => void;
```

```
destroy?: () => void;
```

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/98-reference/21-svelte-action.md) [llms.txt](/docs/svelte/svelte-action/llms.txt)

previous next

[svelte](/docs/svelte/svelte) [svelte/animate](/docs/svelte/svelte-animate)

----
url: https://svelte.dev/docs/svelte/$state/llms.txt
----

````
The `$state` rune allows you to create _reactive state_, which means that your UI _reacts_ when it changes.

```svelte
<script>
	let count = $state(0);
</script>

<button onclick={() => count++}>
	clicks: {count}
</button>
```

Unlike other frameworks you may have encountered, there is no API for interacting with state — `count` is just a number, rather than an object or a function, and you can update it like you would update any other variable.

### Deep state

If `$state` is used with an array or a simple object, the result is a deeply reactive _state proxy_. [Proxies](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy) allow Svelte to run code when you read or write properties, including via methods like `array.push(...)`, triggering granular updates.

State is proxified recursively until Svelte finds something other than an array or simple object (like a class or an object created with `Object.create`). In a case like this...

```js
let todos = $state([
	{
		done: false,
		text: 'add more todos'
	}
]);
```

...modifying an individual todo's property will trigger updates to anything in your UI that depends on that specific property:

```js
let todos = [{ done: false, text: 'add more todos' }];
// ---cut---
todos[0].done = !todos[0].done;
```

If you push a new object to the array, it will also be proxified:

```js
let todos = [{ done: false, text: 'add more todos' }];
// ---cut---
todos.push({
	done: false,
	text: 'eat lunch'
});
```

> [!NOTE] When you update properties of proxies, the original object is _not_ mutated. If you need to use your own proxy handlers in a state proxy, you should wrap the object _after_ wrapping it in `$state`.

Note that if you destructure a reactive value, the references are not reactive — as in normal JavaScript, they are evaluated at the point of destructuring:

```js
let todos = [{ done: false, text: 'add more todos' }];
// ---cut---
let { done, text } = todos[0];

// this will not affect the value of `done`
todos[0].done = !todos[0].done;
```

### Classes

Class instances are not proxied. Instead, you can use `$state` in class fields (whether public or private), or as the first assignment to a property immediately inside the `constructor`:

```js
// @errors: 7006 2554
class Todo {
	done = $state(false);

	constructor(text) {
		this.text = $state(text);
	}

	reset() {
		this.text = '';
		this.done = false;
	}
}
```

> [!NOTE] The compiler transforms `done` and `text` into `get`/`set` methods on the class prototype referencing private fields. This means the properties are not enumerable.

When calling methods in JavaScript, the value of [`this`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this) matters. This won't work, because `this` inside the `reset` method will be the `<button>` rather than the `Todo`:

```svelte
<button onclick={todo.reset}>
	reset
</button>
```

You can either use an inline function...

```svelte
<button onclick=+++{() => todo.reset()}>+++
	reset
</button>
```

...or use an arrow function in the class definition:

```js
// @errors: 7006 2554
class Todo {
	done = $state(false);

	constructor(text) {
		this.text = $state(text);
	}

	+++reset = () => {+++
		this.text = '';
		this.done = false;
	}
}
```

### Built-in classes

Svelte provides reactive implementations of built-in classes like `Set`, `Map`, `Date` and `URL` that can be imported from [`svelte/reactivity`](svelte-reactivity).

## `$state.raw`

In cases where you don't want objects and arrays to be deeply reactive you can use `$state.raw`.

State declared with `$state.raw` cannot be mutated; it can only be _reassigned_. In other words, rather than assigning to a property of an object, or using an array method like `push`, replace the object or array altogether if you'd like to update it:

```js
let person = $state.raw({
	name: 'Heraclitus',
	age: 49
});

// this will have no effect
person.age += 1;

// this will work, because we're creating a new person
person = {
	name: 'Heraclitus',
	age: 50
};
```

This can improve performance with large arrays and objects that you weren't planning to mutate anyway, since it avoids the cost of making them reactive. Note that raw state can _contain_ reactive state (for example, a raw array of reactive objects).

As with `$state`, you can declare class fields using `$state.raw`.

## `$state.snapshot`

To take a static snapshot of a deeply reactive `$state` proxy, use `$state.snapshot`:

```svelte
<script>
	let counter = $state({ count: 0 });

	function onclick() {
		// Will log `{ count: ... }` rather than `Proxy { ... }`
		console.log($state.snapshot(counter));
	}
</script>
```

This is handy when you want to pass some state to an external library or API that doesn't expect a proxy, such as `structuredClone`.

If a value has a `toJSON` method, the snapshot will clone the value returned from `toJSON` instead of the original object.

## `$state.eager`

When state changes, it may not be reflected in the UI immediately if it is used by an `await` expression, because [updates are synchronized](await-expressions#Synchronized-updates).

In some cases, you may want to update the UI as soon as the state changes. For example, you might want to update a navigation bar when the user clicks on a link, so that they get visual feedback while waiting for the new page to load. To do this, use `$state.eager(value)`:

```svelte
<nav>
	<a href="/" aria-current={$state.eager(pathname) === '/' ? 'page' : null}>home</a>
	<a href="/about" aria-current={$state.eager(pathname) === '/about' ? 'page' : null}>about</a>
</nav>
```

Use this feature sparingly, and only to provide feedback in response to user action — in general, allowing Svelte to coordinate updates will provide a better user experience.

## Passing state into functions

JavaScript is a _pass-by-value_ language — when you call a function, the arguments are the _values_ rather than the _variables_. In other words:

```js
/// file: index.js
// @filename: index.js
// ---cut---
/**
 * @param {number} a
 * @param {number} b
 */
function add(a, b) {
	return a + b;
}

let a = 1;
let b = 2;
let total = add(a, b);
console.log(total); // 3

a = 3;
b = 4;
console.log(total); // still 3!
```

If `add` wanted to have access to the _current_ values of `a` and `b`, and to return the current `total` value, you would need to use functions instead:

```js
/// file: index.js
// @filename: index.js
// ---cut---
/**
 * @param {() => number} getA
 * @param {() => number} getB
 */
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
```

State in Svelte is no different — when you reference something declared with the `$state` rune...

```js
let a = +++$state(1)+++;
let b = +++$state(2)+++;
```

...you're accessing its _current value_.

Note that 'functions' is broad — it encompasses properties of proxies and [`get`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get)/[`set`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/set) properties...

```js
/// file: index.js
// @filename: index.js
// ---cut---
/**
 * @param {{ a: number, b: number }} input
 */
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
```

...though if you find yourself writing code like that, consider using [classes](#Classes) instead.

## Passing state across modules

You can declare state in `.svelte.js` and `.svelte.ts` files, but you can only _export_ that state if it's not directly reassigned. In other words you can't do this:

```js
/// file: state.svelte.js
export let count = $state(0);

export function increment() {
	count += 1;
}
```

That's because every reference to `count` is transformed by the Svelte compiler — the code above is roughly equivalent to this:

```js
/// file: state.svelte.js (compiler output)
// @filename: index.ts
interface Signal<T> {
	value: T;
}

interface Svelte {
	state<T>(value?: T): Signal<T>;
	get<T>(source: Signal<T>): T;
	set<T>(source: Signal<T>, value: T): void;
}
declare const $: Svelte;
// ---cut---
export let count = $.state(0);

export function increment() {
	$.set(count, $.get(count) + 1);
}
```

> [!NOTE] You can see the code Svelte generates by clicking the 'JS Output' tab in the [playground](/playground).

Since the compiler only operates on one file at a time, if another file imports `count` Svelte doesn't know that it needs to wrap each reference in `$.get` and `$.set`:

```js
// @filename: state.svelte.js
export let count = 0;

// @filename: index.js
// ---cut---
import { count } from './state.svelte.js';

console.log(typeof count); // 'object', not 'number'
```

This leaves you with two options for sharing state between modules — either don't reassign it...

```js
// This is allowed — since we're updating
// `counter.count` rather than `counter`,
// Svelte doesn't wrap it in `$.state`
export const counter = $state({
	count: 0
});

export function increment() {
	counter.count += 1;
}
```

...or don't directly export it:

```js
let count = $state(0);

export function getCount() {
	return count;
}

export function increment() {
	count += 1;
}
```
````

----
url: https://svelte.dev/docs/svelte/svelte-events/llms.txt
----

````
```js
// @noErrors
import { on } from 'svelte/events';
```

## on

Attaches an event handler to the window and returns a function that removes the handler. Using this
rather than `addEventListener` will preserve the correct order relative to handlers added declaratively
(with attributes like `onclick`), which use event delegation for performance reasons

<div class="ts-block">

```dts
function on<Type extends keyof WindowEventMap>(
	window: Window,
	type: Type,
	handler: (
		this: Window,
		event: WindowEventMap[Type] & { currentTarget: Window }
	) => any,
	options?: AddEventListenerOptions | undefined
): () => void;
```

</div>

<div class="ts-block">

```dts
function on<Type extends keyof DocumentEventMap>(
	document: Document,
	type: Type,
	handler: (
		this: Document,
		event: DocumentEventMap[Type] & {
			currentTarget: Document;
		}
	) => any,
	options?: AddEventListenerOptions | undefined
): () => void;
```

</div>

<div class="ts-block">

```dts
function on<
	Element extends HTMLElement,
	Type extends keyof HTMLElementEventMap
>(
	element: Element,
	type: Type,
	handler: (
		this: Element,
		event: HTMLElementEventMap[Type] & {
			currentTarget: Element;
		}
	) => any,
	options?: AddEventListenerOptions | undefined
): () => void;
```

</div>

<div class="ts-block">

```dts
function on<
	Element extends MediaQueryList,
	Type extends keyof MediaQueryListEventMap
>(
	element: Element,
	type: Type,
	handler: (
		this: Element,
		event: MediaQueryListEventMap[Type] & {
			currentTarget: Element;
		}
	) => any,
	options?: AddEventListenerOptions | undefined
): () => void;
```

</div>

<div class="ts-block">

```dts
function on(
	element: EventTarget,
	type: string,
	handler: EventListener,
	options?: AddEventListenerOptions | undefined
): () => void;
```

</div>
````

----
url: https://svelte.dev/docs/svelte/$derived/llms.txt
----

````
Derived state is declared with the `$derived` rune:

```svelte
<script>
	let count = $state(0);
	let doubled = $derived(count * 2);
</script>

<button onclick={() => count++}>
	{doubled}
</button>

<p>{count} doubled is {doubled}</p>
```

The expression inside `$derived(...)` should be free of side-effects. Svelte will disallow state changes (e.g. `count++`) inside derived expressions.

As with `$state`, you can mark class fields as `$derived`.

> [!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`

Sometimes you need to create complex derivations that don't fit inside a short expression. In these cases, you can use `$derived.by` which accepts a function as its argument.

```svelte
<script>
	let numbers = $state([1, 2, 3]);
	let total = $derived.by(() => {
		let total = 0;
		for (const n of numbers) {
			total += n;
		}
		return total;
	});
</script>

<button onclick={() => numbers.push(numbers.length + 1)}>
	{numbers.join(' + ')} = {total}
</button>
```

In essence, `$derived(expression)` is equivalent to `$derived.by(() => expression)`.

## Understanding dependencies

Anything read synchronously inside the `$derived` expression (or `$derived.by` function body) is considered a _dependency_ of the derived state. When the state changes, the derived will be marked as _dirty_ and recalculated when it is next read.

In addition, if an expression contains an [`await`](await-expressions), Svelte transforms it such that any state _after_ the `await` is also tracked — in other words, in a case like this...

```js
let a = Promise.resolve(1);
let b = 2;
// ---cut---
let total = $derived(await a + b);
```

...both `a` and `b` are tracked, even though `b` is only read once `a` has resolved, after the initial execution. (This does not apply to `await` in functions that are called by the expression, only the expression itself.)

To exempt a piece of state from being treated as a dependency, use [`untrack`](svelte#untrack).

## Overriding derived values

Derived expressions are recalculated when their dependencies change, but you can temporarily override their values by reassigning them (unless they are declared with `const`). This can be useful for things like _optimistic UI_, where a value is derived from the 'source of truth' (such as data from your server) but you'd like to show immediate feedback to the user:

```svelte
<script>
	let { post, like } = $props();

	let likes = $derived(post.likes);

	async function onclick() {
		// increment the `likes` count immediately...
		likes += 1;

		// and tell the server, which will eventually update `post`
		try {
			await like();
		} catch {
			// failed! roll back the change
			likes -= 1;
		}
	}
</script>

<button {onclick}>🧡 {likes}</button>
```

> [!NOTE] Prior to Svelte 5.25, deriveds were read-only.

## Deriveds and reactivity

Unlike `$state`, which converts objects and arrays to [deeply reactive proxies]($state#Deep-state), `$derived` values are left as-is. For example, in a case like this...

```js
// @errors: 7005
let items = $state([ /*...*/ ]);

let index = $state(0);
let selected = $derived(items[index]);
```

...you can change (or `bind:` to) properties of `selected` and it will affect the underlying `items` array. If `items` was _not_ deeply reactive, mutating `selected` would have no effect.

## Destructuring

If you use destructuring with a `$derived` declaration, the resulting variables will all be reactive — this...

```js
function stuff() { return { a: 1, b: 2, c: 3 } }
// ---cut---
let { a, b, c } = $derived(stuff());
```

...is roughly equivalent to this:

```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

Svelte uses something called _push-pull reactivity_ — when state is updated, everything that depends on the state (whether directly or indirectly) is immediately notified of the change (the 'push'), but derived values are not re-evaluated until they are actually read (the 'pull').

If the new value of a derived is referentially identical to its previous value, downstream updates will be skipped. In other words, Svelte will only update the text inside the button when `large` changes, not when `count` changes, even though `large` depends on `count`:

```svelte
<script>
	let count = $state(0);
	let large = $derived(count > 10);
</script>

<button onclick={() => count++}>
	{large}
</button>
```
````

----
url: https://svelte.dev/docs/svelte/$effect/llms.txt
----

````
Effects are functions that run when state updates, and can be used for things like calling third-party libraries, drawing on `<canvas>` elements, or making network requests. They only run in the browser, not during server-side rendering.

Generally speaking, you should _not_ update state inside effects, as it will make code more convoluted and will often lead to never-ending update cycles. If you find yourself doing so, see [when not to use `$effect`](#When-not-to-use-$effect) to learn about alternative approaches.

You can create an effect with the `$effect` rune (demo:

```svelte
<script>
	let size = $state(50);
	let color = $state('#ff3e00');

	let canvas;

	$effect(() => {
		const context = canvas.getContext('2d');
		context.clearRect(0, 0, canvas.width, canvas.height);

		// this will re-run whenever `color` or `size` change
		context.fillStyle = color;
		context.fillRect(0, 0, size, size);
	});
</script>

<canvas bind:this={canvas} width="100" height="100"></canvas>
```

When Svelte runs an effect function, it tracks which pieces of state (and derived state) are accessed (unless accessed inside [`untrack`](svelte#untrack)), and re-runs the function when that state later changes.

> [!NOTE] If you're having difficulty understanding why your `$effect` is rerunning or is not running see [understanding dependencies](#Understanding-dependencies). Effects are triggered differently than the `$:` blocks you may be used to if coming from Svelte 4.

### Understanding lifecycle

Your effects run after the component has been mounted to the DOM, and in a [microtask](https://developer.mozilla.org/en-US/docs/Web/API/HTML_DOM_API/Microtask_guide) after state changes. Re-runs are batched (i.e. changing `color` and `size` in the same moment won't cause two separate runs), and happen after any DOM updates have been applied.

You can use `$effect` anywhere, not just at the top level of a component, as long as it is called while a parent effect is running.

> [!NOTE] Svelte uses effects internally to represent logic and expressions in your template — this is how `<h1>hello {name}!</h1>` updates when `name` changes.

An effect can return a _teardown function_ which will run immediately before the effect re-runs:

<!-- codeblock:start {"title":"Effect teardown"} -->
```svelte
<!--- file: App.svelte --->
<script>
	let count = $state(0);
	let milliseconds = $state(1000);

	$effect(() => {
		// This will be recreated whenever `milliseconds` changes
		const interval = setInterval(() => {
			count += 1;
		}, milliseconds);

		return () => {
			// if a teardown function is provided, it will run
			// a) immediately before the effect re-runs
			// b) when the component is destroyed
			clearInterval(interval);
		};
	});
</script>

<h1>{count}</h1>

<button onclick={() => (milliseconds *= 2)}>slower</button>
<button onclick={() => (milliseconds /= 2)}>faster</button>
```
<!-- codeblock:end -->

Teardown functions also run when the effect is destroyed, which happens when its parent is destroyed (for example, a component is unmounted) or the parent effect re-runs.

### Understanding dependencies

`$effect` automatically picks up any reactive values (`$state`, `$derived`, `$props`) that are _synchronously_ read inside its function body (including indirectly, via function calls) and registers them as dependencies. When those dependencies change, the `$effect` schedules a re-run.

If `$state` and `$derived` are used directly inside the `$effect` (for example, during creation of a [reactive class](https://svelte.dev/docs/svelte/$state#Classes)), those values will _not_ be treated as dependencies.

Values that are read _asynchronously_ — after an `await` or inside a `setTimeout`, for example — will not be tracked. Here, the canvas will be repainted when `color` changes, but not when `size` changes (demo:

```ts
// @filename: index.ts
declare let canvas: {
	width: number;
	height: number;
	getContext(type: '2d', options?: CanvasRenderingContext2DSettings): CanvasRenderingContext2D;
};
declare let color: string;
declare let size: number;

// ---cut---
$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);
});
```

An effect only reruns when the object it reads changes, not when a property inside it changes. (If you want to observe changes _inside_ an object at dev time, you can use [`$inspect`]($inspect).)

```svelte
<script>
	let state = $state({ value: 0 });
	let derived = $derived({ value: state.value * 2 });

	// this will run once, because `state` is never reassigned (only mutated)
	$effect(() => {
		state;
	});

	// this will run whenever `state.value` changes...
	$effect(() => {
		state.value;
	});

	// ...and so will this, because `derived` is a new object each time
	$effect(() => {
		derived;
	});
</script>

<button onclick={() => (state.value += 1)}>
	{state.value}
</button>

<p>{state.value} doubled is {derived.value}</p>
```

An effect only depends on the values that it read the last time it ran. This has interesting implications for effects that have conditional code.

For instance, if `condition` is `true` in the code snippet below, the code inside the `if` block will run and `color` will be evaluated. This means that changes to either `condition` or `color` will cause the effect to re-run.

Conversely, if `condition` is `false`, `color` will not be evaluated, and the effect will _only_ re-run again when `condition` changes.

```ts
// @filename: ambient.d.ts
declare module 'canvas-confetti' {
	interface ConfettiOptions {
		colors: string[];
	}

	function confetti(opts?: ConfettiOptions): void;
	export default confetti;
}

// @filename: index.js
// ---cut---
import confetti from 'canvas-confetti';

let condition = $state(true);
let color = $state('#ff3e00');

$effect(() => {
	if (condition) {
		confetti({ colors: [color] });
	} else {
		confetti();
	}
});
```

## `$effect.pre`

In rare cases, you may need to run code _before_ the DOM updates. For this we can use the `$effect.pre` rune:

```svelte
<script>
	import { tick } from 'svelte';

	let div = $state();
	let messages = $state([]);

	// ...

	$effect.pre(() => {
		if (!div) return; // not yet mounted

		// reference `messages` array length so that this code re-runs whenever it changes
		messages.length;

		// autoscroll when new messages are added
		if (div.offsetHeight + div.scrollTop > div.scrollHeight - 20) {
			tick().then(() => {
				div.scrollTo(0, div.scrollHeight);
			});
		}
	});
</script>

<div bind:this={div}>
	{#each messages as message}
		<p>{message}</p>
	{/each}
</div>
```

`$effect.pre` runs before DOM updates that are scheduled after it, not before every DOM mutation in the flush - DOM of parent components may already be updated. When using [await expressions](await-expressions), block updates like `{#if ...}` and `{#each ...}` in the same component also run before `$effect.pre`.

Apart from the timing, `$effect.pre` works exactly like `$effect`.

## `$effect.tracking`

The `$effect.tracking` rune is an advanced feature that tells you whether or not the code is running inside a tracking context, such as an effect or inside your template:

<!-- codeblock:start {"title":"$effect.tracking()"} -->
```svelte
<!--- file: App.svelte --->
<script>
	console.log('in component setup:', $effect.tracking()); // false

	$effect(() => {
		console.log('in effect:', $effect.tracking()); // true
	});
</script>

<p>in template: {$effect.tracking()}</p> <!-- true -->
```
<!-- codeblock:end -->

It is used to implement abstractions like [`createSubscriber`](/docs/svelte/svelte-reactivity#createSubscriber), which will create listeners to update reactive values but _only_ if those values are being tracked (rather than, for example, read inside an event handler).

## `$effect.pending`

When using [`await`](await-expressions) in components, the `$effect.pending()` rune tells you how many promises are pending in the current [boundary](svelte-boundary), not including child boundaries:

<!-- codeblock:start {"title":"$effect.pending"} -->
```svelte
<!--- file: App.svelte --->
<script>
	let a = $state(1);
	let b = $state(2);

	async function add(a, b) {
		await new Promise((f) => setTimeout(f, 500)); // artificial delay
		return a + b;
	}
</script>

<button onclick={() => a++}>a++</button>
<button onclick={() => b++}>b++</button>

<p>{a} + {b} = {await add(a, b)}</p>

{#if $effect.pending()}
	<p>pending promises: {$effect.pending()}</p>
{/if}
```
<!-- codeblock:end -->

## `$effect.root`

The `$effect.root` rune is an advanced feature that creates a non-tracked scope that doesn't auto-cleanup. This is useful for nested effects that you want to manually control. This rune also allows for the creation of effects outside of the component initialisation phase.

```js
const destroy = $effect.root(() => {
	$effect(() => {
		// setup
	});

	return () => {
		// cleanup
	};
});

// later...
destroy();
```

## When not to use `$effect`

In general, `$effect` is best considered something of an escape hatch — useful for things like analytics and direct DOM manipulation — rather than a tool you should use frequently. In particular, avoid using it to synchronise state. Instead of this...

```svelte
<script>
	let count = $state(0);
	let doubled = $state();

	// don't do this!
	$effect(() => {
		doubled = count * 2;
	});
</script>
```

...do this:

```svelte
<script>
	let count = $state(0);
	let doubled = $derived(count * 2);
</script>
```

> [!NOTE] For things that are more complicated than a simple expression like `count * 2`, you can also use `$derived.by`.

If you're using an effect because you want to be able to reassign the derived value (to build an optimistic UI, for example) note that [deriveds can be directly overridden]($derived#Overriding-derived-values) as of Svelte 5.25.

You might be tempted to do something convoluted with effects to link one value to another. The following example shows two inputs for "money spent" and "money left" that are connected to each other. If you update one, the other should update accordingly. Instead of using effects for this...

<!-- codeblock:start {"title":"Setting state in effects (don't do this!)"} -->
```svelte
<!--- file: App.svelte --->
<script>
	const total = 100;
	let spent = $state(0);
	let left = $state(total);

	$effect(() => {
		left = total - spent;
	});

	$effect(() => {
		spent = total - left;
	});
</script>

<label>
	<input type="range" bind:value={spent} max={total} />
	{spent}/{total} spent
</label>

<label>
	<input type="range" bind:value={left} max={total} />
	{left}/{total} left
</label>

<style>
	label {
		display: flex;
		gap: 0.5em;
	}
</style>
```
<!-- codeblock:end -->

...use `oninput` callbacks or — better still — [function bindings](bind#Function-bindings) where possible:

<!-- codeblock:start {"title":"Setting state with function bindings"} -->
```svelte
<!--- file: App.svelte --->
<script>
	const total = 100;
	let spent = $state(0);
	let left = $derived(total - spent);

+++	function updateLeft(left) {
		spent = total - left;
	}+++
</script>

<label>
	<input type="range" bind:value={spent} max={total} />
	{spent}/{total} spent
</label>

<label>
	<input type="range" +++bind:value={() => left, updateLeft}+++ max={total} />
	{left}/{total} left
</label>

<style>
	label {
		display: flex;
		gap: 0.5em;
	}
</style>
```
<!-- codeblock:end -->

If you absolutely have to update `$state` within an effect and run into an infinite loop because you read and write to the same `$state`, use [untrack](svelte#untrack).
````

----
url: https://svelte.dev/docs/svelte/getting-started
----

[Skip to main content](#main)

We recommend using [SvelteKit](../kit), which lets you [build almost anything](../kit/project-types). It’s the official application framework from the Svelte team and powered by [Vite](https://vite.dev/). Create a new project with:

```
npx sv create myapp
cd myapp
npm install
npm run dev
```

Don’t worry if you don’t know Svelte yet! You can ignore all the nice features SvelteKit brings on top for now and dive into it later.

## Alternatives to SvelteKit[](#Alternatives-to-SvelteKit)

You can also use Svelte directly with Vite via [vite-plugin-svelte](https://github.com/sveltejs/vite-plugin-svelte) by running `npm create vite@latest` and selecting the `svelte` option (or, if working with an existing project, adding the plugin to your `vite.config.js` file). With this, `npm run build` will generate HTML, JS, and CSS files inside the `dist` directory. In most cases, you will probably need to [choose a routing library](/packages#routing) as well.

> Vite is often used in standalone mode to build [single page apps (SPAs)](../kit/glossary#SPA), which you can also [build with SvelteKit](../kit/single-page-apps).

There are also [plugins for other bundlers](/packages#bundler-plugins), but we recommend Vite.

## Editor tooling[](#Editor-tooling)

The Svelte team maintains a [VS Code extension](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode), and there are integrations with various other [editors](https://sveltesociety.dev/collection/editor-support-c85c080efc292a34) and tools as well.

You can also check your code from the command line using [`npx sv check`](/docs/cli/sv-check).

## Getting help[](#Getting-help)

Don’t be shy about asking for help in the [Discord chatroom](/chat)! You can also find answers on [Stack Overflow](https://stackoverflow.com/questions/tagged/svelte).

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/01-introduction/02-getting-started.md) [llms.txt](/docs/svelte/getting-started/llms.txt)

previous next

[Overview](/docs/svelte/overview) [.svelte files](/docs/svelte/svelte-files)

----
url: https://svelte.dev/docs/svelte/global-styles/llms.txt
----

````
## :global(...)

To apply styles to a single selector globally, use the `:global(...)` modifier:

```svelte
<style>
	:global(body) {
		/* applies to <body> */
		margin: 0;
	}

	div :global(strong) {
		/* applies to all <strong> elements, in any component,
		   that are inside <div> elements belonging
		   to this component */
		color: goldenrod;
	}

	p:global(.big.red) {
		/* applies to all <p> elements belonging to this component
		   with `class="big red"`, even if it is applied
		   programmatically (for example by a library) */
	}
</style>
```

If you want to make @keyframes that are accessible globally, you need to prepend your keyframe names with `-global-`.

The `-global-` part will be removed when compiled, and the keyframe will then be referenced using just `my-animation-name` elsewhere in your code.

```svelte
<style>
	@keyframes -global-my-animation-name {
		/* code goes here */
	}
</style>
```

## :global

To apply styles to a group of selectors globally, create a `:global {...}` block:

```svelte
<style>
	:global {
		/* applies to every <div> in your application */
		div { ... }

		/* applies to every <p> in your application */
		p { ... }
	}

	.a :global {
		/* applies to every `.b .c .d` element, in any component,
		   that is inside an `.a` element in this component */
		.b .c .d {...}
	}
</style>
```

> [!NOTE] The second example above could also be written as an equivalent `.a :global .b .c .d` selector, where everything after the `:global` is unscoped, though the nested form is preferred.
````

----
url: https://svelte.dev/docs/svelte/$inspect/llms.txt
----

````
> [!NOTE] `$inspect` only works during development. In a production build it becomes a noop.

The `$inspect` rune is roughly equivalent to `console.log`, with the exception that it will re-run whenever its argument changes. `$inspect` tracks reactive state deeply, meaning that updating something inside an object or array using fine-grained reactivity will cause it to re-fire:

<!-- codeblock:start {"title":"$inspect(...)"} -->
```svelte
<!--- file: App.svelte --->
<script>
	let count = $state(0);
	let message = $state('hello');

	$inspect(count, message); // will console.log when `count` or `message` change
</script>

<button onclick={() => count++}>Increment</button>
<input bind:value={message} />
```
<!-- codeblock:end -->

On updates, a stack trace will be printed, making it easy to find the origin of a state change (unless you're in the playground, due to technical limitations).

## $inspect(...).with

`$inspect(...)` returns an object with a `with` method, which you can invoke with a callback that will then be invoked instead of `console.log`. The first argument to the callback is either `"init"` or `"update"`; subsequent arguments are the values passed to `$inspect`:

<!-- codeblock:start {"title":"$inspect(...).with(...)"} -->
```svelte
<!--- file: App.svelte --->
<script>
	let count = $state(0);

	$inspect(count).with((type, count) => {
		if (type === 'update') {
			debugger; // or `console.trace`, or whatever you want
		}
	});
</script>

<button onclick={() => count++}>Increment</button>
```
<!-- codeblock:end -->

## $inspect.trace(...)

This rune, added in 5.14, causes the surrounding function to be _traced_ in development. Any time the function re-runs as part of an [effect]($effect) or a [derived]($derived), information will be printed to the console about which pieces of reactive state caused the effect to fire.

```svelte
<script>
	import { doSomeWork } from './elsewhere';

	$effect(() => {
		+++// $inspect.trace must be the first statement of a function body+++
		+++$inspect.trace();+++
		doSomeWork();
	});
</script>
```

`$inspect.trace` takes an optional first argument which will be used as the label.
````

----
url: https://svelte.dev/docs/svelte/legacy-svelte-fragment/llms.txt
----

````
The `<svelte:fragment>` element allows you to place content in a [named slot](legacy-slots) without wrapping it in a container DOM element. This keeps the flow layout of your document intact.

```svelte
<!--- file: Widget.svelte --->
<div>
	<slot name="header">No header was provided</slot>
	<p>Some content between header and footer</p>
	<slot name="footer" />
</div>
```

```svelte
<!--- file: App.svelte --->
<script>
	import Widget from './Widget.svelte';
</script>

<Widget>
	<h1 slot="header">Hello</h1>
	<svelte:fragment slot="footer">
		<p>All rights reserved.</p>
		<p>Copyright (c) 2019 Svelte Industries</p>
	</svelte:fragment>
</Widget>
```

> [!NOTE]
> In Svelte 5+, this concept is obsolete, as snippets don't create a wrapping element
````

----
url: https://svelte.dev/docs/svelte/svelte-animate/llms.txt
----

````
```js
// @noErrors
import { flip } from 'svelte/animate';
```

## flip

The flip function calculates the start and end position of an element and animates between them, translating the x and y values.
`flip` stands for [First, Last, Invert, Play](https://aerotwist.com/blog/flip-your-animations/).

<div class="ts-block">

```dts
function flip(
	node: Element,
	{
		from,
		to
	}: {
		from: DOMRect;
		to: DOMRect;
	},
	params?: FlipParams
): AnimationConfig;
```

</div>



## AnimationConfig

<div class="ts-block">

```dts
interface AnimationConfig {/*…*/}
```

<div class="ts-block-property">

```dts
delay?: number;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
duration?: number;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
easing?: (t: number) => number;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
css?: (t: number, u: number) => string;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
tick?: (t: number, u: number) => void;
```

<div class="ts-block-property-details"></div>
</div></div>

## FlipParams

<div class="ts-block">

```dts
interface FlipParams {/*…*/}
```

<div class="ts-block-property">

```dts
delay?: number;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
duration?: number | ((len: number) => number);
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
easing?: (t: number) => number;
```

<div class="ts-block-property-details"></div>
</div></div>
````

----
url: https://svelte.dev/docs/svelte/$bindable
----

[Skip to main content](#main)

Ordinarily, props go one way, from parent to child. This makes it easy to understand how data flows around your app.

In Svelte, component props can be *bound*, which means that data can also flow *up* from child to parent. This isn’t something you should do often — overuse can make your data flow unpredictable and your components harder to maintain — but it can simplify your code if used sparingly and carefully.

It also means that a state proxy can be *mutated* in the child.

> Mutation is also possible with normal props, but is strongly discouraged — Svelte will warn you if it detects that a component is mutating state it does not ‘own’.

To mark a prop as bindable, we use the `$bindable` rune:

FancyInput

```
<script>
	let { value = $bindable(), ...props } = $props();
</script>

<input bind:value={value} {...props} />

<style>
	input {
		font-family: 'Comic Sans MS';
		color: deeppink;
	}
</style>
```

```
<script lang="ts">
	let { value = $bindable(), ...props } = $props();
</script>

<input bind:value={value} {...props} />

<style>
	input {
		font-family: 'Comic Sans MS';
		color: deeppink;
	}
</style>
```

Now, a component that uses `<FancyInput>` can add the [`bind:`](bind) directive ([demo](/playground/untitled#H4sIAAAAAAAAE3WQwWrDMBBEf2URBSfg2nfFMZRCoYeecqx6UJx1IyqvhLUONcb_XqSkTUOSk1az7DBvJtEai0HI90nw6FHIJIhckO7i78n7IhzQctS2OuAtvXHESByEFFVoeuO5VqTYdN71DC-amvGV_MDQ9q6DrCjP0skkWymKJxYZOgxBfyKs4SGwZlxke7TWZcuVoqo8-1P1z3lraCcP2g64nk4GM5S1osrXf0JV-lrkgvGbheR-wDm_g30V8JL-1vpOCZFogpQsEsWcemtxscyhKArfOx9gjps0Lq4hzRVfemaYfu-PoIqqwKPFY_XpaIqj4tYRP7a6M3aUkD27zjSw0RTgbZN6Z8WNs66XsEP03tBXUueUJFlelvYx_wCuI3leNwIAAA==)):

App

```
<script>
	import FancyInput from './FancyInput.svelte';

	let message = $state('hello');
</script>

<FancyInput bind:value={message} />
<p>{message}</p>
```

```
<script lang="ts">
	import FancyInput from './FancyInput.svelte';

	let message = $state('hello');
</script>

<FancyInput bind:value={message} />
<p>{message}</p>
```

The parent component doesn’t *have* to use `bind:` — it can just pass a normal prop. Some parents don’t want to listen to what their children have to say.

In this case, you can specify a fallback value for when no prop is passed at all:

FancyInput

```
let { valuelet value: any = $bindablefunction $bindable<"fallback">(fallback?: "fallback" | undefined): "fallback"
namespace $bindable

Declares a prop as bindable, meaning the parent component can use bind:propName={value} to bind to it.



let { propName = $bindable() }: { propName: boolean } = $props();

{@link https://svelte.dev/docs/svelte/$bindable Documentation}


('fallback'), ...propslet props: any } = $propsfunction $props(): any
namespace $props

Declares the props that a component accepts. Example:



let { optionalProp = 42, requiredProp, bindableProp = $bindable() }: { optionalProp?: number; requiredProps: string; bindableProp: boolean } = $props();

{@link https://svelte.dev/docs/svelte/$props Documentation}


();
```

When a bindable prop has a fallback value, the parent must pass a value other than `undefined` if it uses `bind:`. This avoids ambiguity about which value should apply, since the parent and child should share the same value for a binding.

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/02-runes/06-$bindable.md) [llms.txt](/docs/svelte/$bindable/llms.txt)

previous next

[$props](/docs/svelte/$props) [$inspect](/docs/svelte/$inspect)

----
url: https://svelte.dev/docs/svelte/@debug/llms.txt
----

````
The `{@debug ...}` tag offers an alternative to `console.log(...)`. It logs the values of specific variables whenever they change, and pauses code execution if you have devtools open.

```svelte
<script>
	let user = {
		firstname: 'Ada',
		lastname: 'Lovelace'
	};
</script>

{@debug user}

<h1>Hello {user.firstname}!</h1>
```

`{@debug ...}` accepts a comma-separated list of variable names (not arbitrary expressions).

```svelte
<!-- Compiles -->
{@debug user}
{@debug user1, user2, user3}

<!-- WON'T compile -->
{@debug user.firstname}
{@debug myArray[0]}
{@debug !isReady}
{@debug typeof user === 'object'}
```

The `{@debug}` tag without any arguments will insert a `debugger` statement that gets triggered when _any_ state changes, as opposed to the specified variables.
````

----
url: https://svelte.dev/docs/svelte/svelte
----

[Skip to main content](#main)

```
import {
	SvelteComponent(alias) class SvelteComponent<Props extends Record<string, any> = Record<string, any>, Events extends Record<string, any> = any, Slots extends Record<string, any> = any>
import SvelteComponent

This was the base class for Svelte components in Svelte 4. Svelte 5+ components
are completely different under the hood. For typing, use Component instead.
To instantiate components, use mount instead.
See migration guide for more info.


reference,
	SvelteComponentTyped(alias) class SvelteComponentTyped<Props extends Record<string, any> = Record<string, any>, Events extends Record<string, any> = any, Slots extends Record<string, any> = any>
import SvelteComponentTyped

Use Component instead. See migration guide for more information.


reference,
	afterUpdate(alias) function afterUpdate(fn: () => void): void
import afterUpdate

Schedules a callback to run immediately after the component has been updated.




The first time the callback runs will be after the initial onMount.




In runes mode use $effect instead.




Use $effect instead


reference,
	beforeUpdate(alias) function beforeUpdate(fn: () => void): void
import beforeUpdate

Schedules a callback to run immediately before the component is updated after any state change.




The first time the callback runs will be before the initial onMount.




In runes mode use $effect.pre instead.




Use $effect.pre instead


reference,
	createContext(alias) function createContext<T>(): [() => T, (context: T) => T, () => boolean]
import createContext

Returns a [get, set, has] triplet of functions for working with context in a type-safe way.




get will throw an error if set has not yet been called in the current component or any of
its ancestors.




5.40.0


reference,
	createEventDispatcher(alias) function createEventDispatcher<EventMap extends Record<string, any> = any>(): EventDispatcher<EventMap>
import createEventDispatcher

Creates an event dispatcher that can be used to dispatch component events.
Event dispatchers are functions that can take two arguments: name and detail.




Component events created with createEventDispatcher create a
CustomEvent.
These events do not bubble.
The detail argument corresponds to the CustomEvent.detail
property and can contain any type of data.




The event dispatcher can be typed to narrow the allowed event names and the type of the detail argument:



const dispatch = createEventDispatcher<{
 loaded: null; // does not take a detail argument
 change: string; // takes a detail argument of type string, which is required
 optional: number | null; // takes an optional detail argument of type number
}>();

Use callback props and/or the $host() rune instead — see migration guide


reference,
	createRawSnippet(alias) function createRawSnippet<Params extends unknown[]>(fn: (...params: Getters<Params>) => {
    render: () => string;
    setup?: (element: Element) => void | (() => void);
}): Snippet<Params>
import createRawSnippet

Create a snippet programmatically


reference,
	flushSync(alias) function flushSync<T = void>(fn?: (() => T) | undefined): T
import flushSync

Synchronously flush any pending updates.
Returns void if no callback is provided, otherwise returns the result of calling the callback.


reference,
	fork(alias) function fork(fn: () => void): Fork
import fork

Creates a 'fork', in which state changes are evaluated but not applied to the DOM.
This is useful for speculatively loading data (for example) when you suspect that
the user is about to take some action.




Frameworks like SvelteKit can use this to preload data when the user touches or
hovers over a link, making any subsequent navigation feel instantaneous.




The fn parameter is a synchronous function that modifies some state. The
state changes will be reverted after the fork is initialised, then reapplied
if and when the fork is eventually committed.




When it becomes clear that a fork will not be committed (e.g. because the
user navigated elsewhere), it must be discarded to avoid leaking memory.




5.42


reference,
	getAbortSignal(alias) function getAbortSignal(): AbortSignal
import getAbortSignal

Returns an AbortSignal that aborts when the current derived or effect re-runs or is destroyed.




Must be called while a derived or effect is running.



<script>
	import { getAbortSignal } from 'svelte';

	let { id } = $props();

	async function getData(id) {
		const response = await fetch(`/items/${id}`, {
			signal: getAbortSignal()
		});

		return await response.json();
	}

	const data = $derived(await getData(id));
</script>
reference,
	getAllContexts(alias) function getAllContexts<T extends Map<any, any> = Map<any, any>>(): T
import getAllContexts

Retrieves the whole context map that belongs to the current component, including entries
inherited from its ancestors. Must be called during component initialisation. Useful, for
example, if you programmatically create a component and want to pass the existing context to it.


reference,
	getContext(alias) function getContext<T>(key: any): T
import getContext

Retrieves the context set with the specified key in the current component or any of its
ancestors. If multiple components set the same key, the value from the closest one is returned.
A setContext call in the current component is only visible to getContext calls that run after it.
Must be called during component initialisation.




createContext is a type-safe alternative.


reference,
	hasContext(alias) function hasContext(key: any): boolean
import hasContext

Checks whether a given key has been set in the context of the current component or any of
its ancestors. Must be called during component initialisation.


reference,
	hydratable(alias) function hydratable<T>(key: string, fn: () => T): T
import hydratablereference,
	hydrate(alias) function hydrate<Props extends Record<string, any>, Exports extends Record<string, any>>(component: ComponentType<SvelteComponent<Props>> | Component<Props, Exports, any>, options: {} extends Props ? {
    target: Document | Element | ShadowRoot;
    props?: Props;
    events?: Record<string, (e: any) => any>;
    context?: Map<any, any>;
    intro?: boolean;
    recover?: boolean;
    transformError?: (error: unknown) => unknown;
} : {
    target: Document | Element | ShadowRoot;
    props: Props;
    events?: Record<string, (e: any) => any>;
    context?: Map<any, any>;
    intro?: boolean;
    recover?: boolean;
    transformError?: (error: unknown) => unknown;
}): Exports
import hydrate

Hydrates a component on the given target and returns the exports and potentially the props (if compiled with accessors: true) of the component


reference,
	mount(alias) function mount<Props extends Record<string, any>, Exports extends Record<string, any>>(component: ComponentType<SvelteComponent<Props>> | Component<Props, Exports, any>, options: MountOptions<Props>): Exports
import mount

Mounts a component to the given target and returns the exports and potentially the props (if compiled with accessors: true) of the component.
Transitions will play during the initial render unless the intro option is set to false.


reference,
	onDestroy(alias) function onDestroy(fn: () => any): void
import onDestroy

Schedules a callback to run immediately before the component is unmounted.




Out of onMount, beforeUpdate, afterUpdate and onDestroy, this is the
only one that runs inside a server-side component.


reference,
	onMount(alias) function onMount<T>(fn: () => NotFunction<T> | Promise<NotFunction<T>> | (() => any)): void
import onMount

onMount, like $effect, schedules a function to run as soon as the component has been mounted to the DOM.
Unlike $effect, the provided function only runs once.




It must be called during the component's initialisation (but doesn't need to live inside the component;
it can be called from an external module). If a function is returned synchronously from onMount,
it will be called when the component is unmounted.




onMount functions do not run during server-side rendering.


reference,
	setContext(alias) function setContext<T>(key: any, context: T): T
import setContext

Associates an arbitrary context object with the current component and the specified key
and returns that object. The context is then available to the component itself and all of its
descendants (including slotted content) with getContext.




Like lifecycle functions, this must be called during component initialisation.




createContext is a type-safe alternative.


reference,
	settled(alias) function settled(): Promise<void>
import settled

Returns a promise that resolves once any state changes, and asynchronous work resulting from them,
have resolved and the DOM has been updated




5.36


reference,
	tick(alias) function tick(): Promise<void>
import tick

Returns a promise that resolves once any pending state changes have been applied.


reference,
	unmount(alias) function unmount(component: Record<string, any>, options?: {
    outro?: boolean;
} | undefined): Promise<void>
import unmount

Unmounts a component that was previously mounted using mount or hydrate.




Since 5.13.0, if options.outro is true, transitions will play before the component is removed from the DOM.




Returns a Promise that resolves after transitions have completed if options.outro is true, or immediately otherwise (prior to 5.13.0, returns void).



import { mount, unmount } from 'svelte';
import App from './App.svelte';

const app = mount(App, { target: document.body });

// later...
unmount(app, { outro: true });
reference,
	untrack(alias) function untrack<T>(fn: () => T): T
import untrack

When used inside a $derived or $effect,
any state read inside fn will not be treated as a dependency.



$effect(() => {
  // this will run when `data` changes, but not when `time` changes
  save(data, {
    timestamp: untrack(() => time)
  });
});
reference
} from 'svelte';
```

## SvelteComponent[](#SvelteComponent)

This was the base class for Svelte components in Svelte 4. Svelte 5+ components are completely different under the hood. For typing, use `Component` instead. To instantiate components, use `mount` instead. See [migration guide](/docs/svelte/v5-migration-guide#Components-are-no-longer-classes) for more info.

```
class SvelteComponent<
	Props extends Record<string, any> = Record<string, any>,
	Events extends Record<string, any> = any,
	Slots extends Record<string, any> = any
> {/*…*/}
```

```
static element?: typeof HTMLElement;
```

The custom element version of the component. Only present if compiled with the `customElement` compiler option

```
[prop: string]: any;
```

```
constructor(options: ComponentConstructorOptions<Properties<Props, Slots>>);
```

* deprecated This constructor only exists when using the `asClassComponent` compatibility helper, which is a stop-gap solution. Migrate towards using `mount` instead. See [migration guide](/docs/svelte/v5-migration-guide#Components-are-no-longer-classes) for more info.

```
$destroy(): void;
```

* deprecated This method only exists when using one of the legacy compatibility helpers, which is a stop-gap solution. See [migration guide](/docs/svelte/v5-migration-guide#Components-are-no-longer-classes) for more info.

```
$on<K extends Extract<keyof Events, string>>(
	type: K,
	callback: (e: Events[K]) => void
): () => void;
```

* deprecated This method only exists when using one of the legacy compatibility helpers, which is a stop-gap solution. See [migration guide](/docs/svelte/v5-migration-guide#Components-are-no-longer-classes) for more info.

```
$set(props: Partial<Props>): void;
```

* deprecated This method only exists when using one of the legacy compatibility helpers, which is a stop-gap solution. See [migration guide](/docs/svelte/v5-migration-guide#Components-are-no-longer-classes) for more info.

## SvelteComponentTyped[](#SvelteComponentTyped)

> Use `Component` instead. See [migration guide](/docs/svelte/v5-migration-guide#Components-are-no-longer-classes) for more information.

```
class SvelteComponentTyped<
	Props extends Record<string, any> = Record<string, any>,
	Events extends Record<string, any> = any,
	Slots extends Record<string, any> = any
> extends SvelteComponent<Props, Events, Slots> {}
```

## afterUpdate[](#afterUpdate)

> Use [`$effect`](/docs/svelte/$effect) instead

Schedules a callback to run immediately after the component has been updated.

The first time the callback runs will be after the initial `onMount`.

In runes mode use `$effect` instead.

```
function afterUpdate(fn: () => void): void;
```

## beforeUpdate[](#beforeUpdate)

> Use [`$effect.pre`](/docs/svelte/$effect#$effect.pre) instead

Schedules a callback to run immediately before the component is updated after any state change.

The first time the callback runs will be before the initial `onMount`.

In runes mode use `$effect.pre` instead.

```
function beforeUpdate(fn: () => void): void;
```

## createContext[](#createContext)

> Available since 5.40.0

Returns a `[get, set, has]` triplet of functions for working with context in a type-safe way.

`get` will throw an error if `set` has not yet been called in the current component or any of its ancestors.

```
function createContext<T>(): [
	() => T,
	(context: T) => T,
	() => boolean
];
```

## createEventDispatcher[](#createEventDispatcher)

> Use callback props and/or the `$host()` rune instead — see [migration guide](/docs/svelte/v5-migration-guide#Event-changes-Component-events)

Creates an event dispatcher that can be used to dispatch [component events](/docs/svelte/legacy-on#Component-events). Event dispatchers are functions that can take two arguments: `name` and `detail`.

Component events created with `createEventDispatcher` create a [CustomEvent](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent). These events do not [bubble](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Events#Event_bubbling_and_capture). The `detail` argument corresponds to the [CustomEvent.detail](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/detail) property and can contain any type of data.

The event dispatcher can be typed to narrow the allowed event names and the type of the `detail` argument:

```
const dispatchconst dispatch: any = createEventDispatcherany<{
 loaded(property) loaded: null: null; // does not take a detail argument
 change(property) change: string: string; // takes a detail argument of type string, which is required
 optional(property) optional: number | null: number | null; // takes an optional detail argument of type number
}>();
```

```
function createEventDispatcher<
	EventMap extends Record<string, any> = any
>(): EventDispatcher<EventMap>;
```

## createRawSnippet[](#createRawSnippet)

Create a snippet programmatically

```
function createRawSnippet<Params extends unknown[]>(
	fn: (...params: Getters<Params>) => {
		render: () => string;
		setup?: (element: Element) => void | (() => void);
	}
): Snippet<Params>;
```

## flushSync[](#flushSync)

Synchronously flush any pending updates. Returns void if no callback is provided, otherwise returns the result of calling the callback.

```
function flushSync<T = void>(fn?: (() => T) | undefined): T;
```

## fork[](#fork)

> Available since 5.42

Creates a ‘fork’, in which state changes are evaluated but not applied to the DOM. This is useful for speculatively loading data (for example) when you suspect that the user is about to take some action.

Frameworks like SvelteKit can use this to preload data when the user touches or hovers over a link, making any subsequent navigation feel instantaneous.

The `fn` parameter is a synchronous function that modifies some state. The state changes will be reverted after the fork is initialised, then reapplied if and when the fork is eventually committed.

When it becomes clear that a fork will *not* be committed (e.g. because the user navigated elsewhere), it must be discarded to avoid leaking memory.

```
function fork(fn: () => void): Fork;
```

## getAbortSignal[](#getAbortSignal)

Returns an [`AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal) that aborts when the current [derived](/docs/svelte/$derived) or [effect](/docs/svelte/$effect) re-runs or is destroyed.

Must be called while a derived or effect is running.

```
<script>
	import { getAbortSignal } from 'svelte';

	let { id } = $props();

	async function getData(id) {
		const response = await fetch(`/items/${id}`, {
			signal: getAbortSignal()
		});

		return await response.json();
	}

	const data = $derived(await getData(id));
</script>
```

```
function getAbortSignal(): AbortSignal;
```

## getAllContexts[](#getAllContexts)

Retrieves the whole context map that belongs to the current component, including entries inherited from its ancestors. Must be called during component initialisation. Useful, for example, if you programmatically create a component and want to pass the existing context to it.

```
function getAllContexts<
	T extends Map<any, any> = Map<any, any>
>(): T;
```

## getContext[](#getContext)

Retrieves the context set with the specified `key` in the current component or any of its ancestors. If multiple components set the same key, the value from the closest one is returned. A `setContext` call in the current component is only visible to `getContext` calls that run after it. Must be called during component initialisation.

[`createContext`](/docs/svelte/svelte#createContext) is a type-safe alternative.

```
function getContext<T>(key: any): T;
```

## hasContext[](#hasContext)

Checks whether a given `key` has been set in the context of the current component or any of its ancestors. Must be called during component initialisation.

```
function hasContext(key: any): boolean;
```

## hydratable[](#hydratable)

```
function hydratable<T>(key: string, fn: () => T): T;
```

## hydrate[](#hydrate)

Hydrates a component on the given target and returns the exports and potentially the props (if compiled with `accessors: true`) of the component

```
function hydrate<
	Props extends Record<string, any>,
	Exports extends Record<string, any>
>(
	component:
		| ComponentType<SvelteComponent<Props>>
		| Component<Props, Exports, any>,
	options: {} extends Props
		? {
				target: Document | Element | ShadowRoot;
				props?: Props;
				events?: Record<string, (e: any) => any>;
				context?: Map<any, any>;
				intro?: boolean;
				recover?: boolean;
				transformError?: (error: unknown) => unknown;
			}
		: {
				target: Document | Element | ShadowRoot;
				props: Props;
				events?: Record<string, (e: any) => any>;
				context?: Map<any, any>;
				intro?: boolean;
				recover?: boolean;
				transformError?: (error: unknown) => unknown;
			}
): Exports;
```

## mount[](#mount)

Mounts a component to the given target and returns the exports and potentially the props (if compiled with `accessors: true`) of the component. Transitions will play during the initial render unless the `intro` option is set to `false`.

```
function mount<
	Props extends Record<string, any>,
	Exports extends Record<string, any>
>(
	component:
		| ComponentType<SvelteComponent<Props>>
		| Component<Props, Exports, any>,
	options: MountOptions<Props>
): Exports;
```

## onDestroy[](#onDestroy)

Schedules a callback to run immediately before the component is unmounted.

Out of `onMount`, `beforeUpdate`, `afterUpdate` and `onDestroy`, this is the only one that runs inside a server-side component.

```
function onDestroy(fn: () => any): void;
```

## onMount[](#onMount)

`onMount`, like [`$effect`](/docs/svelte/$effect), schedules a function to run as soon as the component has been mounted to the DOM. Unlike `$effect`, the provided function only runs once.

It must be called during the component’s initialisation (but doesn’t need to live *inside* the component; it can be called from an external module). If a function is returned *synchronously* from `onMount`, it will be called when the component is unmounted.

`onMount` functions do not run during [server-side rendering](/docs/svelte/svelte-server#render).

```
function onMount<T>(
	fn: () =>
		| NotFunction<T>
		| Promise<NotFunction<T>>
		| (() => any)
): void;
```

## setContext[](#setContext)

Associates an arbitrary `context` object with the current component and the specified `key` and returns that object. The context is then available to the component itself and all of its descendants (including slotted content) with `getContext`.

Like lifecycle functions, this must be called during component initialisation.

[`createContext`](/docs/svelte/svelte#createContext) is a type-safe alternative.

```
function setContext<T>(key: any, context: T): T;
```

## settled[](#settled)

> Available since 5.36

Returns a promise that resolves once any state changes, and asynchronous work resulting from them, have resolved and the DOM has been updated

```
function settled(): Promise<void>;
```

## tick[](#tick)

Returns a promise that resolves once any pending state changes have been applied.

```
function tick(): Promise<void>;
```

## unmount[](#unmount)

Unmounts a component that was previously mounted using `mount` or `hydrate`.

Since 5.13.0, if `options.outro` is `true`, [transitions](/docs/svelte/transition) will play before the component is removed from the DOM.

Returns a `Promise` that resolves after transitions have completed if `options.outro` is true, or immediately otherwise (prior to 5.13.0, returns `void`).

```
import { mount(alias) function mount<Props extends Record<string, any>, Exports extends Record<string, any>>(component: ComponentType<SvelteComponent<Props>> | Component<Props, Exports, any>, options: MountOptions<Props>): Exports
import mount

Mounts a component to the given target and returns the exports and potentially the props (if compiled with accessors: true) of the component.
Transitions will play during the initial render unless the intro option is set to false.


reference, unmount(alias) function unmount(component: Record<string, any>, options?: {
    outro?: boolean;
} | undefined): Promise<void>
import unmount

Unmounts a component that was previously mounted using mount or hydrate.




Since 5.13.0, if options.outro is true, transitions will play before the component is removed from the DOM.




Returns a Promise that resolves after transitions have completed if options.outro is true, or immediately otherwise (prior to 5.13.0, returns void).



import { mount, unmount } from 'svelte';
import App from './App.svelte';

const app = mount(App, { target: document.body });

// later...
unmount(app, { outro: true });
reference } from 'svelte';
import App(alias) type App = SvelteComponent<Record<string, any>, any, any>
(alias) const App: LegacyComponentType
import App from './App.svelte';

const appconst app: {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<string, any> = mount(alias) mount<Record<string, any>, {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<string, any>>(component: ComponentType<SvelteComponent<Record<string, any>, any, any>> | Component<Record<string, any>, {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<string, any>, any>, options: MountOptions<...>): {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<...>
import mount

Mounts a component to the given target and returns the exports and potentially the props (if compiled with accessors: true) of the component.
Transitions will play during the initial render unless the intro option is set to false.


reference(App(alias) const App: LegacyComponentType
import App, { target(property) target: Document | Element | ShadowRoot

Target element where the component will be mounted.


: documentvar document: Document

window.document returns a reference to the document contained in the window.




MDN Reference


.body(property) Document.body: HTMLElement

The Document.body property represents the  or  node of the current document, or null if no such element exists.




MDN Reference


 });

// later...
unmount(alias) unmount(component: Record<string, any>, options?: {
    outro?: boolean;
} | undefined): Promise<void>
import unmount

Unmounts a component that was previously mounted using mount or hydrate.




Since 5.13.0, if options.outro is true, transitions will play before the component is removed from the DOM.




Returns a Promise that resolves after transitions have completed if options.outro is true, or immediately otherwise (prior to 5.13.0, returns void).



import { mount, unmount } from 'svelte';
import App from './App.svelte';

const app = mount(App, { target: document.body });

// later...
unmount(app, { outro: true });
reference(appconst app: {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<string, any>, { outro(property) outro?: boolean | undefined: true });
```

```
function unmount(
	component: Record<string, any>,
	options?:
		| {
				outro?: boolean;
		  }
		| undefined
): Promise<void>;
```

## untrack[](#untrack)

When used inside a [`$derived`](/docs/svelte/$derived) or [`$effect`](/docs/svelte/$effect), any state read inside `fn` will not be treated as a dependency.

```
$effectfunction $effect(fn: () => void | (() => void)): void
namespace $effect

Runs code when a component is mounted to the DOM, and then whenever its dependencies change, i.e. $state or $derived values.
The timing of the execution is after the DOM has been updated.




Example:



$effect(() => console.log('The count is now ' + count));

If you return a function from the effect, it will be called right before the effect is run again, or when the component is unmounted.




Does not run during server-side rendering.




{@link https://svelte.dev/docs/svelte/$effect Documentation}


fn 

The function to execute


(() => {
	// this will run when `data` changes, but not when `time` changes
	saveany(dataany, {
		timestamp(property) timestamp: any: untrackany(() => timeany)
	});
});
```

```
function untrack<T>(fn: () => T): T;
```

## Component[](#Component)

Can be used to create strongly typed Svelte components.

#### Example:[](#Component-Example:)

You have component library on npm called `component-library`, from which you export a component called `MyComponent`. For Svelte+TypeScript users, you want to provide typings. Therefore you create a `index.d.ts`:

```
import type { Component(alias) interface Component<Props extends Record<string, any> = {}, Exports extends Record<string, any> = {}, Bindings extends keyof Props | "" = string>
import Component

Can be used to create strongly typed Svelte components.



Example:



You have component library on npm called component-library, from which
you export a component called MyComponent. For Svelte+TypeScript users,
you want to provide typings. Therefore you create a index.d.ts:



import type { Component } from 'svelte';
export declare const MyComponent: Component<{ foo: string }> {}

Typing this makes it possible for IDEs like VS Code with the Svelte extension
to provide intellisense and to use the component like this in a Svelte file
with TypeScript:



<script lang="ts">
	import { MyComponent } from "component-library";
</script>
<MyComponent foo={'bar'} />
reference } from 'svelte';
export declare const MyComponentconst MyComponent: Component<{
    foo: string;
}, {}, string>: Component(alias) interface Component<Props extends Record<string, any> = {}, Exports extends Record<string, any> = {}, Bindings extends keyof Props | "" = string>
import Component

Can be used to create strongly typed Svelte components.



Example:



You have component library on npm called component-library, from which
you export a component called MyComponent. For Svelte+TypeScript users,
you want to provide typings. Therefore you create a index.d.ts:



import type { Component } from 'svelte';
export declare const MyComponent: Component<{ foo: string }> {}

Typing this makes it possible for IDEs like VS Code with the Svelte extension
to provide intellisense and to use the component like this in a Svelte file
with TypeScript:



<script lang="ts">
	import { MyComponent } from "component-library";
</script>
<MyComponent foo={'bar'} />
reference<{ foo(property) foo: string: string }> {}
```

Typing this makes it possible for IDEs like VS Code with the Svelte extension to provide intellisense and to use the component like this in a Svelte file with TypeScript:

```
<script lang="ts">
	import { MyComponent } from "component-library";
</script>
<MyComponent foo={'bar'} />
```

```
interface Component<
	Props extends Record<string, any> = {},
	Exports extends Record<string, any> = {},
	Bindings extends keyof Props | '' = string
> {/*…*/}
```

```
(
	this: void,
	internals: ComponentInternals,
	props: Props
): {
	/**
	 * @deprecated This method only exists when using one of the legacy compatibility helpers, which
	 * is a stop-gap solution. See [migration guide](https://svelte.dev/docs/svelte/v5-migration-guide#Components-are-no-longer-classes)
	 * for more info.
	 */
	$on?(type: string, callback: (e: any) => void): () => void;
	/**
	 * @deprecated This method only exists when using one of the legacy compatibility helpers, which
	 * is a stop-gap solution. See [migration guide](https://svelte.dev/docs/svelte/v5-migration-guide#Components-are-no-longer-classes)
	 * for more info.
	 */
	$set?(props: Partial<Props>): void;
} & Exports;
```

* `internal` An internal object used by Svelte. Do not use or modify.
* `props` The props passed to the component.

```
element?: typeof HTMLElement;
```

The custom element version of the component. Only present if compiled with the `customElement` compiler option

## ComponentConstructorOptions[](#ComponentConstructorOptions)

> In Svelte 4, components are classes. In Svelte 5, they are functions. Use `mount` instead to instantiate components. See [migration guide](/docs/svelte/v5-migration-guide#Components-are-no-longer-classes) for more info.

```
interface ComponentConstructorOptions<
	Props extends Record<string, any> = Record<string, any>
> {/*…*/}
```

```
target: Element | Document | ShadowRoot;
```

```
anchor?: Element;
```

```
props?: Props;
```

```
context?: Map<any, any>;
```

```
hydrate?: boolean;
```

```
intro?: boolean;
```

```
recover?: boolean;
```

```
sync?: boolean;
```

```
idPrefix?: string;
```

```
$$inline?: boolean;
```

```
transformError?: (error: unknown) => unknown;
```

## ComponentEvents[](#ComponentEvents)

> The new `Component` type does not have a dedicated Events type. Use `ComponentProps` instead.

```
type ComponentEvents<Comp extends SvelteComponent> =
	Comp extends SvelteComponent<any, infer Events>
		? Events
		: never;
```

## ComponentInternals[](#ComponentInternals)

Internal implementation details that vary between environments

```
type ComponentInternals = Branded<{}, 'ComponentInternals'>;
```

## ComponentProps[](#ComponentProps)

Convenience type to get the props the given component expects.

Example: Ensure a variable contains the props expected by `MyComponent`:

```
import type { ComponentProps(alias) type ComponentProps<Comp extends SvelteComponent | Component<any, any>> = Comp extends SvelteComponent<infer Props extends Record<string, any>, any, any> ? Props : Comp extends Component<infer Props extends Record<string, any>, any, string> ? Props : never
import ComponentProps

Convenience type to get the props the given component expects.




Example: Ensure a variable contains the props expected by MyComponent:



import type { ComponentProps } from 'svelte';
import MyComponent from './MyComponent.svelte';

// Errors if these aren't the correct props expected by MyComponent.
const props: ComponentProps<typeof MyComponent> = { foo: 'bar' };



[!NOTE] In Svelte 4, you would do ComponentProps<MyComponent> because MyComponent was a class.






Example: A generic function that accepts some component and infers the type of its props:



import type { Component, ComponentProps } from 'svelte';
import MyComponent from './MyComponent.svelte';

function withProps<TComponent extends Component<any>>(
	component: TComponent,
	props: ComponentProps<TComponent>
) {};

// Errors if the second argument is not the correct props expected by the component in the first argument.
withProps(MyComponent, { foo: 'bar' });
reference } from 'svelte';
import MyComponent(alias) type MyComponent = SvelteComponent<Record<string, any>, any, any>
(alias) const MyComponent: LegacyComponentType
import MyComponent from './MyComponent.svelte';

// Errors if these aren't the correct props expected by MyComponent.
const propsconst props: Record<string, any>: ComponentProps(alias) type ComponentProps<Comp extends SvelteComponent | Component<any, any>> = Comp extends SvelteComponent<infer Props extends Record<string, any>, any, any> ? Props : Comp extends Component<infer Props extends Record<string, any>, any, string> ? Props : never
import ComponentProps

Convenience type to get the props the given component expects.




Example: Ensure a variable contains the props expected by MyComponent:



import type { ComponentProps } from 'svelte';
import MyComponent from './MyComponent.svelte';

// Errors if these aren't the correct props expected by MyComponent.
const props: ComponentProps<typeof MyComponent> = { foo: 'bar' };



[!NOTE] In Svelte 4, you would do ComponentProps<MyComponent> because MyComponent was a class.






Example: A generic function that accepts some component and infers the type of its props:



import type { Component, ComponentProps } from 'svelte';
import MyComponent from './MyComponent.svelte';

function withProps<TComponent extends Component<any>>(
	component: TComponent,
	props: ComponentProps<TComponent>
) {};

// Errors if the second argument is not the correct props expected by the component in the first argument.
withProps(MyComponent, { foo: 'bar' });
reference<typeof MyComponent(alias) const MyComponent: LegacyComponentType
import MyComponent> = { foo(property) foo: string: 'bar' };
```

> In Svelte 4, you would do `ComponentProps<MyComponent>` because `MyComponent` was a class.

Example: A generic function that accepts some component and infers the type of its props:

```
import type { Component(alias) interface Component<Props extends Record<string, any> = {}, Exports extends Record<string, any> = {}, Bindings extends keyof Props | "" = string>
import Component

Can be used to create strongly typed Svelte components.



Example:



You have component library on npm called component-library, from which
you export a component called MyComponent. For Svelte+TypeScript users,
you want to provide typings. Therefore you create a index.d.ts:



import type { Component } from 'svelte';
export declare const MyComponent: Component<{ foo: string }> {}

Typing this makes it possible for IDEs like VS Code with the Svelte extension
to provide intellisense and to use the component like this in a Svelte file
with TypeScript:



<script lang="ts">
	import { MyComponent } from "component-library";
</script>
<MyComponent foo={'bar'} />
reference, ComponentProps(alias) type ComponentProps<Comp extends SvelteComponent | Component<any, any>> = Comp extends SvelteComponent<infer Props extends Record<string, any>, any, any> ? Props : Comp extends Component<infer Props extends Record<string, any>, any, string> ? Props : never
import ComponentProps

Convenience type to get the props the given component expects.




Example: Ensure a variable contains the props expected by MyComponent:



import type { ComponentProps } from 'svelte';
import MyComponent from './MyComponent.svelte';

// Errors if these aren't the correct props expected by MyComponent.
const props: ComponentProps<typeof MyComponent> = { foo: 'bar' };



[!NOTE] In Svelte 4, you would do ComponentProps<MyComponent> because MyComponent was a class.






Example: A generic function that accepts some component and infers the type of its props:



import type { Component, ComponentProps } from 'svelte';
import MyComponent from './MyComponent.svelte';

function withProps<TComponent extends Component<any>>(
	component: TComponent,
	props: ComponentProps<TComponent>
) {};

// Errors if the second argument is not the correct props expected by the component in the first argument.
withProps(MyComponent, { foo: 'bar' });
reference } from 'svelte';
import MyComponent(alias) type MyComponent = SvelteComponent<Record<string, any>, any, any>
(alias) const MyComponent: LegacyComponentType
import MyComponent from './MyComponent.svelte';

function withPropsfunction withProps<TComponent extends Component<any>>(component: TComponent, props: ComponentProps<TComponent>): void<TComponent(type parameter) TComponent in withProps<TComponent extends Component<any>>(component: TComponent, props: ComponentProps<TComponent>): void extends Component(alias) interface Component<Props extends Record<string, any> = {}, Exports extends Record<string, any> = {}, Bindings extends keyof Props | "" = string>
import Component

Can be used to create strongly typed Svelte components.



Example:



You have component library on npm called component-library, from which
you export a component called MyComponent. For Svelte+TypeScript users,
you want to provide typings. Therefore you create a index.d.ts:



import type { Component } from 'svelte';
export declare const MyComponent: Component<{ foo: string }> {}

Typing this makes it possible for IDEs like VS Code with the Svelte extension
to provide intellisense and to use the component like this in a Svelte file
with TypeScript:



<script lang="ts">
	import { MyComponent } from "component-library";
</script>
<MyComponent foo={'bar'} />
reference<any>>(
	component(parameter) component: TComponent extends Component<any>: TComponent(type parameter) TComponent in withProps<TComponent extends Component<any>>(component: TComponent, props: ComponentProps<TComponent>): void,
	props(parameter) props: ComponentProps<TComponent>: ComponentProps(alias) type ComponentProps<Comp extends SvelteComponent | Component<any, any>> = Comp extends SvelteComponent<infer Props extends Record<string, any>, any, any> ? Props : Comp extends Component<infer Props extends Record<string, any>, any, string> ? Props : never
import ComponentProps

Convenience type to get the props the given component expects.




Example: Ensure a variable contains the props expected by MyComponent:



import type { ComponentProps } from 'svelte';
import MyComponent from './MyComponent.svelte';

// Errors if these aren't the correct props expected by MyComponent.
const props: ComponentProps<typeof MyComponent> = { foo: 'bar' };



[!NOTE] In Svelte 4, you would do ComponentProps<MyComponent> because MyComponent was a class.






Example: A generic function that accepts some component and infers the type of its props:



import type { Component, ComponentProps } from 'svelte';
import MyComponent from './MyComponent.svelte';

function withProps<TComponent extends Component<any>>(
	component: TComponent,
	props: ComponentProps<TComponent>
) {};

// Errors if the second argument is not the correct props expected by the component in the first argument.
withProps(MyComponent, { foo: 'bar' });
reference<TComponent(type parameter) TComponent in withProps<TComponent extends Component<any>>(component: TComponent, props: ComponentProps<TComponent>): void>
) {};

// Errors if the second argument is not the correct props expected by the component in the first argument.
withPropsfunction withProps<LegacyComponentType>(component: LegacyComponentType, props: Record<string, any>): void(MyComponent(alias) const MyComponent: LegacyComponentType
import MyComponent, { foo(property) foo: string: 'bar' });
```

```
type ComponentProps<
	Comp extends SvelteComponent | Component<any, any>
> =
	Comp extends SvelteComponent<infer Props>
		? Props
		: Comp extends Component<infer Props, any>
			? Props
			: never;
```

## ComponentType[](#ComponentType)

> This type is obsolete when working with the new `Component` type.

```
type ComponentType<
	Comp extends SvelteComponent = SvelteComponent
> = (new (
	options: ComponentConstructorOptions<
		Comp extends SvelteComponent<infer Props>
			? Props
			: Record<string, any>
	>
) => Comp) & {
	/** The custom element version of the component. Only present if compiled with the `customElement` compiler option */
	element?: typeof HTMLElement;
};
```

## EventDispatcher[](#EventDispatcher)

```
interface EventDispatcher<
	EventMap extends Record<string, any>
> {/*…*/}
```

```
<Type extends keyof EventMap>(
	...args: null extends EventMap[Type]
		? [type: Type, parameter?: EventMap[Type] | null | undefined, options?: DispatchOptions]
		: undefined extends EventMap[Type]
			? [type: Type, parameter?: EventMap[Type] | null | undefined, options?: DispatchOptions]
			: [type: Type, parameter: EventMap[Type], options?: DispatchOptions]
): boolean;
```

## Fork[](#Fork)

> Available since 5.42

Represents work that is happening off-screen, such as data being preloaded in anticipation of the user navigating

```
interface Fork {/*…*/}
```

```
commit(): Promise<void>;
```

Commit the fork. The promise will resolve once the state change has been applied

```
discard(): void;
```

Discard the fork

## MountOptions[](#MountOptions)

Defines the options accepted by the `mount()` function.

```
type MountOptions<
	Props extends Record<string, any> = Record<string, any>
> = {
	/**
	 * Target element where the component will be mounted.
	 */
	target: Document | Element | ShadowRoot;
	/**
	 * Optional node inside `target`. When specified, it is used to render the component immediately before it.
	 */
	anchor?: Node;
	/**
	 * Allows the specification of events.
	 * @deprecated Use callback props instead.
	 */
	events?: Record<string, (e: any) => any>;
	/**
	 * Can be accessed via `getContext()` at the component level.
	 */
	context?: Map<any, any>;
	/**
	 * Whether or not to play transitions on initial render.
	 * @default true
	 */
	intro?: boolean;
	/**
	 * A function that transforms errors caught by error boundaries before they are passed to the `failed` snippet.
	 * Defaults to the identity function.
	 */
	transformError?: (
		error: unknown
	) => unknown | Promise<unknown>;
} & ({} extends Props
	? {
			/**
			 * Component properties.
			 */
			props?: Props;
		}
	: {
			/**
			 * Component properties.
			 */
			props: Props;
		});
```

## Snippet[](#Snippet)

The type of a `#snippet` block. You can use it to (for example) express that your component expects a snippet of a certain type:

```
let { bannerlet banner: Snippet<[{
    text: string;
}]> }: { banner(property) banner: Snippet<[{
    text: string;
}]>: Snippettype Snippet = /*unresolved*/ any<[{ text(property) text: string: string }]> } = $propsfunction $props(): any
namespace $props

Declares the props that a component accepts. Example:



let { optionalProp = 42, requiredProp, bindableProp = $bindable() }: { optionalProp?: number; requiredProps: string; bindableProp: boolean } = $props();

{@link https://svelte.dev/docs/svelte/$props Documentation}


();
```

You can only call a snippet through the `{@render ...}` tag.

See the [snippet documentation](/docs/svelte/snippet) for more info.

```
interface Snippet<Parameters extends unknown[] = []> {/*…*/}
```

```
(
	this: void,
	// this conditional allows tuples but not arrays. Arrays would indicate a
	// rest parameter type, which is not supported. If rest parameters are added
	// in the future, the condition can be removed.
	...args: number extends Parameters['length'] ? never : Parameters
): {
	'{@render ...} must be called with a Snippet': "import type { Snippet } from 'svelte'";
} & typeof SnippetReturn;
```

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/98-reference/20-svelte.md) [llms.txt](/docs/svelte/svelte/llms.txt)

previous next

[Frequently asked questions](/docs/svelte/faq) [svelte/action](/docs/svelte/svelte-action)

----
url: https://svelte.dev/docs/svelte/svelte-server
----

[Skip to main content](#main)

```
import { render(alias) function render<Comp extends SvelteComponent<any> | Component<any>, Props extends ComponentProps<Comp> = ComponentProps<Comp>>(...args: {} extends Props ? [component: Comp extends SvelteComponent<any> ? ComponentType<Comp> : Comp, options?: {
    props?: Omit<Props, "$$slots" | "$$events">;
    context?: Map<any, any>;
    idPrefix?: string;
    csp?: Csp;
    transformError?: (error: unknown) => unknown | Promise<unknown>;
}] : [component: Comp extends SvelteComponent<any> ? ComponentType<Comp> : Comp, options: {
    props: Omit<Props, "$$slots" | "$$events">;
    context?: Map<any, any>;
    idPrefix?: string;
    csp?: Csp;
    transformError?: (error: unknown) => unknown | Promise<unknown>;
}]): RenderOutput
import render

Only available on the server and when compiling with the server option.
Takes a component and returns an object with body and head properties on it, which you can use to populate the HTML when server-rendering your app.


reference } from 'svelte/server';
```

## render[](#render)

Only available on the server and when compiling with the `server` option. Takes a component and returns an object with `body` and `head` properties on it, which you can use to populate the HTML when server-rendering your app.

```
function render<
	Comp extends SvelteComponent<any> | Component<any>,
	Props extends ComponentProps<Comp> = ComponentProps<Comp>
>(
	...args: {} extends Props
		? [
				component: Comp extends SvelteComponent<any>
					? ComponentType<Comp>
					: Comp,
				options?: {
					props?: Omit<Props, '$$slots' | '$$events'>;
					context?: Map<any, any>;
					idPrefix?: string;
					csp?: Csp;
					transformError?: (
						error: unknown
					) => unknown | Promise<unknown>;
				}
			]
		: [
				component: Comp extends SvelteComponent<any>
					? ComponentType<Comp>
					: Comp,
				options: {
					props: Omit<Props, '$$slots' | '$$events'>;
					context?: Map<any, any>;
					idPrefix?: string;
					csp?: Csp;
					transformError?: (
						error: unknown
					) => unknown | Promise<unknown>;
				}
			]
): RenderOutput;
```

## Csp[](#Csp)

```
type Csp = { nonce?: string; hash?: boolean };
```

## RenderOutput[](#RenderOutput)

```
type RenderOutput = SyncRenderOutput &
	PromiseLike<SyncRenderOutput>;
```

## Sha256Source[](#Sha256Source)

```
type Sha256Source = `sha256-${string}`;
```

## SyncRenderOutput[](#SyncRenderOutput)

```
interface SyncRenderOutput {/*…*/}
```

```
head: string;
```

HTML that goes into the `<head>`

```
html: string;
```

* deprecated use `body` instead

```
body: string;
```

HTML that goes somewhere into the `<body>`

```
hashes: {
	script: Sha256Source[];
};
```

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/98-reference/21-svelte-server.md) [llms.txt](/docs/svelte/svelte-server/llms.txt)

previous next

[svelte/reactivity](/docs/svelte/svelte-reactivity) [svelte/store](/docs/svelte/svelte-store)

----
url: https://svelte.dev/docs/svelte/svelte-server/llms.txt
----

````
```js
// @noErrors
import { render } from 'svelte/server';
```

## render

Only available on the server and when compiling with the `server` option.
Takes a component and returns an object with `body` and `head` properties on it, which you can use to populate the HTML when server-rendering your app.

<div class="ts-block">

```dts
function render<
	Comp extends SvelteComponent<any> | Component<any>,
	Props extends ComponentProps<Comp> = ComponentProps<Comp>
>(
	...args: {} extends Props
		? [
				component: Comp extends SvelteComponent<any>
					? ComponentType<Comp>
					: Comp,
				options?: {
					props?: Omit<Props, '$$slots' | '$$events'>;
					context?: Map<any, any>;
					idPrefix?: string;
					csp?: Csp;
					transformError?: (
						error: unknown
					) => unknown | Promise<unknown>;
				}
			]
		: [
				component: Comp extends SvelteComponent<any>
					? ComponentType<Comp>
					: Comp,
				options: {
					props: Omit<Props, '$$slots' | '$$events'>;
					context?: Map<any, any>;
					idPrefix?: string;
					csp?: Csp;
					transformError?: (
						error: unknown
					) => unknown | Promise<unknown>;
				}
			]
): RenderOutput;
```

</div>



## Csp

<div class="ts-block">

```dts
type Csp = { nonce?: string; hash?: boolean };
```

</div>

## RenderOutput

<div class="ts-block">

```dts
type RenderOutput = SyncRenderOutput &
	PromiseLike<SyncRenderOutput>;
```

</div>

## Sha256Source

<div class="ts-block">

```dts
type Sha256Source = `sha256-${string}`;
```

</div>

## SyncRenderOutput

<div class="ts-block">

```dts
interface SyncRenderOutput {/*…*/}
```

<div class="ts-block-property">

```dts
head: string;
```

<div class="ts-block-property-details">

HTML that goes into the `<head>`

</div>
</div>

<div class="ts-block-property">

```dts
html: string;
```

<div class="ts-block-property-details">

<div class="ts-block-property-bullets">

- <span class="tag deprecated">deprecated</span> use `body` instead

</div>

</div>
</div>

<div class="ts-block-property">

```dts
body: string;
```

<div class="ts-block-property-details">

HTML that goes somewhere into the `<body>`

</div>
</div>

<div class="ts-block-property">

```dts
hashes: {
	script: Sha256Source[];
};
```

<div class="ts-block-property-details"></div>
</div></div>
````

----
url: https://svelte.dev/docs/svelte/browser-support
----

[Skip to main content](#main)

The table below shows the minimum browser versions Svelte is expected to work in, derived from the browser APIs used by Svelte’s internal code.

| Browser           | Minimum version |
| ----------------- | --------------- |
| Chrome/Edge       | 87              |
| Firefox           | 83              |
| Safari            | 14              |
| Opera             | 73              |
| Opera (Android)   | 62              |
| Samsung Internet  | 14.0            |
| Android WebView   | 87              |
| Internet Explorer | not supported   |

> This equates to a [Baseline](https://web-platform-dx.github.io/baseline/) target of 2020.

This table only covers Svelte itself. It does not include [SvelteKit](/docs/kit), other Svelte libraries, or your own code.

## Exceptions[](#Exceptions)

A few Svelte features require a higher minimum browser version. You’ll only need to take the following table into consideration if you use these specific features.

| Feature                                                          | Chrome/Edge | Firefox | Safari        |
| ---------------------------------------------------------------- | ----------- | ------- | ------------- |
| [`$state.snapshot`](/docs/svelte/$state#$state.snapshot)         | 98          | 94      | 15.4          |
| [`bind:devicePixelContentBoxSize`](/docs/svelte/bind#Dimensions) | —           | 93      | not supported |
| [`flip` from `svelte/animate`](/docs/svelte/svelte-animate#flip) | —           | 126     | —             |

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/07-misc/05-browser-support.md) [llms.txt](/docs/svelte/browser-support/llms.txt)

previous next

[Custom elements](/docs/svelte/custom-elements) [Svelte 4 migration guide](/docs/svelte/v4-migration-guide)

----
url: https://svelte.dev/docs/svelte/hydratable
----

[Skip to main content](#main)

In Svelte, when you want to render asynchronous content data on the server, you can simply `await` it. This is great! However, it comes with a pitfall: when hydrating that content on the client, Svelte has to redo the asynchronous work, which blocks hydration for however long it takes:

```
<script>
  import { getUser } from 'my-database-library';

  // This will get the user on the server, render the user's name into the h1,
  // and then, during hydration on the client, it will get the user _again_,
  // blocking hydration until it's done.
  const user = await getUser();
</script>

<h1>{user.name}</h1>
```

That’s silly, though. If we’ve already done the hard work of getting the data on the server, we don’t want to get it again during hydration on the client. `hydratable` is a low-level API built to solve this problem. You probably won’t need this very often — it will be used behind the scenes by whatever datafetching library you use. For example, it powers [remote functions in SvelteKit](/docs/kit/remote-functions).

To fix the example above:

```
<script>
  import { hydratable } from 'svelte';
  import { getUser } from 'my-database-library';

  // During server rendering, this will serialize and stash the result of `getUser`, associating
  // it with the provided key and baking it into the `head` content. During hydration, it will
  // look for the serialized version, returning it instead of running `getUser`. After hydration
  // is done, if it's called again, it'll simply invoke `getUser`.
  const user = await hydratable('user', () => getUser());
</script>

<h1>{user.name}</h1>
```

This API can also be used to provide access to random or time-based values that are stable between server rendering and hydration. For example, to get a random number that doesn’t update on hydration:

```
import { hydratable(alias) function hydratable<T>(key: string, fn: () => T): T
import hydratablereference } from 'svelte';
const randconst rand: number = hydratable(alias) hydratable<number>(key: string, fn: () => number): number
import hydratablereference('random', () => Mathvar Math: Math

An intrinsic object that provides basic mathematics functionality and constants.


.random(method) Math.random(): number

Returns a pseudorandom number between 0 and 1.


());
```

If you’re a library author, be sure to prefix the keys of your `hydratable` values with the name of your library so that your keys don’t conflict with other libraries.

## Serialization[](#Serialization)

All data returned from a `hydratable` function must be serializable. But this doesn’t mean you’re limited to JSON — Svelte uses [`devalue`](https://npmjs.com/package/devalue), which can serialize all sorts of things including `Map`, `Set`, `URL`, and `BigInt`. Check the documentation page for a full list. In addition to these, thanks to some Svelte magic, you can also fearlessly use promises:

```
<script>
  import { hydratable } from 'svelte';
  const promises = hydratable('random', () => {
	return {
	  one: Promise.resolve(1),
	  two: Promise.resolve(2)
	}
  });
</script>

{await promises.one}
{await promises.two}
```

## CSP[](#CSP)

`hydratable` adds an inline `<script>` block to the `head` returned from `render`. If you’re using [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP) (CSP), this script will likely fail to run. You can provide a `nonce` to `render`:

server

```
const nonceconst nonce: `${string}-${string}-${string}-${string}-${string}` = cryptovar crypto: Crypto

MDN Reference


.randomUUID(method) Crypto.randomUUID(): `${string}-${string}-${string}-${string}-${string}`

The randomUUID() method of the Crypto interface is used to generate a v4 UUID using a cryptographically secure random number generator.
Available only in secure contexts.




MDN Reference


();

const { headconst head: string

HTML that goes into the <head>


, bodyconst body: string

HTML that goes somewhere into the <body>


 } = await render(alias) render<SvelteComponent<Record<string, any>, any, any>, Record<string, any>>(component: ComponentType<SvelteComponent<Record<string, any>, any, any>>, options?: {
    props?: Omit<Record<string, any>, "$$slots" | "$$events"> | undefined;
    context?: Map<any, any>;
    idPrefix?: string;
    csp?: Csp;
    transformError?: ((error: unknown) => unknown | Promise<unknown>) | undefined;
} | undefined): RenderOutput
import render

Only available on the server and when compiling with the server option.
Takes a component and returns an object with body and head properties on it, which you can use to populate the HTML when server-rendering your app.


reference(App(alias) const App: LegacyComponentType
import App, {
	csp(property) csp?: Csp | undefined: { nonce(property) nonce?: string | undefined }
});
```

This will add the `nonce` to the script block, on the assumption that you will later add the same nonce to the CSP header of the document that contains it:

server

```
responselet response: Response.headers(property) Response.headers: Headers

The headers read-only property of the Response interface contains the Headers object associated with the response.




MDN Reference


.set(method) Headers.set(name: string, value: string): void

The set() method of the Headers interface sets a new value for an existing header inside a Headers object, or adds the header if it does not already exist.




MDN Reference


(
  'Content-Security-Policy',
  `script-src 'nonce-${noncelet nonce: string}'`
 );
```

It’s essential that a `nonce` — which, British slang definition aside, means ‘number used once’ — is only used when dynamically server rendering an individual response.

If instead you are generating static HTML ahead of time, you must use hashes instead:

server

```
const { headconst head: string

HTML that goes into the <head>


, bodyconst body: string

HTML that goes somewhere into the <body>


, hashesconst hashes: {
    script: Sha256Source[];
} } = await render(alias) render<SvelteComponent<Record<string, any>, any, any>, Record<string, any>>(component: ComponentType<SvelteComponent<Record<string, any>, any, any>>, options?: {
    props?: Omit<Record<string, any>, "$$slots" | "$$events"> | undefined;
    context?: Map<any, any>;
    idPrefix?: string;
    csp?: Csp;
    transformError?: ((error: unknown) => unknown | Promise<unknown>) | undefined;
} | undefined): RenderOutput
import render

Only available on the server and when compiling with the server option.
Takes a component and returns an object with body and head properties on it, which you can use to populate the HTML when server-rendering your app.


reference(App(alias) const App: LegacyComponentType
import App, {
	csp(property) csp?: Csp | undefined: { hash(property) hash?: boolean | undefined: true }
});
```

`hashes.script` will be an array of strings like `["sha256-abcd123"]`. As with `nonce`, the hashes should be used in your CSP header:

server

```
responselet response: Response.headers(property) Response.headers: Headers

The headers read-only property of the Response interface contains the Headers object associated with the response.




MDN Reference


.set(method) Headers.set(name: string, value: string): void

The set() method of the Headers interface sets a new value for an existing header inside a Headers object, or adds the header if it does not already exist.




MDN Reference


(
  'Content-Security-Policy',
  `script-src ${hasheslet hashes: {
    script: string[];
}.script(property) script: string[].map(method) Array<string>.map<string>(callbackfn: (value: string, index: number, array: string[]) => string, thisArg?: any): string[]

Calls a defined callback function on each element of an array, and returns an array that contains the results.


callbackfn 

A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array.


thisArg 

An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.


((hash(parameter) hash: string) => `'${hash(parameter) hash: string}'`).join(method) Array<string>.join(separator?: string): string

Adds all the elements of an array into a string, separated by the specified separator string.


separator 

A string used to separate one element of the array from the next in the resulting string. If omitted, the array elements are separated with a comma.


(' ')}`
 );
```

We recommend using `nonce` over hash if you can, as `hash` will interfere with streaming SSR in the future.

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/06-runtime/05-hydratable.md) [llms.txt](/docs/svelte/hydratable/llms.txt)

previous next

[Imperative component API](/docs/svelte/imperative-component-api) [Best practices](/docs/svelte/best-practices)

----
url: https://svelte.dev/docs/svelte/@render
----

[Skip to main content](#main)

To render a [snippet](snippet), use a `{@render ...}` tag.

```
{#snippet sum(a, b)}
	<p>{a} + {b} = {a + b}</p>
{/snippet}

{@render sum(1, 2)}
{@render sum(3, 4)}
{@render sum(5, 6)}
```

The expression can be an identifier like `sum`, or an arbitrary JavaScript expression:

```
{@render (cool ? coolSnippet : lameSnippet)()}
```

## Optional snippets[](#Optional-snippets)

If the snippet is potentially undefined — for example, because it’s an incoming prop — then you can use optional chaining to only render it when it *is* defined:

```
{@render children?.()}
```

Alternatively, use an [`{#if ...}`](if) block with an `:else` clause to render fallback content:

```
{#if children}
	{@render children()}
{:else}
	<p>fallback content</p>
{/if}
```

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/03-template-syntax/07-@render.md) [llms.txt](/docs/svelte/@render/llms.txt)

previous next

[{#snippet ...}](/docs/svelte/snippet) [{@html ...}](/docs/svelte/@html)

----
url: https://svelte.dev/docs/svelte/v5-migration-guide
----

[Skip to main content](#main)

Version 5 comes with an overhauled syntax and reactivity system. While it may look different at first, you’ll soon notice many similarities. This guide goes over the changes in detail and shows you how to upgrade. Along with it, we also provide information on *why* we did these changes.

You don’t have to migrate to the new syntax right away — Svelte 5 still supports the old Svelte 4 syntax, and you can mix and match components using the new syntax with components using the old and vice versa. We expect many people to be able to upgrade with only a few lines of code changed initially. There’s also a [migration script](#Migration-script) that helps you with many of these steps automatically.

## Reactivity syntax changes[](#Reactivity-syntax-changes)

At the heart of Svelte 5 is the new runes API. Runes are basically compiler instructions that inform Svelte about reactivity. Syntactically, runes are functions starting with a dollar-sign.

### let → $state[](#Reactivity-syntax-changes-let-$state)

In Svelte 4, a `let` declaration at the top level of a component was implicitly reactive. In Svelte 5, things are more explicit: a variable is reactive when created using the `$state` rune. Let’s migrate the counter to runes mode by wrapping the counter in `$state`:

```
<script>
	let count = $state(0);
</script>
```

Nothing else changes. `count` is still the number itself, and you read and write directly to it, without a wrapper like `.value` or `getCount()`.

> Why we did this
>
> `let` being implicitly reactive at the top level worked great, but it meant that reactivity was constrained — a `let` declaration anywhere else was not reactive. This forced you to resort to using stores when refactoring code out of the top level of components for reuse. This meant you had to learn an entirely separate reactivity model, and the result often wasn’t as nice to work with. Because reactivity is more explicit in Svelte 5, you can keep using the same API outside the top level of components. Head to [the tutorial](/tutorial) to learn more.

### $: → $derived/$effect[](#Reactivity-syntax-changes-$:-$derived-$effect)

In Svelte 4, a `$:` statement at the top level of a component could be used to declare a derivation, i.e. state that is entirely defined through a computation of other state. In Svelte 5, this is achieved using the `$derived` rune:

```
<script>
	let count = $state(0);
	$: const double = $derived(count * 2);
</script>
```

As with `$state`, nothing else changes. `double` is still the number itself, and you read it directly, without a wrapper like `.value` or `getDouble()`.

A `$:` statement could also be used to create side effects. In Svelte 5, this is achieved using the `$effect` rune:

```
<script>
	let count = $state(0);

	$:$effect(() => {
		if (count > 5) {
			alert('Count is too high!');
		}
	});
</script>
```

Note that [when `$effect` runs is different]($effect#Understanding-dependencies) than when `$:` runs.

> Why we did this
>
> `$:` was a great shorthand and easy to get started with: you could slap a `$:` in front of most code and it would somehow work. This intuitiveness was also its drawback the more complicated your code became, because it wasn’t as easy to reason about. Was the intent of the code to create a derivation, or a side effect? With `$derived` and `$effect`, you have a bit more up-front decision making to do (spoiler alert: 90% of the time you want `$derived`), but future-you and other developers on your team will have an easier time.
>
> There were also gotchas that were hard to spot:
>
> * `$:` only updated directly before rendering, which meant you could read stale values in-between rerenders
> * `$:` only ran once per tick, which meant that statements may run less often than you think
> * `$:` dependencies were determined through static analysis of the dependencies. This worked in most cases, but could break in subtle ways during a refactoring where dependencies would be for example moved into a function and no longer be visible as a result
> * `$:` statements were also ordered by using static analysis of the dependencies. In some cases there could be ties and the ordering would be wrong as a result, needing manual interventions. Ordering could also break while refactoring code and some dependencies no longer being visible as a result.
>
> Lastly, it wasn’t TypeScript-friendly (our editor tooling had to jump through some hoops to make it valid for TypeScript), which was a blocker for making Svelte’s reactivity model truly universal.
>
> `$derived` and `$effect` fix all of these by
>
> * always returning the latest value
> * running as often as needed to be stable
> * determining the dependencies at runtime, and therefore being immune to refactorings
> * executing dependencies as needed and therefore being immune to ordering problems
> * being TypeScript-friendly

### export let → $props[](#Reactivity-syntax-changes-export-let-$props)

In Svelte 4, properties of a component were declared using `export let`. Each property was one declaration. In Svelte 5, all properties are declared through the `$props` rune, through destructuring:

```
<script>
	export let optional = 'unset';
	export let required;
	let { optional = 'unset', required } = $props();
</script>
```

There are multiple cases where declaring properties becomes less straightforward than having a few `export let` declarations:

* you want to rename the property, for example because the name is a reserved identifier (e.g. `class`)
* you don’t know which other properties to expect in advance
* you want to forward every property to another component

All these cases need special syntax in Svelte 4:

* renaming: `export { klass as class}`
* other properties: `$$restProps`
* all properties `$$props`

In Svelte 5, the `$props` rune makes this straightforward without any additional Svelte-specific syntax:

* renaming: use property renaming `let { class: klass } = $props();`
* other properties: use spreading `let { foo, bar, ...rest } = $props();`
* all properties: don’t destructure `let props = $props();`

```
<script>
	let klass = '';
	export { klass as class};
	let { class: klass, ...rest } = $props();
</script>
<button class={klass} {...$$restPropsrest}>click me</button>
```

> Why we did this
>
> `export let` was one of the more controversial API decisions, and there was a lot of debate about whether you should think about a property being `export`ed or `import`ed. `$props` doesn’t have this trait. It’s also in line with the other runes, and the general thinking reduces to “everything special to reactivity in Svelte is a rune”.
>
> There were also a lot of limitations around `export let`, which required additional API, as shown above. `$props` unite this in one syntactical concept that leans heavily on regular JavaScript destructuring syntax.

## Event changes[](#Event-changes)

Event handlers have been given a facelift in Svelte 5. Whereas in Svelte 4 we use the `on:` directive to attach an event listener to an element, in Svelte 5 they are properties like any other (in other words — remove the colon):

```
<script>
	let count = $state(0);
</script>

<button on:click={() => count++}>
	clicks: {count}
</button>
```

Since they’re just properties, you can use the normal shorthand syntax...

```
<script>
	let count = $state(0);

	function onclick() {
		count++;
	}
</script>

<button {onclick}>
	clicks: {count}
</button>
```

...though when using a named event handler function it’s usually better to use a more descriptive name.

### Component events[](#Event-changes-Component-events)

In Svelte 4, components could emit events by creating a dispatcher with `createEventDispatcher`.

This function is deprecated in Svelte 5. Instead, components should accept *callback props* — which means you then pass functions as properties to these components:

App

```
<script>
	import Pump from './Pump.svelte';

	let size = $state(15);
	let burst = $state(false);

	function reset() {
		size = 15;
		burst = false;
	}
</script>

<Pump
	on:inflate={(power) => {
		size += power.detail;
		if (size > 75) burst = true;
	}}
	on:deflate={(power) => {
		if (size > 0) size -= power.detail;
	}}
/>

{#if burst}
	<button onclick={reset}>new balloon</button>
	<span class="boom">💥</span>
{:else}
	<span class="balloon" style="scale: {0.01 * size}">
		🎈
	</span>
{/if}
```

```
<script lang="ts">
	import Pump from './Pump.svelte';

	let size = $state(15);
	let burst = $state(false);

	function reset() {
		size = 15;
		burst = false;
	}
</script>

<Pump
	on:inflate={(power) => {
		size += power.detail;
		if (size > 75) burst = true;
	}}
	on:deflate={(power) => {
		if (size > 0) size -= power.detail;
	}}
/>

{#if burst}
	<button onclick={reset}>new balloon</button>
	<span class="boom">💥</span>
{:else}
	<span class="balloon" style="scale: {0.01 * size}">
		🎈
	</span>
{/if}
```

Pump

```
<script>
	import { createEventDispatcher } from 'svelte';
	const dispatch = createEventDispatcher();

	let { inflate, deflate } = $props();
	let power = $state(5);
</script>

<button onclick={() => dispatch('inflate', power)inflate(power)}>
	inflate
</button>
<button onclick={() => dispatch('deflate', power)deflate(power)}>
	deflate
</button>
<button onclick={() => power--}>-</button>
Pump power: {power}
<button onclick={() => power++}>+</button>
```

```
<script lang="ts">
	import { createEventDispatcher } from 'svelte';
	const dispatch = createEventDispatcher();

	let { inflate, deflate } = $props();
	let power = $state(5);
</script>

<button onclick={() => dispatch('inflate', power)inflate(power)}>
	inflate
</button>
<button onclick={() => dispatch('deflate', power)deflate(power)}>
	deflate
</button>
<button onclick={() => power--}>-</button>
Pump power: {power}
<button onclick={() => power++}>+</button>
```

### Bubbling events[](#Event-changes-Bubbling-events)

Instead of doing `<button on:click>` to ‘forward’ the event from the element to the component, the component should accept an `onclick` callback prop:

```
<script>
	let { onclick } = $props();
</script>

<button on:click {onclick}>
	click me
</button>
```

Note that this also means you can ‘spread’ event handlers onto the element along with other props instead of tediously forwarding each event separately:

```
<script>
	let props = $props();
</script>

<button {...$$props} on:click on:keydown on:all_the_other_stuff {...props}>
	click me
</button>
```

### Event modifiers[](#Event-changes-Event-modifiers)

In Svelte 4, you can add event modifiers to handlers:

```
<button on:click|once|preventDefault={handler}>...</button>
```

Modifiers are specific to `on:` and so do not work with modern event handlers. Adding things like `event.preventDefault()` inside the handler itself is preferable, since all the logic lives in one place rather than being split between handler and modifiers.

Since event handlers are just functions, you can create your own wrappers as necessary:

```
<script>
	function once(fn) {
		return function (event) {
			if (fn) fn.call(this, event);
			fn = null;
		};
	}

	function preventDefault(fn) {
		return function (event) {
			event.preventDefault();
			fn.call(this, event);
		};
	}
</script>

<button onclick={once(preventDefault(handler))}>...</button>
```

There are three modifiers — `capture`, `passive` and `nonpassive` — that can’t be expressed as wrapper functions, since they need to be applied when the event handler is bound rather than when it runs.

For `capture`, we add the modifier to the event name:

```
<button onclickcapture={...}>...</button>
```

Changing the [`passive`](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#using_passive_listeners) option of an event handler, meanwhile, is not something to be done lightly. If you have a use case for it — and you probably don’t! — then you will need to use an action to apply the event handler yourself.

### Multiple event handlers[](#Event-changes-Multiple-event-handlers)

In Svelte 4, this is possible:

```
<button on:click={one} on:click={two}>...</button>
```

Duplicate attributes/properties on elements — which now includes event handlers — are not allowed. Instead, do this:

```
<button
	onclick={(e) => {
		one(e);
		two(e);
	}}
>
	...
</button>
```

When spreading props, local event handlers must go *after* the spread, or they risk being overwritten:

```
<button
	{...props}
	onclick={(e) => {
		doStuff(e);
		props.onclick?.(e);
	}}
>
	...
</button>
```

> Why we did this
>
> `createEventDispatcher` was always a bit boilerplate-y:
>
> * import the function
> * call the function to get a dispatch function
> * call said dispatch function with a string and possibly a payload
> * retrieve said payload on the other end through a `.detail` property, because the event itself was always a `CustomEvent`
>
> It was always possible to use component callback props, but because you had to listen to DOM events using `on:`, it made sense to use `createEventDispatcher` for component events due to syntactical consistency. Now that we have event attributes (`onclick`), it’s the other way around: Callback props are now the more sensible thing to do.
>
> The removal of event modifiers is arguably one of the changes that seems like a step back for those who’ve liked the shorthand syntax of event modifiers. Given that they are not used that frequently, we traded a smaller surface area for more explicitness. Modifiers also were inconsistent, because most of them were only usable on DOM elements.
>
> Multiple listeners for the same event are also no longer possible, but it was something of an anti-pattern anyway, since it impedes readability: if there are many attributes, it becomes harder to spot that there are two handlers unless they are right next to each other. It also implies that the two handlers are independent, when in fact something like `event.stopImmediatePropagation()` inside `one` would prevent `two` from being called.
>
> By deprecating `createEventDispatcher` and the `on:` directive in favour of callback props and normal element properties, we:
>
> * reduce Svelte’s learning curve
> * remove boilerplate, particularly around `createEventDispatcher`
> * remove the overhead of creating `CustomEvent` objects for events that may not even have listeners
> * add the ability to spread event handlers
> * add the ability to know which event handlers were provided to a component
> * add the ability to express whether a given event handler is required or optional
> * increase type safety (previously, it was effectively impossible for Svelte to guarantee that a component didn’t emit a particular event)

## Snippets instead of slots[](#Snippets-instead-of-slots)

In Svelte 4, content can be passed to components using slots. Svelte 5 replaces them with snippets, which are more powerful and flexible, and so slots are deprecated in Svelte 5.

They continue to work, however, and you can pass snippets to a component that uses slots:

Child

```
<slot />
<hr />
<slot name="foo" message="hello" />
```

Parent

```
<script>
	import Child from './Child.svelte';
</script>

<Child>
	default child content

	{#snippet foo({ message })}
		message from child: {message}
	{/snippet}
</Child>
```

```
<script lang="ts">
	import Child from './Child.svelte';
</script>

<Child>
	default child content

	{#snippet foo({ message })}
		message from child: {message}
	{/snippet}
</Child>
```

(The reverse is not true — you cannot pass slotted content to a component that uses [`{@render ...}`](/docs/svelte/@render) tags.)

When using custom elements, you should still use `<slot />` like before. In a future version, when Svelte removes its internal version of slots, it will leave those slots as-is, i.e. output a regular DOM tag instead of transforming it.

### Default content[](#Snippets-instead-of-slots-Default-content)

In Svelte 4, the easiest way to pass a piece of UI to the child was using a `<slot />`. In Svelte 5, this is done using the `children` prop instead, which is then shown with `{@render children()}`:

```
<script>
	let { children } = $props();
</script>

<slot />
{@render children?.()}
```

### Multiple content placeholders[](#Snippets-instead-of-slots-Multiple-content-placeholders)

If you wanted multiple UI placeholders, you had to use named slots. In Svelte 5, use props instead, name them however you like and `{@render ...}` them:

```
<script>
	let { header, main, footer } = $props();
</script>

<header>
	<slot name="header" />
	{@render header()}
</header>

<main>
	<slot name="main" />
	{@render main()}
</main>

<footer>
	<slot name="footer" />
	{@render footer()}
</footer>
```

### Passing data back up[](#Snippets-instead-of-slots-Passing-data-back-up)

In Svelte 4, you would pass data to a `<slot />` and then retrieve it with `let:` in the parent component. In Svelte 5, snippets take on that responsibility:

App

```
<script>
	import List from './List.svelte';
</script>

<List items={['one', 'two', 'three']} let:item>
	{#snippet item(text)}
		<span>{text}</span>
	{/snippet}
	<span slot="empty">No items yet</span>
	{#snippet empty()}
		<span>No items yet</span>
	{/snippet}
</List>
```

```
<script lang="ts">
	import List from './List.svelte';
</script>

<List items={['one', 'two', 'three']} let:item>
	{#snippet item(text)}
		<span>{text}</span>
	{/snippet}
	<span slot="empty">No items yet</span>
	{#snippet empty()}
		<span>No items yet</span>
	{/snippet}
</List>
```

List

```
<script>
	let { items, item, empty } = $props();
</script>

{#if items.length}
	<ul>
		{#each items as entry}
			<li>
				<slot item={entry} />
				{@render item(entry)}
			</li>
		{/each}
	</ul>
{:else}
	<slot name="empty" />
	{@render empty?.()}
{/if}
```

```
<script lang="ts">
	let { items, item, empty } = $props();
</script>

{#if items.length}
	<ul>
		{#each items as entry}
			<li>
				<slot item={entry} />
				{@render item(entry)}
			</li>
		{/each}
	</ul>
{:else}
	<slot name="empty" />
	{@render empty?.()}
{/if}
```

> Why we did this
>
> Slots were easy to get started with, but the more advanced the use case became, the more involved and confusing the syntax became:
>
> * the `let:` syntax was confusing to many people as it *creates* a variable whereas all other `:` directives *receive* a variable
> * the scope of a variable declared with `let:` wasn’t clear. In the example above, it may look like you can use the `item` slot prop in the `empty` slot, but that’s not true
> * named slots had to be applied to an element using the `slot` attribute. Sometimes you didn’t want to create an element, so we had to add the `<svelte:fragment>` API
> * named slots could also be applied to a component, which changed the semantics of where `let:` directives are available (even today us maintainers often don’t know which way around it works)
>
> Snippets solve all of these problems by being much more readable and clear. At the same time they’re more powerful as they allow you to define sections of UI that you can render *anywhere*, not just passing them as props to a component.

## Migration script[](#Migration-script)

By now you should have a pretty good understanding of the before/after and how the old syntax relates to the new syntax. It probably also became clear that a lot of these migrations are rather technical and repetitive — something you don’t want to do by hand.

We thought the same, which is why we provide a migration script to do most of the migration automatically. You can upgrade your project by using `npx sv migrate svelte-5`. This will do the following things:

* bump core dependencies in your `package.json`
* migrate to runes (`let` → `$state` etc)
* migrate to event attributes for DOM elements (`on:click` → `onclick`)
* migrate slot creations to render tags (`<slot />` → `{@render children()}`)
* migrate slot usages to snippets (`<div slot="x">...</div>` → `{#snippet x()}<div>...</div>{/snippet}`)
* migrate obvious component creations (`new Component(...)` → `mount(Component, ...)`)

You can also migrate a single component in VS Code through the `Migrate Component to Svelte 5 Syntax` command, or in our Playground through the `Migrate` button.

Not everything can be migrated automatically, and some migrations need manual cleanup afterwards. The following sections describe these in more detail.

### run[](#Migration-script-run)

You may see that the migration script converts some of your `$:` statements to a `run` function which is imported from `svelte/legacy`. This happens if the migration script couldn’t reliably migrate the statement to a `$derived` and concluded this is a side effect instead. In some cases this may be wrong and it’s best to change this to use a `$derived` instead. In other cases it may be right, but since `$:` statements also ran on the server but `$effect` does not, it isn’t safe to transform it as such. Instead, `run` is used as a stopgap solution. `run` mimics most of the characteristics of `$:`, in that it runs on the server once, and runs as `$effect.pre` on the client (`$effect.pre` runs *before* changes are applied to the DOM; most likely you want to use `$effect` instead).

```
<script>
	import { run } from 'svelte/legacy';
	run(() => {
	$effect(() => {
		// some side effect code
	})
</script>
```

### Event modifiers[](#Migration-script-Event-modifiers)

Event modifiers are not applicable to event attributes (e.g. you can’t do `onclick|preventDefault={...}`). Therefore, when migrating event directives to event attributes, we need a function-replacement for these modifiers. These are imported from `svelte/legacy`, and should be migrated away from in favor of e.g. just using `event.preventDefault()`.

```
<script>
	import { preventDefault } from 'svelte/legacy';
</script>

<button
	onclick={preventDefault((event) => {
		event.preventDefault();
		// ...
	})}
>
	click me
</button>
```

### Things that are not automigrated[](#Migration-script-Things-that-are-not-automigrated)

The migration script does not convert `createEventDispatcher`. You need to adjust those parts manually. It doesn’t do it because it’s too risky because it could result in breakage for users of the component, which the migration script cannot find out.

The migration script does not convert `beforeUpdate/afterUpdate`. It doesn’t do it because it’s impossible to determine the actual intent of the code. As a rule of thumb you can often go with a combination of `$effect.pre` (runs at the same time as `beforeUpdate` did) and `tick` (imported from `svelte`, allows you to wait until changes are applied to the DOM and then do some work).

## Components are no longer classes[](#Components-are-no-longer-classes)

In Svelte 3 and 4, components are classes. In Svelte 5 they are functions and should be instantiated differently. If you need to manually instantiate components, you should use `mount` or `hydrate` (imported from `svelte`) instead. If you see this error using SvelteKit, try updating to the latest version of SvelteKit first, which adds support for Svelte 5. If you’re using Svelte without SvelteKit, you’ll likely have a `main.js` file (or similar) which you need to adjust:

```
import { mount(alias) function mount<Props extends Record<string, any>, Exports extends Record<string, any>>(component: ComponentType<SvelteComponent<Props>> | Component<Props, Exports, any>, options: MountOptions<Props>): Exports
import mount

Mounts a component to the given target and returns the exports and potentially the props (if compiled with accessors: true) of the component.
Transitions will play during the initial render unless the intro option is set to false.


reference } from 'svelte';
import App(alias) type App = SvelteComponent<Record<string, any>, any, any>
(alias) const App: LegacyComponentType
import App from './App.svelte'

const app = new App({ target: document.getElementById("app") });
const appconst app: {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<string, any> = mount(alias) mount<Record<string, any>, {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<string, any>>(component: ComponentType<SvelteComponent<Record<string, any>, any, any>> | Component<Record<string, any>, {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<string, any>, any>, options: MountOptions<...>): {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<...>
import mount

Mounts a component to the given target and returns the exports and potentially the props (if compiled with accessors: true) of the component.
Transitions will play during the initial render unless the intro option is set to false.


reference(App(alias) const App: LegacyComponentType
import App, { target(property) target: Document | Element | ShadowRoot

Target element where the component will be mounted.


: documentvar document: Document

window.document returns a reference to the document contained in the window.




MDN Reference


.getElementById(method) Document.getElementById(elementId: string): HTMLElement | null

The getElementById() method of the Document interface returns an Element object representing the element whose id property matches the specified string. Since element IDs are required to be unique if specified, they're a useful way to get access to a specific element quickly.


("app") });

export default appconst app: {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<string, any>;
```

`mount` and `hydrate` have the exact same API. The difference is that `hydrate` will pick up the Svelte’s server-rendered HTML inside its target and hydrate it. Both return an object with the exports of the component and potentially property accessors (if compiled with `accessors: true`). They do not come with the `$on`, `$set` and `$destroy` methods you may know from the class component API. These are its replacements:

For `$on`, instead of listening to events, pass them via the `events` property on the options argument.

```
import { mount(alias) function mount<Props extends Record<string, any>, Exports extends Record<string, any>>(component: ComponentType<SvelteComponent<Props>> | Component<Props, Exports, any>, options: MountOptions<Props>): Exports
import mount

Mounts a component to the given target and returns the exports and potentially the props (if compiled with accessors: true) of the component.
Transitions will play during the initial render unless the intro option is set to false.


reference } from 'svelte';
import App(alias) type App = SvelteComponent<Record<string, any>, any, any>
(alias) const App: LegacyComponentType
import App from './App.svelte'

const app = new App({ target: document.getElementById("app") });
app.$on('event', callback);
const appconst app: {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<string, any> = mount(alias) mount<Record<string, any>, {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<string, any>>(component: ComponentType<SvelteComponent<Record<string, any>, any, any>> | Component<Record<string, any>, {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<string, any>, any>, options: MountOptions<...>): {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<...>
import mount

Mounts a component to the given target and returns the exports and potentially the props (if compiled with accessors: true) of the component.
Transitions will play during the initial render unless the intro option is set to false.


reference(App(alias) const App: LegacyComponentType
import App, { target(property) target: Document | Element | ShadowRoot

Target element where the component will be mounted.


: documentvar document: Document

window.document returns a reference to the document contained in the window.




MDN Reference


.getElementById(method) Document.getElementById(elementId: string): HTMLElement | null

The getElementById() method of the Document interface returns an Element object representing the element whose id property matches the specified string. Since element IDs are required to be unique if specified, they're a useful way to get access to a specific element quickly.


("app"), events(property) events?: Record<string, (e: any) => any> | undefined

Allows the specification of events.




Use callback props instead.


: { event(property) event: any: callbackany } });
```

> Note that using `events` is discouraged — instead, [use callbacks](#Event-changes)

For `$set`, use `$state` instead to create a reactive property object and manipulate it. If you’re doing this inside a `.js` or `.ts` file, adjust the ending to include `.svelte`, i.e. `.svelte.js` or `.svelte.ts`.

```
import { mount(alias) function mount<Props extends Record<string, any>, Exports extends Record<string, any>>(component: ComponentType<SvelteComponent<Props>> | Component<Props, Exports, any>, options: MountOptions<Props>): Exports
import mount

Mounts a component to the given target and returns the exports and potentially the props (if compiled with accessors: true) of the component.
Transitions will play during the initial render unless the intro option is set to false.


reference } from 'svelte';
import App(alias) type App = SvelteComponent<Record<string, any>, any, any>
(alias) const App: LegacyComponentType
import App from './App.svelte'

const app = new App({ target: document.getElementById("app"), props: { foo: 'bar' } });
app.$set({ foo: 'baz' });
const propsconst props: {
    foo: string;
} = $statefunction $state<{
    foo: string;
}>(initial: {
    foo: string;
}): {
    foo: string;
} (+1 overload)
namespace $state

Declares reactive state.




Example:



let count = $state(0);

{@link https://svelte.dev/docs/svelte/$state Documentation}


initial 

The initial value


({ foo(property) foo: string: 'bar' });
const appconst app: {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<string, any> = mount(alias) mount<Record<string, any>, {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<string, any>>(component: ComponentType<SvelteComponent<Record<string, any>, any, any>> | Component<Record<string, any>, {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<string, any>, any>, options: MountOptions<...>): {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<...>
import mount

Mounts a component to the given target and returns the exports and potentially the props (if compiled with accessors: true) of the component.
Transitions will play during the initial render unless the intro option is set to false.


reference(App(alias) const App: LegacyComponentType
import App, { target(property) target: Document | Element | ShadowRoot

Target element where the component will be mounted.


: documentvar document: Document

window.document returns a reference to the document contained in the window.




MDN Reference


.getElementById(method) Document.getElementById(elementId: string): HTMLElement | null

The getElementById() method of the Document interface returns an Element object representing the element whose id property matches the specified string. Since element IDs are required to be unique if specified, they're a useful way to get access to a specific element quickly.


("app"), props(property) props?: Record<string, any> | undefined

Component properties.


 });
propsconst props: {
    foo: string;
}.foo(property) foo: string = 'baz';
```

For `$destroy`, use `unmount` instead.

```
import { mount(alias) function mount<Props extends Record<string, any>, Exports extends Record<string, any>>(component: ComponentType<SvelteComponent<Props>> | Component<Props, Exports, any>, options: MountOptions<Props>): Exports
import mount

Mounts a component to the given target and returns the exports and potentially the props (if compiled with accessors: true) of the component.
Transitions will play during the initial render unless the intro option is set to false.


reference, unmount(alias) function unmount(component: Record<string, any>, options?: {
    outro?: boolean;
} | undefined): Promise<void>
import unmount

Unmounts a component that was previously mounted using mount or hydrate.




Since 5.13.0, if options.outro is true, transitions will play before the component is removed from the DOM.




Returns a Promise that resolves after transitions have completed if options.outro is true, or immediately otherwise (prior to 5.13.0, returns void).



import { mount, unmount } from 'svelte';
import App from './App.svelte';

const app = mount(App, { target: document.body });

// later...
unmount(app, { outro: true });
reference } from 'svelte';
import App(alias) type App = SvelteComponent<Record<string, any>, any, any>
(alias) const App: LegacyComponentType
import App from './App.svelte'

const app = new App({ target: document.getElementById("app"), props: { foo: 'bar' } });
app.$destroy();
const appconst app: {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<string, any> = mount(alias) mount<Record<string, any>, {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<string, any>>(component: ComponentType<SvelteComponent<Record<string, any>, any, any>> | Component<Record<string, any>, {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<string, any>, any>, options: MountOptions<...>): {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<...>
import mount

Mounts a component to the given target and returns the exports and potentially the props (if compiled with accessors: true) of the component.
Transitions will play during the initial render unless the intro option is set to false.


reference(App(alias) const App: LegacyComponentType
import App, { target(property) target: Document | Element | ShadowRoot

Target element where the component will be mounted.


: documentvar document: Document

window.document returns a reference to the document contained in the window.




MDN Reference


.getElementById(method) Document.getElementById(elementId: string): HTMLElement | null

The getElementById() method of the Document interface returns an Element object representing the element whose id property matches the specified string. Since element IDs are required to be unique if specified, they're a useful way to get access to a specific element quickly.


("app") });
unmount(alias) unmount(component: Record<string, any>, options?: {
    outro?: boolean;
} | undefined): Promise<void>
import unmount

Unmounts a component that was previously mounted using mount or hydrate.




Since 5.13.0, if options.outro is true, transitions will play before the component is removed from the DOM.




Returns a Promise that resolves after transitions have completed if options.outro is true, or immediately otherwise (prior to 5.13.0, returns void).



import { mount, unmount } from 'svelte';
import App from './App.svelte';

const app = mount(App, { target: document.body });

// later...
unmount(app, { outro: true });
reference(appconst app: {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<string, any>);
```

As a stop-gap-solution, you can also use `createClassComponent` or `asClassComponent` (imported from `svelte/legacy`) instead to keep the same API known from Svelte 4 after instantiating.

```
import { createClassComponent(alias) function createClassComponent<Props extends Record<string, any>, Exports extends Record<string, any>, Events extends Record<string, any>, Slots extends Record<string, any>>(options: ComponentConstructorOptions<Props> & {
    component: ComponentType<SvelteComponent<Props, Events, Slots>> | Component<Props>;
}): SvelteComponent<Props, Events, Slots> & Exports
import createClassComponent

Takes the same options as a Svelte 4 component and the component function and returns a Svelte 4 compatible component.




Use this only as a temporary solution to migrate your imperative component code to Svelte 5.


reference } from 'svelte/legacy';
import App(alias) type App = SvelteComponent<Record<string, any>, any, any>
(alias) const App: LegacyComponentType
import App from './App.svelte'

const app = new App({ target: document.getElementById("app") });
const appconst app: SvelteComponent<Record<string, any>, any, any> & Record<string, any> = createClassComponent(alias) createClassComponent<Record<string, any>, Record<string, any>, any, any>(options: ComponentConstructorOptions<Record<string, any>> & {
    component: Component<Record<string, any>, {}, string> | ComponentType<SvelteComponent<Record<string, any>, any, any>>;
}): SvelteComponent<Record<string, any>, any, any> & Record<string, any>
import createClassComponent

Takes the same options as a Svelte 4 component and the component function and returns a Svelte 4 compatible component.




Use this only as a temporary solution to migrate your imperative component code to Svelte 5.


reference({ component(property) component: Component<Record<string, any>, {}, string> | ComponentType<SvelteComponent<Record<string, any>, any, any>>: App(alias) const App: LegacyComponentType
import App, target(property) ComponentConstructorOptions<Props extends Record<string, any> = Record<string, any>>.target: Document | Element | ShadowRoot: documentvar document: Document

window.document returns a reference to the document contained in the window.




MDN Reference


.getElementById(method) Document.getElementById(elementId: string): HTMLElement | null

The getElementById() method of the Document interface returns an Element object representing the element whose id property matches the specified string. Since element IDs are required to be unique if specified, they're a useful way to get access to a specific element quickly.


("app") });

export default appconst app: SvelteComponent<Record<string, any>, any, any> & Record<string, any>;
```

If this component is not under your control, you can use the `compatibility.componentApi` compiler option for auto-applied backwards compatibility, which means code using `new Component(...)` keeps working without adjustments (note that this adds a bit of overhead to each component). This will also add `$set` and `$on` methods for all component instances you get through `bind:this`.

```
/// svelte.config.js
export default {
	compilerOptions(property) compilerOptions: {
    compatibility: {
        componentApi: number;
    };
}: {
		compatibility(property) compatibility: {
    componentApi: number;
}: {
			componentApi(property) componentApi: number: 4
		}
	}
};
```

Note that `mount` and `hydrate` are *not* synchronous, so things like `onMount` won’t have been called by the time the function returns and the pending block of promises will not have been rendered yet (because `#await` waits a microtask to wait for a potentially immediately-resolved promise). If you need that guarantee, call `flushSync` (import from `'svelte'`) after calling `mount/hydrate`.

### Server API changes[](#Components-are-no-longer-classes-Server-API-changes)

Similarly, components no longer have a `render` method when compiled for server-side rendering. Instead, pass the function to `render` from `svelte/server`:

```
import { render(alias) function render<Comp extends SvelteComponent<any> | Component<any>, Props extends ComponentProps<Comp> = ComponentProps<Comp>>(...args: {} extends Props ? [component: Comp extends SvelteComponent<any> ? ComponentType<Comp> : Comp, options?: {
    props?: Omit<Props, "$$slots" | "$$events">;
    context?: Map<any, any>;
    idPrefix?: string;
    csp?: Csp;
    transformError?: (error: unknown) => unknown | Promise<unknown>;
}] : [component: Comp extends SvelteComponent<any> ? ComponentType<Comp> : Comp, options: {
    props: Omit<Props, "$$slots" | "$$events">;
    context?: Map<any, any>;
    idPrefix?: string;
    csp?: Csp;
    transformError?: (error: unknown) => unknown | Promise<unknown>;
}]): RenderOutput
import render

Only available on the server and when compiling with the server option.
Takes a component and returns an object with body and head properties on it, which you can use to populate the HTML when server-rendering your app.


reference } from 'svelte/server';
import App(alias) type App = SvelteComponent<Record<string, any>, any, any>
(alias) const App: LegacyComponentType
import App from './App.svelte';

const { html, head } = App.render({ props: { message: 'hello' }});
const { htmlconst html: string, headconst head: string

HTML that goes into the <head>


 } = render(alias) render<SvelteComponent<Record<string, any>, any, any>, Record<string, any>>(component: ComponentType<SvelteComponent<Record<string, any>, any, any>>, options?: {
    props?: Omit<Record<string, any>, "$$slots" | "$$events"> | undefined;
    context?: Map<any, any>;
    idPrefix?: string;
    csp?: Csp;
    transformError?: ((error: unknown) => unknown | Promise<unknown>) | undefined;
} | undefined): RenderOutput
import render

Only available on the server and when compiling with the server option.
Takes a component and returns an object with body and head properties on it, which you can use to populate the HTML when server-rendering your app.


reference(App(alias) const App: LegacyComponentType
import App, { props(property) props?: Omit<Record<string, any>, "$$slots" | "$$events"> | undefined: { message(property) message: string: 'hello' }});
```

In Svelte 4, rendering a component to a string also returned the CSS of all components. In Svelte 5, this is no longer the case by default because most of the time you’re using a tooling chain that takes care of it in other ways (like SvelteKit). If you need CSS to be returned from `render`, you can set the `css` compiler option to `'injected'` and it will add `<style>` elements to the `head`.

### Component typing changes[](#Components-are-no-longer-classes-Component-typing-changes)

The change from classes towards functions is also reflected in the typings: `SvelteComponent`, the base class from Svelte 4, is deprecated in favour of the new `Component` type which defines the function shape of a Svelte component. To manually define a component shape in a `d.ts` file:

```
import type { Component(alias) interface Component<Props extends Record<string, any> = {}, Exports extends Record<string, any> = {}, Bindings extends keyof Props | "" = string>
import Component

Can be used to create strongly typed Svelte components.



Example:



You have component library on npm called component-library, from which
you export a component called MyComponent. For Svelte+TypeScript users,
you want to provide typings. Therefore you create a index.d.ts:



import type { Component } from 'svelte';
export declare const MyComponent: Component<{ foo: string }> {}

Typing this makes it possible for IDEs like VS Code with the Svelte extension
to provide intellisense and to use the component like this in a Svelte file
with TypeScript:



<script lang="ts">
	import { MyComponent } from "component-library";
</script>
<MyComponent foo={'bar'} />
reference } from 'svelte';
export declare const MyComponentconst MyComponent: Component<{
    foo: string;
}, {}, string>: Component(alias) interface Component<Props extends Record<string, any> = {}, Exports extends Record<string, any> = {}, Bindings extends keyof Props | "" = string>
import Component

Can be used to create strongly typed Svelte components.



Example:



You have component library on npm called component-library, from which
you export a component called MyComponent. For Svelte+TypeScript users,
you want to provide typings. Therefore you create a index.d.ts:



import type { Component } from 'svelte';
export declare const MyComponent: Component<{ foo: string }> {}

Typing this makes it possible for IDEs like VS Code with the Svelte extension
to provide intellisense and to use the component like this in a Svelte file
with TypeScript:



<script lang="ts">
	import { MyComponent } from "component-library";
</script>
<MyComponent foo={'bar'} />
reference<{
	foo(property) foo: string: string;
}>;
```

To declare that a component of a certain type is required:

```
import { ComponentAimport ComponentA, ComponentBimport ComponentB } from 'component-library';
import type { SvelteComponent } from 'svelte';
import type { Component(alias) interface Component<Props extends Record<string, any> = {}, Exports extends Record<string, any> = {}, Bindings extends keyof Props | "" = string>
import Component

Can be used to create strongly typed Svelte components.



Example:



You have component library on npm called component-library, from which
you export a component called MyComponent. For Svelte+TypeScript users,
you want to provide typings. Therefore you create a index.d.ts:



import type { Component } from 'svelte';
export declare const MyComponent: Component<{ foo: string }> {}

Typing this makes it possible for IDEs like VS Code with the Svelte extension
to provide intellisense and to use the component like this in a Svelte file
with TypeScript:



<script lang="ts">
	import { MyComponent } from "component-library";
</script>
<MyComponent foo={'bar'} />
reference } from 'svelte';

let C: typeof SvelteComponent<{ foo: string }> = $state(
let Clet C: Component<{
    foo: string;
}, {}, string>: Component(alias) interface Component<Props extends Record<string, any> = {}, Exports extends Record<string, any> = {}, Bindings extends keyof Props | "" = string>
import Component

Can be used to create strongly typed Svelte components.



Example:



You have component library on npm called component-library, from which
you export a component called MyComponent. For Svelte+TypeScript users,
you want to provide typings. Therefore you create a index.d.ts:



import type { Component } from 'svelte';
export declare const MyComponent: Component<{ foo: string }> {}

Typing this makes it possible for IDEs like VS Code with the Svelte extension
to provide intellisense and to use the component like this in a Svelte file
with TypeScript:



<script lang="ts">
	import { MyComponent } from "component-library";
</script>
<MyComponent foo={'bar'} />
reference<{ foo(property) foo: string: string }> = $statefunction $state<any>(initial: any): any (+1 overload)
namespace $state

Declares reactive state.




Example:



let count = $state(0);

{@link https://svelte.dev/docs/svelte/$state Documentation}


initial 

The initial value


(
	Mathvar Math: Math

An intrinsic object that provides basic mathematics functionality and constants.


.random(method) Math.random(): number

Returns a pseudorandom number between 0 and 1.


() ? ComponentAimport ComponentA : ComponentBimport ComponentB
);
```

The two utility types `ComponentEvents` and `ComponentType` are also deprecated. `ComponentEvents` is obsolete because events are defined as callback props now, and `ComponentType` is obsolete because the new `Component` type is the component type already (i.e. `ComponentType<SvelteComponent<{ prop: string }>>` is equivalent to `Component<{ prop: string }>`).

### bind:this changes[](#Components-are-no-longer-classes-bind:this-changes)

Because components are no longer classes, using `bind:this` no longer returns a class instance with `$set`, `$on` and `$destroy` methods on it. It only returns the instance exports (`export function/const`) and, if you’re using the `accessors` option, a getter/setter-pair for each property.

## \<svelte:component> is no longer necessary[](#svelte:component-is-no-longer-necessary)

In Svelte 4, components are *static* — if you render `<Thing>`, and the value of `Thing` changes, [nothing happens](/playground/7f1fa24f0ab44c1089dcbb03568f8dfa?version=4.2.18). To make it dynamic you had to use `<svelte:component>`.

This is no longer true in Svelte 5:

```
<script>
	import A from './A.svelte';
	import B from './B.svelte';

	let Thing = $state();
</script>

<select bind:value={Thing}>
	<option value={A}>A</option>
	<option value={B}>B</option>
</select>

<!-- these are equivalent -->
<Thing />
<svelte:component this={Thing} />
```

While migrating, keep in mind that your component’s name should be capitalized (`Thing`) to distinguish it from elements, unless using dot notation.

### Dot notation indicates a component[](#svelte:component-is-no-longer-necessary-Dot-notation-indicates-a-component)

In Svelte 4, `<foo.bar>` would create an element with a tag name of `"foo.bar"`. In Svelte 5, `foo.bar` is treated as a component instead. This is particularly useful inside `each` blocks:

```
{#each items as item}
	<item.component {...item.props} />
{/each}
```

## Whitespace handling changed[](#Whitespace-handling-changed)

Previously, Svelte employed a very complicated algorithm to determine if whitespace should be kept or not. Svelte 5 simplifies this which makes it easier to reason about as a developer. The rules are:

* Whitespace between nodes is collapsed to one whitespace

* Whitespace at the start and end of a tag is removed completely

  This new behavior is slightly different from native HTML rendering. For example, `<p>foo<span> - bar</span></p>` will render:

  * `foo - bar` in HTML
  * `foo- bar` in Svelte 5

  You can reintroduce the missing space by moving it outside the `<span>`...

  ```
  <p>foo <span>- bar</span></p>
  ```

  ...or, if necessary for styling reasons, including it as an expression:

  ```
  <p>foo<span>{' '}- bar</span></p>
  ```

* Certain exceptions apply such as keeping whitespace inside `pre` tags

As before, you can disable whitespace trimming by setting the `preserveWhitespace` option in your compiler settings or on a per-component basis in `<svelte:options>`.

## Modern browser required[](#Modern-browser-required)

Svelte 5 requires a modern browser (in other words, not Internet Explorer) for various reasons:

* it uses [`Proxies`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy)
* elements with `clientWidth` / `clientHeight`/`offsetWidth`/`offsetHeight` bindings use a [`ResizeObserver`](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver) rather than a convoluted `<iframe>` hack
* `<input type="range" bind:value={...} />` only uses an `input` event listener, rather than also listening for `change` events as a fallback

The `legacy` compiler option, which generated bulkier but IE-friendly code, no longer exists.

## Changes to compiler options[](#Changes-to-compiler-options)

* The `false` / `true` (already deprecated previously) and the `"none"` values were removed as valid values from the `css` option
* The `legacy` option was repurposed
* The `hydratable` option has been removed. Svelte components are always hydratable now
* The `enableSourcemap` option has been removed. Source maps are always generated now, tooling can choose to ignore it
* The `tag` option was removed. Use `<svelte:options customElement="tag-name" />` inside the component instead
* The `loopGuardTimeout`, `format`, `sveltePath`, `errorMode` and `varsReport` options were removed

## The children prop is reserved[](#The-children-prop-is-reserved)

Content inside component tags becomes a snippet prop called `children`. You cannot have a separate prop by that name.

## Breaking changes in runes mode[](#Breaking-changes-in-runes-mode)

Some breaking changes only apply once your component is in runes mode.

### Bindings to component exports are not allowed[](#Breaking-changes-in-runes-mode-Bindings-to-component-exports-are-not-allowed)

Exports from runes mode components cannot be bound to directly. For example, having `export const foo = ...` in component `A` and then doing `<A bind:foo />` causes an error. Use `bind:this` instead — `<A bind:this={a} />` — and access the export as `a.foo`. This change makes things easier to reason about, as it enforces a clear separation between props and exports.

### Bindings need to be explicitly defined using $bindable()[](#Breaking-changes-in-runes-mode-Bindings-need-to-be-explicitly-defined-using-$bindable\(\))

In Svelte 4 syntax, every property (declared via `export let`) is bindable, meaning you can `bind:` to it. In runes mode, properties are not bindable by default: you need to denote bindable props with the `$bindable` rune.

If a bindable property has a default value (e.g. `let { foo = $bindable('bar') } = $props();`), you need to pass a non-`undefined` value to that property if you’re binding to it. This prevents ambiguous behavior — the parent and child must have the same value — and results in better performance (in Svelte 4, the default value was reflected back to the parent, resulting in wasteful additional render cycles).

### accessors option is ignored[](#Breaking-changes-in-runes-mode-accessors-option-is-ignored)

Setting the `accessors` option to `true` makes properties of a component directly accessible on the component instance.

```
<svelte:options accessors={true} />

<script>
	// available via componentInstance.name
	export let name;
</script>
```

In runes mode, properties are never accessible on the component instance. You can use component exports instead if you need to expose them.

```
<script>
	let { name } = $props();
	// available via componentInstance.getName()
	export const getName = () => name;
</script>
```

Alternatively, if the place where they are instantiated is under your control, you can also make use of runes inside `.js/.ts` files by adjusting their ending to include `.svelte`, i.e. `.svelte.js` or `.svelte.ts`, and then use `$state`:

```
import { mount(alias) function mount<Props extends Record<string, any>, Exports extends Record<string, any>>(component: ComponentType<SvelteComponent<Props>> | Component<Props, Exports, any>, options: MountOptions<Props>): Exports
import mount

Mounts a component to the given target and returns the exports and potentially the props (if compiled with accessors: true) of the component.
Transitions will play during the initial render unless the intro option is set to false.


reference } from 'svelte';
import App(alias) type App = SvelteComponent<Record<string, any>, any, any>
(alias) const App: LegacyComponentType
import App from './App.svelte'

const app = new App({ target: document.getElementById("app"), props: { foo: 'bar' } });
app.foo = 'baz'
const propsconst props: {
    foo: string;
} = $statefunction $state<{
    foo: string;
}>(initial: {
    foo: string;
}): {
    foo: string;
} (+1 overload)
namespace $state

Declares reactive state.




Example:



let count = $state(0);

{@link https://svelte.dev/docs/svelte/$state Documentation}


initial 

The initial value


({ foo(property) foo: string: 'bar' });
const appconst app: {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<string, any> = mount(alias) mount<Record<string, any>, {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<string, any>>(component: ComponentType<SvelteComponent<Record<string, any>, any, any>> | Component<Record<string, any>, {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<string, any>, any>, options: MountOptions<...>): {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, any>>): void;
} & Record<...>
import mount

Mounts a component to the given target and returns the exports and potentially the props (if compiled with accessors: true) of the component.
Transitions will play during the initial render unless the intro option is set to false.


reference(App(alias) const App: LegacyComponentType
import App, { target(property) target: Document | Element | ShadowRoot

Target element where the component will be mounted.


: documentvar document: Document

window.document returns a reference to the document contained in the window.




MDN Reference


.getElementById(method) Document.getElementById(elementId: string): HTMLElement | null

The getElementById() method of the Document interface returns an Element object representing the element whose id property matches the specified string. Since element IDs are required to be unique if specified, they're a useful way to get access to a specific element quickly.


("app"), props(property) props?: Record<string, any> | undefined

Component properties.


 });
propsconst props: {
    foo: string;
}.foo(property) foo: string = 'baz';
```

### immutable option is ignored[](#Breaking-changes-in-runes-mode-immutable-option-is-ignored)

Setting the `immutable` option has no effect in runes mode. This concept is replaced by how `$state` and its variations work.

### Classes are no longer “auto-reactive”[](#Breaking-changes-in-runes-mode-Classes-are-no-longer-auto-reactive)

In Svelte 4, doing the following triggered reactivity:

```
<script>
	let foo = new Foo();
</script>

<button on:click={() => (foo.value = 1)}>{foo.value}</button
>
```

This is because the Svelte compiler treated the assignment to `foo.value` as an instruction to update anything that referenced `foo`. In Svelte 5, reactivity is determined at runtime rather than compile time, so you should define `value` as a reactive `$state` field on the `Foo` class. Wrapping `new Foo()` with `$state(...)` will have no effect — only vanilla objects and arrays are made deeply reactive.

### Touch events are passive[](#Breaking-changes-in-runes-mode-Touch-events-are-passive)

When using `ontouchstart` and `ontouchmove` event attributes, the handlers are [passive](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#using_passive_listeners) to align with browser defaults. This greatly improves responsiveness by allowing the browser to scroll the document immediately, rather than waiting to see if the event handler calls `event.preventDefault()`.

In the very rare cases that you need to prevent these event defaults, you should use [`on`](/docs/svelte/svelte-events#on) instead (for example inside an action).

### Attribute/prop syntax is stricter[](#Breaking-changes-in-runes-mode-Attribute-prop-syntax-is-stricter)

In Svelte 4, complex attribute values needn’t be quoted:

```
<Component prop=this{is}valid />
```

This is a footgun. In runes mode, if you want to concatenate stuff you must wrap the value in quotes:

```
<Component prop="this{is}valid" />
```

Note that Svelte 5 will also warn if you have a single expression wrapped in quotes, like `answer="{42}"` — in Svelte 6, that will cause the value to be converted to a string, rather than passed as a number.

### HTML structure is stricter[](#Breaking-changes-in-runes-mode-HTML-structure-is-stricter)

In Svelte 4, you were allowed to write HTML code that would be repaired by the browser when server-side rendering it. For example you could write this...

```
<table>
	<tr>
		<td>hi</td>
	</tr>
</table>
```

... and the browser would auto-insert a `<tbody>` element:

```
<table>
	<tbody>
		<tr>
			<td>hi</td>
		</tr>
	</tbody>
</table>
```

Svelte 5 is more strict about the HTML structure and will throw a compiler error in cases where the browser would repair the DOM.

## Other breaking changes[](#Other-breaking-changes)

### Stricter @const assignment validation[](#Other-breaking-changes-Stricter-const-assignment-validation)

Assignments to destructured parts of a `@const` declaration are no longer allowed. It was an oversight that this was ever allowed.

### :is(...), :has(...), and :where(...) are scoped[](#Other-breaking-changes-:is\(\)-:has\(\)-and-:where\(\)-are-scoped)

Previously, Svelte did not analyse selectors inside `:is(...)`, `:has(...)`, and `:where(...)`, effectively treating them as global. Svelte 5 analyses them in the context of the current component. Some selectors may now therefore be treated as unused if they were relying on this treatment. To fix this, use `:global(...)` inside the `:is(...)/:has(...)/:where(...)` selectors.

When using Tailwind’s `@apply` directive, add a `:global` selector to preserve rules that use Tailwind-generated `:is(...)` selectors:

```
main :global {
	@apply bg-blue-100 dark:bg-blue-900;
}
```

### CSS hash position no longer deterministic[](#Other-breaking-changes-CSS-hash-position-no-longer-deterministic)

Previously Svelte would always insert the CSS hash last. This is no longer guaranteed in Svelte 5. This is only breaking if you [have very weird css selectors](https://stackoverflow.com/questions/15670631/does-the-order-of-classes-listed-on-an-item-affect-the-css).

### Scoped CSS uses :where(...)[](#Other-breaking-changes-Scoped-CSS-uses-:where\(\))

To avoid issues caused by unpredictable specificity changes, scoped CSS selectors now use `:where(.svelte-xyz123)` selector modifiers alongside `.svelte-xyz123` (where `xyz123` is, as previously, a hash of the `<style>` contents). You can read more detail [here](https://github.com/sveltejs/svelte/pull/10443).

In the event that you need to support ancient browsers that don’t implement `:where`, you can manually alter the emitted CSS, at the cost of unpredictable specificity changes:

```
cssany = cssany.replaceany(/:where\((.+?)\)/, '$1');
```

### Error/warning codes have been renamed[](#Other-breaking-changes-Error-warning-codes-have-been-renamed)

Error and warning codes have been renamed. Previously they used dashes to separate the words, they now use underscores (e.g. foo-bar becomes foo\_bar). Additionally, a handful of codes have been reworded slightly.

### Reduced number of namespaces[](#Other-breaking-changes-Reduced-number-of-namespaces)

The number of valid namespaces you can pass to the compiler option `namespace` has been reduced to `html` (the default), `mathml` and `svg`.

The `foreign` namespace was only useful for Svelte Native, which we’re planning to support differently in a 5.x minor.

### beforeUpdate/afterUpdate changes[](#Other-breaking-changes-beforeUpdate-afterUpdate-changes)

`beforeUpdate` no longer runs twice on initial render if it modifies a variable referenced in the template.

`afterUpdate` callbacks in a parent component will now run after `afterUpdate` callbacks in any child components.

`beforeUpdate/afterUpdate` no longer run when the component contains a `<slot>` and its content is updated.

Both functions are disallowed in runes mode — use `$effect.pre(...)` and `$effect(...)` instead.

### contenteditable behavior change[](#Other-breaking-changes-contenteditable-behavior-change)

If you have a `contenteditable` node with a corresponding binding *and* a reactive value inside it (example: `<div contenteditable=true bind:textContent>count is {count}</div>`), then the value inside the contenteditable will not be updated by updates to `count` because the binding takes full control over the content immediately and it should only be updated through it.

### oneventname attributes no longer accept string values[](#Other-breaking-changes-oneventname-attributes-no-longer-accept-string-values)

In Svelte 4, it was possible to specify event attributes on HTML elements as a string:

```
<button onclick="alert('hello')">...</button>
```

This is not recommended, and is no longer possible in Svelte 5, where properties like `onclick` replace `on:click` as the mechanism for adding event handlers.

### null and undefined become the empty string[](#Other-breaking-changes-null-and-undefined-become-the-empty-string)

In Svelte 4, `null` and `undefined` were printed as the corresponding string. In 99 out of 100 cases you want this to become the empty string instead, which is also what most other frameworks out there do. Therefore, in Svelte 5, `null` and `undefined` become the empty string.

### bind:files values can only be null, undefined or FileList[](#Other-breaking-changes-bind:files-values-can-only-be-null-undefined-or-FileList)

`bind:files` is now a two-way binding. As such, when setting a value, it needs to be either falsy (`null` or `undefined`) or of type `FileList`.

### Bindings now react to form resets[](#Other-breaking-changes-Bindings-now-react-to-form-resets)

Previously, bindings did not take into account `reset` event of forms, and therefore values could get out of sync with the DOM. Svelte 5 fixes this by placing a `reset` listener on the document and invoking bindings where necessary.

### walk no longer exported[](#Other-breaking-changes-walk-no-longer-exported)

`svelte/compiler` reexported `walk` from `estree-walker` for convenience. This is no longer true in Svelte 5, import it directly from that package instead in case you need it.

### Content inside svelte:options is forbidden[](#Other-breaking-changes-Content-inside-svelte:options-is-forbidden)

In Svelte 4 you could have content inside a `<svelte:options />` tag. It was ignored, but you could write something in there. In Svelte 5, content inside that tag is a compiler error.

### \<slot> elements in declarative shadow roots are preserved[](#Other-breaking-changes-slot-elements-in-declarative-shadow-roots-are-preserved)

Svelte 4 replaced the `<slot />` tag in all places with its own version of slots. Svelte 5 preserves them in the case they are a child of a `<template shadowrootmode="...">` element.

### \<svelte:element> tag must be an expression[](#Other-breaking-changes-svelte:element-tag-must-be-an-expression)

In Svelte 4, `<svelte:element this="div">` is valid code. This makes little sense — you should just do `<div>`. In the vanishingly rare case that you *do* need to use a literal value for some reason, you can do this:

```
<svelte:element this={"div"}>
```

Note that whereas Svelte 4 would treat `<svelte:element this="input">` (for example) identically to `<input>` for the purposes of determining which `bind:` directives could be applied, Svelte 5 does not.

### mount plays transitions by default[](#Other-breaking-changes-mount-plays-transitions-by-default)

The `mount` function used to render a component tree plays transitions by default unless the `intro` option is set to `false`. This is different from legacy class components which, when manually instantiated, didn’t play transitions by default.

### \<img src={...}> and {@html ...} hydration mismatches are not repaired[](#Other-breaking-changes-img-src-and-html-hydration-mismatches-are-not-repaired)

In Svelte 4, if the value of a `src` attribute or `{@html ...}` tag differ between server and client (a.k.a. a hydration mismatch), the mismatch is repaired. This is very costly: setting a `src` attribute (even if it evaluates to the same thing) causes images and iframes to be reloaded, and reinserting a large blob of HTML is slow.

Since these mismatches are extremely rare, Svelte 5 assumes that the values are unchanged, but in development will warn you if they are not. To force an update you can do something like this:

```
<script>
	let { markup, src } = $props();

	if (typeof window !== 'undefined') {
		// stash the values...
		const initial = { markup, src };

		// unset them...
		markup = src = undefined;

		$effect(() => {
			// ...and reset after we've mounted
			markup = initial.markup;
			src = initial.src;
		});
	}
</script>

{@html markup}
<img {src} />
```

### Hydration works differently[](#Other-breaking-changes-Hydration-works-differently)

Svelte 5 makes use of comments during server-side rendering which are used for more robust and efficient hydration on the client. You therefore should not remove comments from your HTML output if you intend to hydrate it, and if you manually authored HTML to be hydrated by a Svelte component, you need to adjust that HTML to include said comments at the correct positions.

### onevent attributes are delegated[](#Other-breaking-changes-onevent-attributes-are-delegated)

Event attributes replace event directives: Instead of `on:click={handler}` you write `onclick={handler}`. For backwards compatibility the `on:event` syntax is still supported and behaves the same as in Svelte 4. Some of the `onevent` attributes however are delegated, which means you need to take care to not stop event propagation on those manually, as they then might never reach the listener for this event type at the root.

### --style-props uses a different element[](#Other-breaking-changes-style-props-uses-a-different-element)

Svelte 5 uses an extra `<svelte-css-wrapper>` element instead of a `<div>` to wrap the component when using CSS custom properties.

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/07-misc/07-v5-migration-guide.md) [llms.txt](/docs/svelte/v5-migration-guide/llms.txt)

previous next

[Svelte 4 migration guide](/docs/svelte/v4-migration-guide) [Frequently asked questions](/docs/svelte/faq)

----
url: https://svelte.dev/docs/svelte/svelte-transition
----

[Skip to main content](#main)

This module provides built-in transition functions for use with the [`transition:`](transition) directive.

```
import {
	blur(alias) function blur(node: Element, { delay, duration, easing, amount, opacity }?: BlurParams | undefined): TransitionConfig
import blur

Animates a blur filter alongside an element's opacity.


reference,
	crossfade(alias) function crossfade({ fallback, ...defaults }: CrossfadeParams & {
    fallback?: (node: Element, params: CrossfadeParams, intro: boolean) => TransitionConfig;
}): [(node: any, params: CrossfadeParams & {
    key: any;
}) => () => TransitionConfig, (node: any, params: CrossfadeParams & {
    key: any;
}) => () => TransitionConfig]
import crossfade

The crossfade function creates a pair of transitions called send and receive. When an element is 'sent', it looks for a corresponding element being 'received', and generates a transition that transforms the element to its counterpart's position and fades it out. When an element is 'received', the reverse happens. If there is no counterpart, the fallback transition is used.


reference,
	draw(alias) function draw(node: SVGElement & {
    getTotalLength(): number;
}, { delay, speed, duration, easing }?: DrawParams | undefined): TransitionConfig
import draw

Animates the stroke of an SVG element, like a snake in a tube. in transitions begin with the path invisible and draw the path to the screen over time. out transitions start in a visible state and gradually erase the path. draw only works with elements that have a getTotalLength method, like <path> and <polyline>.


reference,
	fade(alias) function fade(node: Element, { delay, duration, easing }?: FadeParams | undefined): TransitionConfig
import fade

Animates the opacity of an element from 0 to the current opacity for in transitions and from the current opacity to 0 for out transitions.


reference,
	fly(alias) function fly(node: Element, { delay, duration, easing, x, y, opacity }?: FlyParams | undefined): TransitionConfig
import fly

Animates the x and y positions and the opacity of an element. in transitions animate from the provided values, passed as parameters to the element's default values. out transitions animate from the element's default values to the provided values.


reference,
	scale(alias) function scale(node: Element, { delay, duration, easing, start, opacity }?: ScaleParams | undefined): TransitionConfig
import scale

Animates the opacity and scale of an element. in transitions animate from the provided values, passed as parameters, to an element's current (default) values. out transitions animate from an element's default values to the provided values.


reference,
	slide(alias) function slide(node: Element, { delay, duration, easing, axis }?: SlideParams | undefined): TransitionConfig
import slide

Slides an element in and out.


reference
} from 'svelte/transition';
```

## blur[](#blur)

Animates a `blur` filter alongside an element’s opacity.

```
function blur(
	node: Element,
	{
		delay,
		duration,
		easing,
		amount,
		opacity
	}?: BlurParams | undefined
): TransitionConfig;
```

## crossfade[](#crossfade)

The `crossfade` function creates a pair of [transitions](/docs/svelte/transition) called `send` and `receive`. When an element is ‘sent’, it looks for a corresponding element being ‘received’, and generates a transition that transforms the element to its counterpart’s position and fades it out. When an element is ‘received’, the reverse happens. If there is no counterpart, the `fallback` transition is used.

```
function crossfade({
	fallback,
	...defaults
}: CrossfadeParams & {
	fallback?: (
		node: Element,
		params: CrossfadeParams,
		intro: boolean
	) => TransitionConfig;
}): [
	(
		node: any,
		params: CrossfadeParams & {
			key: any;
		}
	) => () => TransitionConfig,
	(
		node: any,
		params: CrossfadeParams & {
			key: any;
		}
	) => () => TransitionConfig
];
```

## draw[](#draw)

Animates the stroke of an SVG element, like a snake in a tube. `in` transitions begin with the path invisible and draw the path to the screen over time. `out` transitions start in a visible state and gradually erase the path. `draw` only works with elements that have a `getTotalLength` method, like `<path>` and `<polyline>`.

```
function draw(
	node: SVGElement & {
		getTotalLength(): number;
	},
	{
		delay,
		speed,
		duration,
		easing
	}?: DrawParams | undefined
): TransitionConfig;
```

## fade[](#fade)

Animates the opacity of an element from 0 to the current opacity for `in` transitions and from the current opacity to 0 for `out` transitions.

```
function fade(
	node: Element,
	{ delay, duration, easing }?: FadeParams | undefined
): TransitionConfig;
```

## fly[](#fly)

Animates the x and y positions and the opacity of an element. `in` transitions animate from the provided values, passed as parameters to the element’s default values. `out` transitions animate from the element’s default values to the provided values.

```
function fly(
	node: Element,
	{
		delay,
		duration,
		easing,
		x,
		y,
		opacity
	}?: FlyParams | undefined
): TransitionConfig;
```

## scale[](#scale)

Animates the opacity and scale of an element. `in` transitions animate from the provided values, passed as parameters, to an element’s current (default) values. `out` transitions animate from an element’s default values to the provided values.

```
function scale(
	node: Element,
	{
		delay,
		duration,
		easing,
		start,
		opacity
	}?: ScaleParams | undefined
): TransitionConfig;
```

## slide[](#slide)

Slides an element in and out.

```
function slide(
	node: Element,
	{
		delay,
		duration,
		easing,
		axis
	}?: SlideParams | undefined
): TransitionConfig;
```

## BlurParams[](#BlurParams)

```
interface BlurParams {/*…*/}
```

```
delay?: number;
```

```
duration?: number;
```

```
easing?: EasingFunction;
```

```
amount?: number | string;
```

```
opacity?: number;
```

## CrossfadeParams[](#CrossfadeParams)

```
interface CrossfadeParams {/*…*/}
```

```
delay?: number;
```

```
duration?: number | ((len: number) => number);
```

```
easing?: EasingFunction;
```

## DrawParams[](#DrawParams)

```
interface DrawParams {/*…*/}
```

```
delay?: number;
```

```
speed?: number;
```

```
duration?: number | ((len: number) => number);
```

```
easing?: EasingFunction;
```

## EasingFunction[](#EasingFunction)

```
type EasingFunction = (t: number) => number;
```

## FadeParams[](#FadeParams)

```
interface FadeParams {/*…*/}
```

```
delay?: number;
```

```
duration?: number;
```

```
easing?: EasingFunction;
```

## FlyParams[](#FlyParams)

```
interface FlyParams {/*…*/}
```

```
delay?: number;
```

```
duration?: number;
```

```
easing?: EasingFunction;
```

```
x?: number | string;
```

```
y?: number | string;
```

```
opacity?: number;
```

## ScaleParams[](#ScaleParams)

```
interface ScaleParams {/*…*/}
```

```
delay?: number;
```

```
duration?: number;
```

```
easing?: EasingFunction;
```

```
start?: number;
```

```
opacity?: number;
```

## SlideParams[](#SlideParams)

```
interface SlideParams {/*…*/}
```

```
delay?: number;
```

```
duration?: number;
```

```
easing?: EasingFunction;
```

```
axis?: 'x' | 'y';
```

## TransitionConfig[](#TransitionConfig)

```
interface TransitionConfig {/*…*/}
```

```
delay?: number;
```

```
duration?: number;
```

```
easing?: EasingFunction;
```

```
css?: (t: number, u: number) => string;
```

```
tick?: (t: number, u: number) => void;
```

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/98-reference/21-svelte-transition.md) [llms.txt](/docs/svelte/svelte-transition/llms.txt)

previous next

[svelte/store](/docs/svelte/svelte-store) [Compiler errors](/docs/svelte/compiler-errors)

----
url: https://svelte.dev/docs/svelte/legacy-$$slots/llms.txt
----

````
In runes mode, we know which [snippets](snippet) were provided to a component, as they're just normal props.

In legacy mode, the way to know if content was provided for a given slot is with the `$$slots` object, whose keys are the names of the slots passed into the component by the parent.

```svelte
<!--- file: Card.svelte --->
<div>
	<slot name="title" />
	{#if $$slots.description}
		<!-- This <hr> and slot will render only if `slot="description"` is provided. -->
		<hr />
		<slot name="description" />
	{/if}
</div>
```

```svelte
<!--- file: App.svelte --->
<Card>
	<h1 slot="title">Blog Post Title</h1>
	<!-- No slot named "description" was provided so the optional slot will not be rendered. -->
</Card>
```
````

----
url: https://svelte.dev/docs/svelte/svelte-easing
----

[Skip to main content](#main)

This module provides a set of functions that allow you to manipulate time values in different ways. It’s particularly useful for animations when combined with the `motion` module.

```
import {
	backIn(alias) function backIn(t: number): number
import backIn

Rebound effect on start.


reference,
	backInOut(alias) function backInOut(t: number): number
import backInOut

Rebound effect on start and end of value range.


reference,
	backOut(alias) function backOut(t: number): number
import backOut

Rebound effect on end.


reference,
	bounceIn(alias) function bounceIn(t: number): number
import bounceIn

Bounce effect on start.


reference,
	bounceInOut(alias) function bounceInOut(t: number): number
import bounceInOut

Bounce effect on start and end.


reference,
	bounceOut(alias) function bounceOut(t: number): number
import bounceOut

Bounce effect on end.


reference,
	circIn(alias) function circIn(t: number): number
import circIn

Circular effect, accelerate on start.


reference,
	circInOut(alias) function circInOut(t: number): number
import circInOut

Circular effect, accelerate on start, decelerate towards end.


reference,
	circOut(alias) function circOut(t: number): number
import circOut

Circular effect, decelerate towards end.


reference,
	cubicIn(alias) function cubicIn(t: number): number
import cubicIn

Cubic scaling, accelerate on start


reference,
	cubicInOut(alias) function cubicInOut(t: number): number
import cubicInOut

Cubic scaling, accelerate on start, decelerate towards end.


reference,
	cubicOut(alias) function cubicOut(t: number): number
import cubicOut

Cubic scaling, decelerate towards end.


reference,
	elasticIn(alias) function elasticIn(t: number): number
import elasticIn

Elastic effect on start.


reference,
	elasticInOut(alias) function elasticInOut(t: number): number
import elasticInOut

Elastic effect on start and end.


reference,
	elasticOut(alias) function elasticOut(t: number): number
import elasticOut

Elastic effect on end.


reference,
	expoIn(alias) function expoIn(t: number): number
import expoIn

Exponential effect on start.


reference,
	expoInOut(alias) function expoInOut(t: number): number
import expoInOut

Exponential effect on start and end.


reference,
	expoOut(alias) function expoOut(t: number): number
import expoOut

Exponential effect on end.


reference,
	linear(alias) function linear(t: number): number
import linear

Returns value as is.


reference,
	quadIn(alias) function quadIn(t: number): number
import quadIn

Quadratic scaling, accelerate on start.


reference,
	quadInOut(alias) function quadInOut(t: number): number
import quadInOut

Quadratic scaling, accelerate on start, decelerate towards end.


reference,
	quadOut(alias) function quadOut(t: number): number
import quadOut

Quadratic scaling, decelerate towards end.


reference,
	quartIn(alias) function quartIn(t: number): number
import quartIn

Quartic scaling, accelerate on start.


reference,
	quartInOut(alias) function quartInOut(t: number): number
import quartInOut

Quartic scaling, accelerate on start, decelerate towards end.


reference,
	quartOut(alias) function quartOut(t: number): number
import quartOut

Quartic scaling, decelerate towards end.


reference,
	quintIn(alias) function quintIn(t: number): number
import quintIn

Quintic scaling, accelerate on start.


reference,
	quintInOut(alias) function quintInOut(t: number): number
import quintInOut

Quintic scaling, accelerate on start, decelerate towards end.


reference,
	quintOut(alias) function quintOut(t: number): number
import quintOut

Quintic scaling, decelerate towards end.


reference,
	sineIn(alias) function sineIn(t: number): number
import sineIn

Sinusoidal effect, accelerate on start.


reference,
	sineInOut(alias) function sineInOut(t: number): number
import sineInOut

Sinusoidal effect, accelerate on start, decelerate towards end.


reference,
	sineOut(alias) function sineOut(t: number): number
import sineOut

Sinusoidal effect, decelerate towards end.


reference
} from 'svelte/easing';
```

## backIn[](#backIn)

Rebound effect on start.

```
function backIn(t: number): number;
```

## backInOut[](#backInOut)

Rebound effect on start and end of value range.

```
function backInOut(t: number): number;
```

## backOut[](#backOut)

Rebound effect on end.

```
function backOut(t: number): number;
```

## bounceIn[](#bounceIn)

Bounce effect on start.

```
function bounceIn(t: number): number;
```

## bounceInOut[](#bounceInOut)

Bounce effect on start and end.

```
function bounceInOut(t: number): number;
```

## bounceOut[](#bounceOut)

Bounce effect on end.

```
function bounceOut(t: number): number;
```

## circIn[](#circIn)

Circular effect, accelerate on start.

```
function circIn(t: number): number;
```

## circInOut[](#circInOut)

Circular effect, accelerate on start, decelerate towards end.

```
function circInOut(t: number): number;
```

## circOut[](#circOut)

Circular effect, decelerate towards end.

```
function circOut(t: number): number;
```

## cubicIn[](#cubicIn)

Cubic scaling, accelerate on start

```
function cubicIn(t: number): number;
```

## cubicInOut[](#cubicInOut)

Cubic scaling, accelerate on start, decelerate towards end.

```
function cubicInOut(t: number): number;
```

## cubicOut[](#cubicOut)

Cubic scaling, decelerate towards end.

```
function cubicOut(t: number): number;
```

## elasticIn[](#elasticIn)

Elastic effect on start.

```
function elasticIn(t: number): number;
```

## elasticInOut[](#elasticInOut)

Elastic effect on start and end.

```
function elasticInOut(t: number): number;
```

## elasticOut[](#elasticOut)

Elastic effect on end.

```
function elasticOut(t: number): number;
```

## expoIn[](#expoIn)

Exponential effect on start.

```
function expoIn(t: number): number;
```

## expoInOut[](#expoInOut)

Exponential effect on start and end.

```
function expoInOut(t: number): number;
```

## expoOut[](#expoOut)

Exponential effect on end.

```
function expoOut(t: number): number;
```

## linear[](#linear)

Returns value as is.

```
function linear(t: number): number;
```

## quadIn[](#quadIn)

Quadratic scaling, accelerate on start.

```
function quadIn(t: number): number;
```

## quadInOut[](#quadInOut)

Quadratic scaling, accelerate on start, decelerate towards end.

```
function quadInOut(t: number): number;
```

## quadOut[](#quadOut)

Quadratic scaling, decelerate towards end.

```
function quadOut(t: number): number;
```

## quartIn[](#quartIn)

Quartic scaling, accelerate on start.

```
function quartIn(t: number): number;
```

## quartInOut[](#quartInOut)

Quartic scaling, accelerate on start, decelerate towards end.

```
function quartInOut(t: number): number;
```

## quartOut[](#quartOut)

Quartic scaling, decelerate towards end.

```
function quartOut(t: number): number;
```

## quintIn[](#quintIn)

Quintic scaling, accelerate on start.

```
function quintIn(t: number): number;
```

## quintInOut[](#quintInOut)

Quintic scaling, accelerate on start, decelerate towards end.

```
function quintInOut(t: number): number;
```

## quintOut[](#quintOut)

Quintic scaling, decelerate towards end.

```
function quintOut(t: number): number;
```

## sineIn[](#sineIn)

Sinusoidal effect, accelerate on start.

```
function sineIn(t: number): number;
```

## sineInOut[](#sineInOut)

Sinusoidal effect, accelerate on start, decelerate towards end.

```
function sineInOut(t: number): number;
```

## sineOut[](#sineOut)

Sinusoidal effect, decelerate towards end.

```
function sineOut(t: number): number;
```

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/98-reference/21-svelte-easing.md) [llms.txt](/docs/svelte/svelte-easing/llms.txt)

previous next

[svelte/compiler](/docs/svelte/svelte-compiler) [svelte/events](/docs/svelte/svelte-events)

----
url: https://svelte.dev/docs/svelte/runtime-warnings/llms.txt
----

````
## Client warnings

<!-- This file is generated by scripts/process-messages/index.js. Do not edit! -->

### assignment_value_stale

```
Assignment to `%property%` property (%location%) will evaluate to the right-hand side, not the value of `%property%` following the assignment. This may result in unexpected behaviour.
```

Given a case like this...

```svelte
<script>
	let object = $state({ array: null });

	function add() {
		(object.array ??= []).push(object.array.length);
	}
</script>

<button onclick={add}>add</button>
<p>items: {JSON.stringify(object.items)}</p>
```

...the array being pushed to when the button is first clicked is the `[]` on the right-hand side of the assignment, but the resulting value of `object.array` is an empty state proxy. As a result, the pushed value will be discarded.

You can fix this by separating it into two statements:

```js
let object = { array: [0] };
// ---cut---
function add() {
	object.array ??= [];
	object.array.push(object.array.length);
}
```

### await_reactivity_loss

```
Detected reactivity loss when reading `%name%`. This happens when state is read in an async function after an earlier `await`
```

Svelte's signal-based reactivity works by tracking which bits of state are read when a template or `$derived(...)` expression executes. If an expression contains an `await`, Svelte transforms it such that any state _after_ the `await` is also tracked — in other words, in a case like this...

```js
let a = Promise.resolve(1);
let b = 2;
// ---cut---
let total = $derived(await a + b);
```

...both `a` and `b` are tracked, even though `b` is only read once `a` has resolved, after the initial execution.

This does _not_ apply to an `await` that is not 'visible' inside the expression. In a case like this...

```js
let a = Promise.resolve(1);
let b = 2;
// ---cut---
async function sum() {
	return await a + b;
}

let total = $derived(await sum());
```

...`total` will depend on `a` (which is read immediately) but not `b` (which is not). The solution is to pass the values into the function:

```js
let a = Promise.resolve(1);
let b = 2;
// ---cut---
/**
 * @param {Promise<number>} a
 * @param {number} b
 */
async function sum(a, b) {
	return await a + b;
}

let total = $derived(await sum(a, b));
```

### await_waterfall

```
An async derived, `%name%` (%location%) was not read immediately after it resolved. This often indicates an unnecessary waterfall, which can slow down your app
```

In a case like this...

```js
async function one() { return 1 }
async function two() { return 2 }
// ---cut---
let a = $derived(await one());
let b = $derived(await two());
```

...the second `$derived` will not be created until the first one has resolved. Since `await two()` does not depend on the value of `a`, this delay, often described as a 'waterfall', is unnecessary.

(Note that if the values of `await one()` and `await two()` subsequently change, they can do so concurrently — the waterfall only occurs when the deriveds are first created.)

You can solve this by creating the promises first and _then_ awaiting them:

```js
async function one() { return 1 }
async function two() { return 2 }
// ---cut---
let aPromise = $derived(one());
let bPromise = $derived(two());

let a = $derived(await aPromise);
let b = $derived(await bPromise);
```

### binding_property_non_reactive

```
`%binding%` is binding to a non-reactive property
```

```
`%binding%` (%location%) is binding to a non-reactive property
```

### console_log_state

```
Your `console.%method%` contained `$state` proxies. Consider using `$inspect(...)` or `$state.snapshot(...)` instead
```

When logging a [proxy](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy), browser devtools will log the proxy itself rather than the value it represents. In the case of Svelte, the 'target' of a `$state` proxy might not resemble its current value, which can be confusing.

The easiest way to log a value as it changes over time is to use the [`$inspect`](/docs/svelte/$inspect) rune. Alternatively, to log things on a one-off basis (for example, inside an event handler) you can use [`$state.snapshot`](/docs/svelte/$state#$state.snapshot) to take a snapshot of the current value.

### derived_inert

```
Reading a derived belonging to a now-destroyed effect may result in stale values
```

A `$derived` value created inside an effect will stop updating when the effect is destroyed. You should create the `$derived` outside the effect, or inside an `$effect.root`.

### event_handler_invalid

```
%handler% should be a function. Did you mean to %suggestion%?
```

### hydratable_missing_but_expected

```
Expected to find a hydratable with key `%key%` during hydration, but did not.
```

This can happen if you render a hydratable on the client that was not rendered on the server, and means that it was forced to fall back to running its function blockingly during hydration. This is bad for performance, as it blocks hydration until the asynchronous work completes.

```svelte
<script>
  import { hydratable } from 'svelte';

	if (BROWSER) {
		// bad! nothing can become interactive until this asynchronous work is done
		await hydratable('foo', get_slow_random_number);
	}
</script>
```

### hydration_attribute_changed

```
The `%attribute%` attribute on `%html%` changed its value between server and client renders. The client value, `%value%`, will be ignored in favour of the server value
```

Certain attributes like `src` on an `<img>` element will not be repaired during hydration, i.e. the server value will be kept. That's because updating these attributes can cause the image to be refetched (or in the case of an `<iframe>`, for the frame to be reloaded), even if they resolve to the same resource.

To fix this, either silence the warning with a [`svelte-ignore`](basic-markup#Comments) comment, or ensure that the value stays the same between server and client. If you really need the value to change on hydration, you can force an update like this:

```svelte
<script>
	let { src } = $props();

	if (typeof window !== 'undefined') {
		// stash the value...
		const initial = src;

		// unset it...
		src = undefined;

		$effect(() => {
			// ...and reset after we've mounted
			src = initial;
		});
	}
</script>

<img {src} />
```

### hydration_html_changed

```
The value of an `{@html ...}` block changed between server and client renders. The client value will be ignored in favour of the server value
```

```
The value of an `{@html ...}` block %location% changed between server and client renders. The client value will be ignored in favour of the server value
```

If the `{@html ...}` value changes between the server and the client, it will not be repaired during hydration, i.e. the server value will be kept. That's because change detection during hydration is expensive and usually unnecessary.

To fix this, either silence the warning with a [`svelte-ignore`](basic-markup#Comments) comment, or ensure that the value stays the same between server and client. If you really need the value to change on hydration, you can force an update like this:

```svelte
<script>
	let { markup } = $props();

	if (typeof window !== 'undefined') {
		// stash the value...
		const initial = markup;

		// unset it...
		markup = undefined;

		$effect(() => {
			// ...and reset after we've mounted
			markup = initial;
		});
	}
</script>

{@html markup}
```

### hydration_mismatch

```
Hydration failed because the initial UI does not match what was rendered on the server
```

```
Hydration failed because the initial UI does not match what was rendered on the server. The error occurred near %location%
```

This warning is thrown when Svelte encounters an error while hydrating the HTML from the server. During hydration, Svelte walks the DOM, expecting a certain structure. If that structure is different (for example because the HTML was repaired by the DOM because of invalid HTML), then Svelte will run into issues, resulting in this warning.

During development, this error is often preceded by a `console.error` detailing the offending HTML, which needs fixing.

### invalid_raw_snippet_render

```
The `render` function passed to `createRawSnippet` should return HTML for a single element
```

### legacy_recursive_reactive_block

```
Detected a migrated `$:` reactive block in `%filename%` that both accesses and updates the same reactive value. This may cause recursive updates when converted to an `$effect`.
```

### lifecycle_double_unmount

```
Tried to unmount a component that was not mounted
```

### ownership_invalid_binding

```
%parent% passed property `%prop%` to %child% with `bind:`, but its parent component %owner% did not declare `%prop%` as a binding. Consider creating a binding between %owner% and %parent% (e.g. `bind:%prop%={...}` instead of `%prop%={...}`)
```

Consider three components `GrandParent`, `Parent` and `Child`. If you do `<GrandParent bind:value>`, inside `GrandParent` pass on the variable via `<Parent {value} />` (note the missing `bind:`) and then do `<Child bind:value>` inside `Parent`, this warning is thrown.

To fix it, `bind:` to the value instead of just passing a property (i.e. in this example do `<Parent bind:value />`).

### ownership_invalid_mutation

```
Mutating unbound props (`%name%`, at %location%) is strongly discouraged. Consider using `bind:%prop%={...}` in %parent% (or using a callback) instead
```

Consider the following code:

```svelte
<!--- file: App.svelte --->
<script>
	import Child from './Child.svelte';
	let person = $state({ name: 'Florida', surname: 'Man' });
</script>

<Child {person} />
```

```svelte
<!--- file: Child.svelte --->
<script>
	let { person } = $props();
</script>

<input bind:value={person.name}>
<input bind:value={person.surname}>
```

`Child` is mutating `person` which is owned by `App` without being explicitly "allowed" to do so. This is strongly discouraged since it can create code that is hard to reason about at scale ("who mutated this value?"), hence the warning.

To fix it, either create callback props to communicate changes, or mark `person` as [`$bindable`]($bindable).

### select_multiple_invalid_value

```
The `value` property of a `<select multiple>` element should be an array, but it received a non-array value. The selection will be kept as is.
```

When using `<select multiple value={...}>`, Svelte will mark all selected `<option>` elements as selected by iterating over the array passed to `value`. If `value` is not an array, Svelte will emit this warning and keep the selected options as they are.

To silence the warning, ensure that `value`:

- is an array for an explicit selection
- is `null` or `undefined` to keep the selection as is

### state_proxy_equality_mismatch

```
Reactive `$state(...)` proxies and the values they proxy have different identities. Because of this, comparisons with `%operator%` will produce unexpected results
```

`$state(...)` creates a [proxy](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy) of the value it is passed. The proxy and the value have different identities, meaning equality checks will always return `false`:

```svelte
<script>
	let value = { foo: 'bar' };
	let proxy = $state(value);

	value === proxy; // always false
</script>
```

To resolve this, ensure you're comparing values where both values were created with `$state(...)`, or neither were. Note that `$state.raw(...)` will _not_ create a state proxy.

### svelte_boundary_reset_noop

```
A `<svelte:boundary>` `reset` function only resets the boundary the first time it is called
```

When an error occurs while rendering the contents of a [`<svelte:boundary>`](https://svelte.dev/docs/svelte/svelte-boundary), the `onerror` handler is called with the error plus a `reset` function that attempts to re-render the contents.

This `reset` function should only be called once. After that, it has no effect — in a case like this, where a reference to `reset` is stored outside the boundary, clicking the button while `<Contents />` is rendered will _not_ cause the contents to be rendered again.

```svelte
<script>
	let reset;
</script>

<button onclick={reset}>reset</button>

<svelte:boundary onerror={(e, r) => (reset = r)}>
	<!-- contents -->

	{#snippet failed(e)}
		<p>oops! {e.message}</p>
	{/snippet}
</svelte:boundary>
```

### transition_slide_display

```
The `slide` transition does not work correctly for elements with `display: %value%`
```

The [slide](/docs/svelte/svelte-transition#slide) transition works by animating the `height` of the element, which requires a `display` style like `block`, `flex` or `grid`. It does not work for:

- `display: inline` (which is the default for elements like `<span>`), and its variants like `inline-block`, `inline-flex` and `inline-grid`
- `display: table` and `table-[name]`, which are the defaults for elements like `<table>` and `<tr>`
- `display: contents`


## Shared warnings

<!-- This file is generated by scripts/process-messages/index.js. Do not edit! -->

### dynamic_void_element_content

```
`<svelte:element this="%tag%">` is a void element — it cannot have content
```

Elements such as `<input>` cannot have content, any children passed to these elements will be ignored.

### state_snapshot_uncloneable

```
Value cannot be cloned with `$state.snapshot` — the original value was returned
```

```
The following properties cannot be cloned with `$state.snapshot` — the return value contains the originals:

%properties%
```

`$state.snapshot` tries to clone the given value in order to return a reference that no longer changes. Certain objects may not be cloneable, in which case the original value is returned. In the following example, `property` is cloned, but `window` is not, because DOM elements are uncloneable:

```js
const object = $state({ property: 'this is cloneable', window })
const snapshot = $state.snapshot(object);
```
````

----
url: https://svelte.dev/docs/svelte/use
----

[Skip to main content](#main)

> In Svelte 5.29 and newer, consider using [attachments](@attach) instead, as they are more flexible and composable.

Actions are functions that are called when an element is mounted. They are added with the `use:` directive, and will typically use an `$effect` so that they can reset any state when the element is unmounted:

App

```
<script>
	/** @type {import('svelte/action').Action} */
	function myaction(node) {
		// the node has been mounted in the DOM

		$effect(() => {
			// setup goes here

			return () => {
				// teardown goes here
			};
		});
	}
</script>

<div use:myaction>...</div>
```

```
<script lang="ts">
	import type { Action } from 'svelte/action';

	const myaction: Action = (node) => {
		// the node has been mounted in the DOM

		$effect(() => {
			// setup goes here

			return () => {
				// teardown goes here
			};
		});
	};
</script>

<div use:myaction>...</div>
```

An action can be called with an argument:

App

```
<script>
	/** @type {import('svelte/action').Action} */
	function myaction(node, data) {
		// ...
	}
</script>

<div use:myaction={data}>...</div>
```

```
<script lang="ts">
	import type { Action } from 'svelte/action';

	const myaction: Action = (node, data) => {
		// ...
	};
</script>

<div use:myaction={data}>...</div>
```

The action is only called once (but not during server-side rendering) — it will *not* run again if the argument changes.

> Legacy mode
>
> Prior to the `$effect` rune, actions could return an object with `update` and `destroy` methods, where `update` would be called with the latest value of the argument if it changed. Using effects is preferred.

## Typing[](#Typing)

The `Action` interface receives three optional type arguments — a node type (which can be `Element`, if the action applies to everything), a parameter, and any custom event handlers created by the action:

App

```
<script>
	/**
	 * @type {import('svelte/action').Action<
	 * 	HTMLDivElement,
	 * 	undefined,
	 * 	{
	 * 		onswiperight: (e: CustomEvent) => void;
	 * 		onswipeleft: (e: CustomEvent) => void;
	 * 		// ...
	 * 	}
	 * >}
	 */
	function gestures(node) {
		$effect(() => {
			// ...
			node.dispatchEvent(new CustomEvent('swipeleft'));

			// ...
			node.dispatchEvent(new CustomEvent('swiperight'));
		});
	}
</script>

<div
	use:gestures
	onswipeleft={next}
	onswiperight={prev}
>...</div>
```

```
<script lang="ts">
	import type { Action } from 'svelte/action';

	const gestures: Action<
		HTMLDivElement,
		undefined,
		{
			onswiperight: (e: CustomEvent) => void;
			onswipeleft: (e: CustomEvent) => void;
			// ...
		}
	> = (node) => {
		$effect(() => {
			// ...
			node.dispatchEvent(new CustomEvent('swipeleft'));

			// ...
			node.dispatchEvent(new CustomEvent('swiperight'));
		});
	};
</script>

<div
	use:gestures
	onswipeleft={next}
	onswiperight={prev}
>...</div>
```

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/03-template-syntax/13-use.md) [llms.txt](/docs/svelte/use/llms.txt)

previous next

[bind:](/docs/svelte/bind) [transition:](/docs/svelte/transition)

----
url: https://svelte.dev/docs/svelte/runtime-errors/llms.txt
----

````
## Client errors

<!-- This file is generated by scripts/process-messages/index.js. Do not edit! -->

### async_derived_orphan

```
Cannot create a `$derived(...)` with an `await` expression outside of an effect tree
```

In Svelte there are two types of reaction — [`$derived`](/docs/svelte/$derived) and [`$effect`](/docs/svelte/$effect). Deriveds can be created anywhere, because they run _lazily_ and can be [garbage collected](https://developer.mozilla.org/en-US/docs/Glossary/Garbage_collection) if nothing references them. Effects, by contrast, keep running eagerly whenever their dependencies change, until they are destroyed.

Because of this, effects can only be created inside other effects (or [effect roots](/docs/svelte/$effect#$effect.root), such as the one that is created when you first mount a component) so that Svelte knows when to destroy them.

Some sleight of hand occurs when a derived contains an `await` expression: Since waiting until we read `{await getPromise()}` to call `getPromise` would be too late, we use an effect to instead call it proactively, notifying Svelte when the value is available. But since we're using an effect, we can only create asynchronous deriveds inside another effect.

### bind_invalid_checkbox_value

```
Using `bind:value` together with a checkbox input is not allowed. Use `bind:checked` instead
```

### bind_invalid_export

```
Component %component% has an export named `%key%` that a consumer component is trying to access using `bind:%key%`, which is disallowed. Instead, use `bind:this` (e.g. `<%name% bind:this={component} />`) and then access the property on the bound component instance (e.g. `component.%key%`)
```

### bind_not_bindable

```
A component is attempting to bind to a non-bindable property `%key%` belonging to %component% (i.e. `<%name% bind:%key%={...}>`). To mark a property as bindable: `let { %key% = $bindable() } = $props()`
```

### component_api_changed

```
Calling `%method%` on a component instance (of %component%) is no longer valid in Svelte 5
```

See the [migration guide](/docs/svelte/v5-migration-guide#Components-are-no-longer-classes) for more information.

### component_api_invalid_new

```
Attempted to instantiate %component% with `new %name%`, which is no longer valid in Svelte 5. If this component is not under your control, set the `compatibility.componentApi` compiler option to `4` to keep it working.
```

See the [migration guide](/docs/svelte/v5-migration-guide#Components-are-no-longer-classes) for more information.

### derived_references_self

```
A derived value cannot reference itself recursively
```

### each_key_duplicate

```
Keyed each block has duplicate key at indexes %a% and %b%
```

```
Keyed each block has duplicate key `%value%` at indexes %a% and %b%
```

### each_key_volatile

```
Keyed each block has key that is not idempotent — the key for item at index %index% was `%a%` but is now `%b%`. Keys must be the same each time for a given item
```

The key expression in a keyed each block must return the same value when called multiple times for the same item. Using expressions like `[item.a, item.b]` creates a new array each time, which will never be equal to itself. Instead, use a primitive value or create a stable key like `item.a + '-' + item.b`.

### effect_in_teardown

```
`%rune%` cannot be used inside an effect cleanup function
```

### effect_in_unowned_derived

```
Effect cannot be created inside a `$derived` value that was not itself created inside an effect
```

### effect_orphan

```
`%rune%` can only be used inside an effect (e.g. during component initialisation)
```

Effects can only be created while a parent effect is running. This means that they cannot, for example, be created inside an event handler or after an `await` expression (unless the `await` occurs directly inside a component's `<script>` tag, and not inside an async function).

In very rare cases, it is appropriate to use [`$effect.root`]($effect#$effect.root) so that you can create effects outside the normal component lifecycle.

### effect_pending_outside_reaction

```
`$effect.pending()` can only be called inside an effect or derived
```

### effect_update_depth_exceeded

```
Maximum update depth exceeded. This typically indicates that an effect reads and writes the same piece of state
```

If an effect updates some state that it also depends on, it will re-run, potentially in a loop:

```js
let count = $state(0);

$effect(() => {
	// this both reads and writes `count`,
	// so will run in an infinite loop
	count += 1;
});
```

(Svelte intervenes before this can crash your browser tab.)

The same applies to array mutations, since these both read and write to the array:

```js
let array = $state(['hello']);

$effect(() => {
	array.push('goodbye');
});
```

Note that it's fine for an effect to re-run itself as long as it 'settles':

```js
let array = ['a', 'b', 'c'];
// ---cut---
$effect(() => {
	// this is okay, because sorting an already-sorted array
	// won't result in a mutation
	array.sort();
});
```

Often when encountering this issue, the value in question shouldn't be state (for example, if you are pushing to a `logs` array in an effect, make `logs` a normal array rather than `$state([])`). In the rare cases where you really _do_ need to write to state in an effect — [which you should avoid]($effect#When-not-to-use-$effect) — you can read the state with [untrack](svelte#untrack) to avoid adding it as a dependency.

### flush_sync_in_effect

```
Cannot use `flushSync` inside an effect
```

The `flushSync()` function can be used to flush any pending effects synchronously. It cannot be used if effects are currently being flushed — in other words, you can call it after a state change but _not_ inside an effect.

This restriction only applies when using the `experimental.async` option, which will be active by default in Svelte 6.

### fork_discarded

```
Cannot commit a fork that was already discarded
```

### fork_timing

```
Cannot create a fork inside an effect or when state changes are pending
```

### get_abort_signal_outside_reaction

```
`getAbortSignal()` can only be called inside an effect or derived
```

### hydratable_missing_but_required

```
Expected to find a hydratable with key `%key%` during hydration, but did not.
```

This can happen if you render a hydratable on the client that was not rendered on the server, and means that it was forced to fall back to running its function blockingly during hydration. This is bad for performance, as it blocks hydration until the asynchronous work completes.

```svelte
<script>
  import { hydratable } from 'svelte';

	if (BROWSER) {
		// bad! nothing can become interactive until this asynchronous work is done
		await hydratable('foo', get_slow_random_number);
	}
</script>
```

### hydration_failed

```
Failed to hydrate the application
```

### invalid_snippet

```
Could not `{@render}` snippet due to the expression being `null` or `undefined`. Consider using optional chaining `{@render snippet?.()}`
```

### lifecycle_legacy_only

```
`%name%(...)` cannot be used in runes mode
```

### props_invalid_value

```
Cannot do `bind:%key%={undefined}` when `%key%` has a fallback value
```

### props_rest_readonly

```
Rest element properties of `$props()` such as `%property%` are readonly
```

### rune_outside_svelte

```
The `%rune%` rune is only available inside `.svelte` and `.svelte.js/ts` files
```

### state_descriptors_fixed

```
Property descriptors defined on `$state` objects must contain `value` and always be `enumerable`, `configurable` and `writable`.
```

### state_prototype_fixed

```
Cannot set prototype of `$state` object
```

### state_unsafe_mutation

```
Updating state inside `$derived(...)`, `$inspect(...)` or a template expression is forbidden. If the value should not be reactive, declare it without `$state`
```

This error occurs when state is updated while evaluating a `$derived`. You might encounter it while trying to 'derive' two pieces of state in one go:

```svelte
<script>
	let count = $state(0);

	let even = $state(true);

	let odd = $derived.by(() => {
		even = count % 2 === 0;
		return !even;
	});
</script>

<button onclick={() => count++}>{count}</button>

<p>{count} is even: {even}</p>
<p>{count} is odd: {odd}</p>
```

This is forbidden because it introduces instability: if `<p>{count} is even: {even}</p>` is updated before `odd` is recalculated, `even` will be stale. In most cases the solution is to make everything derived:

```js
let count = 0;
// ---cut---
let even = $derived(count % 2 === 0);
let odd = $derived(!even);
```

If side-effects are unavoidable, use [`$effect`]($effect) instead.

### svelte_boundary_reset_onerror

```
A `<svelte:boundary>` `reset` function cannot be called while an error is still being handled
```

If a [`<svelte:boundary>`](https://svelte.dev/docs/svelte/svelte-boundary) has an `onerror` function, it must not call the provided `reset` function synchronously since the boundary is still in a broken state. Typically, `reset()` is called later, once the error has been resolved.

If it's possible to resolve the error inside the `onerror` callback, you must at least wait for the boundary to settle before calling `reset()`, for example using [`tick`](https://svelte.dev/docs/svelte/lifecycle-hooks#tick):

```svelte
<svelte:boundary onerror={async (error, reset) => {
	fixTheError();
	+++await tick();+++
	reset();
}}>

</svelte:boundary>
```


## Server errors

<!-- This file is generated by scripts/process-messages/index.js. Do not edit! -->

### async_local_storage_unavailable

```
The node API `AsyncLocalStorage` is not available, but is required to use async server rendering.
```

Some platforms require configuration flags to enable this API. Consult your platform's documentation.

### await_invalid

```
Encountered asynchronous work while rendering synchronously.
```

You (or the framework you're using) called [`render(...)`](svelte-server#render) with a component containing an `await` expression. Either `await` the result of `render` or wrap the `await` (or the component containing it) in a [`<svelte:boundary>`](svelte-boundary) with a `pending` snippet.

### dynamic_element_invalid_tag

```
`<svelte:element this="%tag%">` is not a valid element name — the element will not be rendered
```

The value passed to the `this` prop of `<svelte:element>` must be a valid HTML element, SVG element, MathML element, or custom element name. A value containing invalid characters (such as whitespace or special characters) was provided, which could be a security risk. Ensure only valid tag names are passed.

### html_deprecated

```
The `html` property of server render results has been deprecated. Use `body` instead.
```

### hydratable_clobbering

```
Attempted to set `hydratable` with key `%key%` twice with different values.

%stack%
```

This error occurs when using `hydratable` multiple times with the same key. To avoid this, you can:
- Ensure all invocations with the same key result in the same value
- Update the keys to make both instances unique

```svelte
<script>
  import { hydratable } from 'svelte';

  // which one should "win" and be serialized in the rendered response?
  const one = hydratable('not-unique', () => 1);
  const two = hydratable('not-unique', () => 2);
</script>
```

### hydratable_serialization_failed

```
Failed to serialize `hydratable` data for key `%key%`.

`hydratable` can serialize anything [`uneval` from `devalue`](https://npmjs.com/package/uneval) can, plus Promises.

Cause:
%stack%
```

### invalid_csp

```
`csp.nonce` was set while `csp.hash` was `true`. These options cannot be used simultaneously.
```

### invalid_id_prefix

```
The `idPrefix` option cannot include `--`.
```

### lifecycle_function_unavailable

```
`%name%(...)` is not available on the server
```

Certain methods such as `mount` cannot be invoked while running in a server context. Avoid calling them eagerly, i.e. not during render.

### server_context_required

```
Could not resolve `render` context.
```

Certain functions such as `hydratable` cannot be invoked outside of a `render(...)` call, such as at the top level of a module.


## Shared errors

<!-- This file is generated by scripts/process-messages/index.js. Do not edit! -->

### experimental_async_required

```
Cannot use `%name%(...)` unless the `experimental.async` compiler option is `true`
```

### invalid_default_snippet

```
Cannot use `{@render children(...)}` if the parent component uses `let:` directives. Consider using a named snippet instead
```

This error would be thrown in a setup like this:

```svelte
<!--- file: Parent.svelte --->
<List {items} let:entry>
    <span>{entry}</span>
</List>
```

```svelte
<!--- file: List.svelte --->
<script>
    let { items, children } = $props();
</script>

<ul>
    {#each items as item}
        <li>{@render children(item)}</li>
    {/each}
</ul>
```

Here, `List.svelte` is using `{@render children(item)` which means it expects `Parent.svelte` to use snippets. Instead, `Parent.svelte` uses the deprecated `let:` directive. This combination of APIs is incompatible, hence the error.

### invalid_snippet_arguments

```
A snippet function was passed invalid arguments. Snippets should only be instantiated via `{@render ...}`
```

### invariant_violation

```
An invariant violation occurred, meaning Svelte's internal assumptions were flawed. This is a bug in Svelte, not your app — please open an issue at https://github.com/sveltejs/svelte, citing the following message: "%message%"
```

### lifecycle_outside_component

```
`%name%(...)` can only be used during component initialisation
```

Certain lifecycle methods can only be used during component initialisation. To fix this, make sure you're invoking the method inside the _top level of the instance script_ of your component.

```svelte
<script>
    import { onMount } from 'svelte';

    function handleClick() {
        // This is wrong
        onMount(() => {})
    }

    // This is correct
    onMount(() => {})
</script>

<button onclick={handleClick}>click me</button>
```

### missing_context

```
Context was not set in the current component or any of its ancestors
```

The [`createContext()`](svelte#createContext) utility returns a `[get, set, has]` triplet of functions. `get` will throw an error if `set` was not used to set the context in the current component or any of its ancestors.

### set_context_after_init

```
`setContext` must be called when a component first initializes, not in a subsequent effect or after an `await` expression
```

This restriction only applies when using the `experimental.async` option, which will be active by default in Svelte 6.

### snippet_without_render_tag

```
Attempted to render a snippet without a `{@render}` block. This would cause the snippet code to be stringified instead of its content being rendered to the DOM. To fix this, change `{snippet}` to `{@render snippet()}`.
```

A component throwing this error will look something like this (`children` is not being rendered):

```svelte
<script>
    let { children } = $props();
</script>

{children}
```

...or like this (a parent component is passing a snippet where a non-snippet value is expected):

```svelte
<!--- file: Parent.svelte --->
<ChildComponent>
  {#snippet label()}
    <span>Hi!</span>
  {/snippet}
</ChildComponent>
```

```svelte
<!--- file: Child.svelte --->
<script>
  let { label } = $props();
</script>

<!-- This component doesn't expect a snippet, but the parent provided one -->
<p>{label}</p>
```

### store_invalid_shape

```
`%name%` is not a store with a `subscribe` method
```

### svelte_element_invalid_this_value

```
The `this` prop on `<svelte:element>` must be a string, if defined
```
````

----
url: https://svelte.dev/docs/svelte/use/llms.txt
----

````
> [!NOTE]
> In Svelte 5.29 and newer, consider using [attachments](@attach) instead, as they are more flexible and composable.

Actions are functions that are called when an element is mounted. They are added with the `use:` directive, and will typically use an `$effect` so that they can reset any state when the element is unmounted:

```svelte
<!--- file: App.svelte --->
<script>
	/** @type {import('svelte/action').Action} */
	function myaction(node) {
		// the node has been mounted in the DOM

		$effect(() => {
			// setup goes here

			return () => {
				// teardown goes here
			};
		});
	}
</script>

<div use:myaction>...</div>
```

An action can be called with an argument:

```svelte
<!--- file: App.svelte --->
<script>
	/** @type {import('svelte/action').Action} */
	function myaction(node, +++data+++) {
		// ...
	}
</script>

<div use:myaction={+++data+++}>...</div>
```

The action is only called once (but not during server-side rendering) — it will _not_ run again if the argument changes.

> [!LEGACY]
> Prior to the `$effect` rune, actions could return an object with `update` and `destroy` methods, where `update` would be called with the latest value of the argument if it changed. Using effects is preferred.

## Typing

The `Action` interface receives three optional type arguments — a node type (which can be `Element`, if the action applies to everything), a parameter, and any custom event handlers created by the action:

```svelte
<!--- file: App.svelte --->
<script>
	/**
	 * @type {import('svelte/action').Action<
	 * 	HTMLDivElement,
	 * 	undefined,
	 * 	{
	 * 		onswiperight: (e: CustomEvent) => void;
	 * 		onswipeleft: (e: CustomEvent) => void;
	 * 		// ...
	 * 	}
	 * >}
	 */
	function gestures(node) {
		$effect(() => {
			// ...
			node.dispatchEvent(new CustomEvent('swipeleft'));

			// ...
			node.dispatchEvent(new CustomEvent('swiperight'));
		});
	}
</script>

<div
	use:gestures
	onswipeleft={next}
	onswiperight={prev}
>...</div>
```
````

----
url: https://svelte.dev/docs/svelte/svelte-motion/llms.txt
----

````
```js
// @noErrors
import {
	Spring,
	Tween,
	prefersReducedMotion,
	spring,
	tweened
} from 'svelte/motion';
```

## Spring

<blockquote class="since note">

Available since 5.8.0

</blockquote>

A wrapper for a value that behaves in a spring-like fashion. Changes to `spring.target` will cause `spring.current` to
move towards it over time, taking account of the `spring.stiffness` and `spring.damping` parameters.

```svelte
<script>
	import { Spring } from 'svelte/motion';

	const spring = new Spring(0);
</script>

<input type="range" bind:value={spring.target} />
<input type="range" bind:value={spring.current} disabled />
```

<div class="ts-block">

```dts
class Spring<T> {/*…*/}
```

<div class="ts-block-property">

```dts
constructor(value: T, options?: SpringOptions);
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
static of<U>(fn: () => U, options?: SpringOptions): Spring<U>;
```

<div class="ts-block-property-details">

Create a spring whose value is bound to the return value of `fn`. This must be called
inside an effect root (for example, during component initialisation).

```svelte
<script>
	import { Spring } from 'svelte/motion';

	let { number } = $props();

	const spring = Spring.of(() => number);
</script>
```

</div>
</div>

<div class="ts-block-property">

```dts
set(value: T, options?: SpringUpdateOptions): Promise<void>;
```

<div class="ts-block-property-details">

Sets `spring.target` to `value` and returns a `Promise` that resolves if and when `spring.current` catches up to it.

If `options.instant` is `true`, `spring.current` immediately matches `spring.target`.

If `options.preserveMomentum` is provided, the spring will continue on its current trajectory for
the specified number of milliseconds. This is useful for things like 'fling' gestures.

</div>
</div>

<div class="ts-block-property">

```dts
damping: number;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
precision: number;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
stiffness: number;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
target: T;
```

<div class="ts-block-property-details">

The end value of the spring.
This property only exists on the `Spring` class, not the legacy `spring` store.

</div>
</div>

<div class="ts-block-property">

```dts
get current(): T;
```

<div class="ts-block-property-details">

The current value of the spring.
This property only exists on the `Spring` class, not the legacy `spring` store.

</div>
</div></div>



## Tween

<blockquote class="since note">

Available since 5.8.0

</blockquote>

A wrapper for a value that tweens smoothly to its target value. Changes to `tween.target` will cause `tween.current` to
move towards it over time, taking account of the `delay`, `duration` and `easing` options.

```svelte
<script>
	import { Tween } from 'svelte/motion';

	const tween = new Tween(0);
</script>

<input type="range" bind:value={tween.target} />
<input type="range" bind:value={tween.current} disabled />
```

<div class="ts-block">

```dts
class Tween<T> {/*…*/}
```

<div class="ts-block-property">

```dts
static of<U>(fn: () => U, options?: TweenOptions<U> | undefined): Tween<U>;
```

<div class="ts-block-property-details">

Create a tween whose value is bound to the return value of `fn`. This must be called
inside an effect root (for example, during component initialisation).

```svelte
<script>
	import { Tween } from 'svelte/motion';

	let { number } = $props();

	const tween = Tween.of(() => number);
</script>
```

</div>
</div>

<div class="ts-block-property">

```dts
constructor(value: T, options?: TweenOptions<T>);
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
set(value: T, options?: TweenOptions<T> | undefined): Promise<void>;
```

<div class="ts-block-property-details">

Sets `tween.target` to `value` and returns a `Promise` that resolves if and when `tween.current` catches up to it.

If `options` are provided, they will override the tween's defaults.

</div>
</div>

<div class="ts-block-property">

```dts
get current(): T;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
set target(v: T);
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
get target(): T;
```

<div class="ts-block-property-details"></div>
</div></div>



## prefersReducedMotion

<blockquote class="since note">

Available since 5.7.0

</blockquote>

A [media query](/docs/svelte/svelte-reactivity#MediaQuery) that matches if the user [prefers reduced motion](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion).

```svelte
<script>
	import { prefersReducedMotion } from 'svelte/motion';
	import { fly } from 'svelte/transition';

	let visible = $state(false);
</script>

<button onclick={() => visible = !visible}>
	toggle
</button>

{#if visible}
	<p transition:fly={{ y: prefersReducedMotion.current ? 0 : 200 }}>
		flies in, unless the user prefers reduced motion
	</p>
{/if}
```

<div class="ts-block">

```dts
const prefersReducedMotion: MediaQuery;
```

</div>



## spring

<blockquote class="tag deprecated note">

Use [`Spring`](/docs/svelte/svelte-motion#Spring) instead

</blockquote>

The spring function in Svelte creates a store whose value is animated, with a motion that simulates the behavior of a spring. This means when the value changes, instead of transitioning at a steady rate, it "bounces" like a spring would, depending on the physics parameters provided. This adds a level of realism to the transitions and can enhance the user experience.

<div class="ts-block">

```dts
function spring<T = any>(
	value?: T | undefined,
	opts?: SpringOptions | undefined
): Spring<T>;
```

</div>



## tweened

<blockquote class="tag deprecated note">

Use [`Tween`](/docs/svelte/svelte-motion#Tween) instead

</blockquote>

A tweened store in Svelte is a special type of store that provides smooth transitions between state values over time.

<div class="ts-block">

```dts
function tweened<T>(
	value?: T | undefined,
	defaults?: TweenOptions<T> | undefined
): Tweened<T>;
```

</div>



## Spring

<div class="ts-block">

```dts
interface Spring<T> extends Readable<T> {/*…*/}
```

<div class="ts-block-property">

```dts
set(new_value: T, opts?: SpringUpdateOptions): Promise<void>;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
update: (fn: Updater<T>, opts?: SpringUpdateOptions) => Promise<void>;
```

<div class="ts-block-property-details">

<div class="ts-block-property-bullets">

- <span class="tag deprecated">deprecated</span> Only exists on the legacy `spring` store, not the `Spring` class

</div>

</div>
</div>

<div class="ts-block-property">

```dts
subscribe(fn: (value: T) => void): Unsubscriber;
```

<div class="ts-block-property-details">

<div class="ts-block-property-bullets">

- <span class="tag deprecated">deprecated</span> Only exists on the legacy `spring` store, not the `Spring` class

</div>

</div>
</div>

<div class="ts-block-property">

```dts
precision: number;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
damping: number;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
stiffness: number;
```

<div class="ts-block-property-details"></div>
</div></div>

## SpringOptions

<div class="ts-block">

```dts
interface SpringOptions {/*…*/}
```

<div class="ts-block-property">

```dts
stiffness?: number;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
damping?: number;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
precision?: number;
```

<div class="ts-block-property-details"></div>
</div></div>

## SpringUpdateOptions

<div class="ts-block">

```dts
interface SpringUpdateOptions {/*…*/}
```

<div class="ts-block-property">

```dts
hard?: any;
```

<div class="ts-block-property-details">

<div class="ts-block-property-bullets">

- <span class="tag deprecated">deprecated</span> Only use this for the spring store; does nothing when set on the Spring class

</div>

</div>
</div>

<div class="ts-block-property">

```dts
soft?: string | number | boolean;
```

<div class="ts-block-property-details">

<div class="ts-block-property-bullets">

- <span class="tag deprecated">deprecated</span> Only use this for the spring store; does nothing when set on the Spring class

</div>

</div>
</div>

<div class="ts-block-property">

```dts
instant?: boolean;
```

<div class="ts-block-property-details">

Only use this for the Spring class; does nothing when set on the spring store

</div>
</div>

<div class="ts-block-property">

```dts
preserveMomentum?: number;
```

<div class="ts-block-property-details">

Only use this for the Spring class; does nothing when set on the spring store

</div>
</div></div>

## TweenOptions

<div class="ts-block">

```dts
interface TweenOptions<T> {/*…*/}
```

<div class="ts-block-property">

```dts
delay?: number;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
duration?: number | ((from: T, to: T) => number);
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
easing?: (t: number) => number;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
interpolate?: (a: T, b: T) => (t: number) => T;
```

<div class="ts-block-property-details"></div>
</div></div>

## Tweened

<div class="ts-block">

```dts
interface Tweened<T> extends Readable<T> {/*…*/}
```

<div class="ts-block-property">

```dts
set(value: T, opts?: TweenOptions<T>): Promise<void>;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
update(updater: Updater<T>, opts?: TweenOptions<T>): Promise<void>;
```

<div class="ts-block-property-details"></div>
</div></div>

## Updater

<div class="ts-block">

```dts
type Updater<T> = (target_value: T, value: T) => T;
```

</div>
````

----
url: https://svelte.dev/docs/svelte/svelte-action/llms.txt
----

````
This module provides types for [actions](use), which have been superseded by [attachments](@attach).

## Action

Actions are functions that are called when an element is created.
You can use this interface to type such actions.
The following example defines an action that only works on `<div>` elements
and optionally accepts a parameter which it has a default value for:
```ts
export const myAction: Action<HTMLDivElement, { someProperty: boolean } | undefined> = (node, param = { someProperty: true }) => {
	// ...
}
```
`Action<HTMLDivElement>` and `Action<HTMLDivElement, undefined>` both signal that the action accepts no parameters.

You can return an object with methods `update` and `destroy` from the function and type which additional attributes and events it has.
See interface `ActionReturn` for more details.

<div class="ts-block">

```dts
interface Action<
	Element = HTMLElement,
	Parameter = undefined,
	Attributes extends Record<string, any> = Record<
		never,
		any
	>
> {/*…*/}
```

<div class="ts-block-property">

```dts
<Node extends Element>(
	...args: undefined extends Parameter
		? [node: Node, parameter?: Parameter]
		: [node: Node, parameter: Parameter]
): void | ActionReturn<Parameter, Attributes>;
```

<div class="ts-block-property-details"></div>
</div></div>

## ActionReturn

Actions can return an object containing the two properties defined in this interface. Both are optional.
- update: An action can have a parameter. This method will be called whenever that parameter changes,
	immediately after Svelte has applied updates to the markup. `ActionReturn` and `ActionReturn<undefined>` both
	mean that the action accepts no parameters.
- destroy: Method that is called after the element is unmounted

Additionally, you can specify which additional attributes and events the action enables on the applied element.
This applies to TypeScript typings only and has no effect at runtime.

Example usage:
```ts
interface Attributes {
	newprop?: string;
	'on:event': (e: CustomEvent<boolean>) => void;
}

export function myAction(node: HTMLElement, parameter: Parameter): ActionReturn<Parameter, Attributes> {
	// ...
	return {
		update: (updatedParameter) => {...},
		destroy: () => {...}
	};
}
```

<div class="ts-block">

```dts
interface ActionReturn<
	Parameter = undefined,
	Attributes extends Record<string, any> = Record<
		never,
		any
	>
> {/*…*/}
```

<div class="ts-block-property">

```dts
update?: (parameter: Parameter) => void;
```

<div class="ts-block-property-details"></div>
</div>

<div class="ts-block-property">

```dts
destroy?: () => void;
```

<div class="ts-block-property-details"></div>
</div></div>
````

----
url: https://svelte.dev/docs/svelte/style
----

[Skip to main content](#main)

The `style:` directive provides a shorthand for setting multiple styles on an element.

```
<!-- These are equivalent -->
<div style:color="red">...</div>
<div style="color: red;">...</div>
```

The value can contain arbitrary expressions:

```
<div style:color={myColor}>...</div>
```

The shorthand form is allowed:

```
<div style:color>...</div>
```

Multiple styles can be set on a single element:

```
<div style:color style:width="12rem" style:background-color={darkMode ? 'black' : 'white'}>...</div>
```

To mark a style as important, use the `|important` modifier:

```
<div style:color|important="red">...</div>
```

When `style:` directives are combined with `style` attributes, the directives will take precedence, even over `!important` properties:

```
<div style:color="red" style="color: blue">This will be red</div>
<div style:color="red" style="color: blue !important">This will still be red</div>
```

You can set CSS custom properties:

```
<div style:--columns={columns}>...</div>
```

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/03-template-syntax/17-style.md) [llms.txt](/docs/svelte/style/llms.txt)

previous next

[animate:](/docs/svelte/animate) [class](/docs/svelte/class)

----
url: https://svelte.dev/docs/svelte/await-expressions
----

[Skip to main content](#main)

As of Svelte 5.36, you can use the `await` keyword inside your components in three places where it was previously unavailable:

* at the top level of your component’s `<script>`
* inside `$derived(...)` declarations
* inside your markup

This feature is currently experimental, and you must opt in by adding the `experimental.async` option wherever you [configure](/docs/kit/configuration) Svelte, usually `svelte.config.js`:

svelte.config

```
export default {
	compilerOptions(property) compilerOptions: {
    experimental: {
        async: boolean;
    };
}: {
		experimental(property) experimental: {
    async: boolean;
}: {
			async(property) async: boolean: true
		}
	}
};
```

The experimental flag will be removed in Svelte 6.

## Synchronized updates[](#Synchronized-updates)

When an `await` expression depends on a particular piece of state, changes to that state will not be reflected in the UI until the asynchronous work has completed, so that the UI is not left in an inconsistent state. In other words, in an example like this...

[Open in playground](/playground/untitled#H4sIAAAAAAAAA42RwU7DQAxEf8WyOCRqRAoSlzSJxB8gwY1wcBJHrLRxVrvelhLtv6O2QC8cuD6PxjP2ikIzY4XPRxne_SLmk0eIbiTlgAVOxnLA6nXFngJ_ax-duw17tspY4LCIsmjACusweOO07aRTywoEDdwEJeXsLt_90P5K789UOqVwlAGmKIOaRYDGMaMC-hzW07RTOpBRED7Ak19mEzjLphyaFgLri5l5iZpNBTxst3m-g7IE8momMxiyMLKl48XGs0YvQLCB_pwndVKX19RSG3FRQY-Omw4lzj37DqE3MlZ7spGblVL7L12fLo6uXSnBBtY-QQPrpclvwVSXrsUC_7qs8odipT5ygadNWJ3fgemtQCVjD0ZGrCaygdMXiHR87sgBAAA)

```
<script>
	let a = $state(1);
	let b = $state(2);

	async function add(a, b) {
		await new Promise((f) => setTimeout(f, 500)); // artificial delay
		return a + b;
	}
</script>

<input type="number" bind:value={a}>
<input type="number" bind:value={b}>

<p>{a} + {b} = {await add(a, b)}</p>
```

```
<script lang="ts">
	let a = $state(1);
	let b = $state(2);

	async function add(a, b) {
		await new Promise((f) => setTimeout(f, 500)); // artificial delay
		return a + b;
	}
</script>

<input type="number" bind:value={a}>
<input type="number" bind:value={b}>

<p>{a} + {b} = {await add(a, b)}</p>
```

...if you increment `a`, the contents of the `<p>` will *not* immediately update to read this —

```
<p>2 + 2 = 3</p>
```

— instead, the text will update to `2 + 2 = 4` when `add(a, b)` resolves.

Updates can overlap — a fast update will be reflected in the UI while an earlier slow update is still ongoing.

## Concurrency[](#Concurrency)

Svelte will do as much asynchronous work as it can in parallel. For example if you have two `await` expressions in your markup...

```
<p>{await one(x)}</p>
<p>{await two(y)}</p>
```

...both functions will run at the same time, as they are independent expressions, even though they are *visually* sequential.

This does not apply to sequential `await` expressions inside your `<script>` or inside async functions — these run like any other asynchronous JavaScript. An exception is that independent `$derived` expressions will update independently, even though they will run sequentially when they are first created:

```
// `b` will not be created until `a` has resolved,
// but once created they will update independently
// even if `x` and `y` update simultaneously
let alet a: number = $derivedfunction $derived<number>(expression: number): number
namespace $derived

Declares derived state, i.e. one that depends on other state variables.
The expression inside $derived(...) should be free of side-effects.




Example:



let double = $derived(count * 2);

{@link https://svelte.dev/docs/svelte/$derived Documentation}


expression 

The derived state expression


(await onefunction one(x: number): Promise<number>x(xlet x: number));
let blet b: number = $derivedfunction $derived<number>(expression: number): number
namespace $derived

Declares derived state, i.e. one that depends on other state variables.
The expression inside $derived(...) should be free of side-effects.




Example:



let double = $derived(count * 2);

{@link https://svelte.dev/docs/svelte/$derived Documentation}


expression 

The derived state expression


(await twofunction two(y: number): Promise<number>y(ylet y: number));
```

> If you write code like this, expect Svelte to give you an [`await_waterfall`](runtime-warnings#Client-warnings-await_waterfall) warning

## Indicating loading states[](#Indicating-loading-states)

To render placeholder UI, you can wrap content in a `<svelte:boundary>` with a [`pending`](svelte-boundary#Properties-pending) snippet. This will be shown when the boundary is first created, but not for subsequent updates, which are globally coordinated.

After the contents of a boundary have resolved for the first time and have replaced the `pending` snippet, you can detect subsequent async work with [`$effect.pending()`]($effect#$effect.pending). This is what you would use to display a “we’re asynchronously validating your input” spinner next to a form field, for example.

You can also use [`settled()`](svelte#settled) to get a promise that resolves when the current update is complete:

```
import { tick(alias) function tick(): Promise<void>
import tick

Returns a promise that resolves once any pending state changes have been applied.


reference, settled(alias) function settled(): Promise<void>
import settled

Returns a promise that resolves once any state changes, and asynchronous work resulting from them,
have resolved and the DOM has been updated




5.36


reference } from 'svelte';

async function onclickfunction onclick(): Promise<void>() {
	updatinglet updating: boolean = true;

	// without this, the change to `updating` will be
	// grouped with the other changes, meaning it
	// won't be reflected in the UI
	await tick(alias) tick(): Promise<void>
import tick

Returns a promise that resolves once any pending state changes have been applied.


reference();

	colorlet color: string = 'octarine';
	answerlet answer: number = 42;

	await settled(alias) settled(): Promise<void>
import settled

Returns a promise that resolves once any state changes, and asynchronous work resulting from them,
have resolved and the DOM has been updated




5.36


reference();

	// any updates affected by `color` or `answer`
	// have now been applied
	updatinglet updating: boolean = false;
}
```

## Error handling[](#Error-handling)

Errors in `await` expressions will bubble to the nearest [error boundary](svelte-boundary).

## Server-side rendering[](#Server-side-rendering)

Svelte supports asynchronous server-side rendering (SSR) with the `render(...)` API. To use it, simply await the return value:

server

```
import { render(alias) function render<Comp extends SvelteComponent<any> | Component<any>, Props extends ComponentProps<Comp> = ComponentProps<Comp>>(...args: {} extends Props ? [component: Comp extends SvelteComponent<any> ? ComponentType<Comp> : Comp, options?: {
    props?: Omit<Props, "$$slots" | "$$events">;
    context?: Map<any, any>;
    idPrefix?: string;
    csp?: Csp;
    transformError?: (error: unknown) => unknown | Promise<unknown>;
}] : [component: Comp extends SvelteComponent<any> ? ComponentType<Comp> : Comp, options: {
    props: Omit<Props, "$$slots" | "$$events">;
    context?: Map<any, any>;
    idPrefix?: string;
    csp?: Csp;
    transformError?: (error: unknown) => unknown | Promise<unknown>;
}]): RenderOutput
import render

Only available on the server and when compiling with the server option.
Takes a component and returns an object with body and head properties on it, which you can use to populate the HTML when server-rendering your app.


reference } from 'svelte/server';
import App(alias) type App = SvelteComponent<Record<string, any>, any, any>
(alias) const App: LegacyComponentType
import App from './App.svelte';

const { headconst head: string

HTML that goes into the <head>


, bodyconst body: string

HTML that goes somewhere into the <body>


 } = await render(alias) render<SvelteComponent<Record<string, any>, any, any>, Record<string, any>>(component: ComponentType<SvelteComponent<Record<string, any>, any, any>>, options?: {
    props?: Omit<Record<string, any>, "$$slots" | "$$events"> | undefined;
    context?: Map<any, any>;
    idPrefix?: string;
    csp?: Csp;
    transformError?: ((error: unknown) => unknown | Promise<unknown>) | undefined;
} | undefined): RenderOutput
import render

Only available on the server and when compiling with the server option.
Takes a component and returns an object with body and head properties on it, which you can use to populate the HTML when server-rendering your app.


reference(App(alias) const App: LegacyComponentType
import App);
```

> If you’re using a framework like SvelteKit, this is done on your behalf.

If a `<svelte:boundary>` with a `pending` snippet is encountered during SSR, that snippet will be rendered while the rest of the content is ignored. All `await` expressions encountered outside boundaries with `pending` snippets will resolve and render their contents prior to `await render(...)` returning.

> In the future, we plan to add a streaming implementation that renders the content in the background.

## Forking[](#Forking)

The [`fork(...)`](svelte#fork) API, added in 5.42, makes it possible to run `await` expressions that you *expect* to happen in the near future. This is mainly intended for frameworks like SvelteKit to implement preloading when (for example) users signal an intent to navigate.

```
<script>
	import { fork } from 'svelte';
	import Menu from './Menu.svelte';

	let open = $state(false);

	/** @type {import('svelte').Fork | null} */
	let pending = null;

	function preload() {
		pending ??= fork(() => {
			open = true;
		});
	}

	function discard() {
		pending?.discard();
		pending = null;
	}
</script>

<button
	onfocusin={preload}
	onfocusout={discard}
	onpointerenter={preload}
	onpointerleave={discard}
	onclick={() => {
		pending?.commit();
		pending = null;

		// in case `pending` didn't exist
		// (if it did, this is a no-op)
		open = true;
	}}
>open menu</button>

{#if open}
	<!-- any async work inside this component will start
	     as soon as the fork is created -->
	<Menu onclose={() => open = false} />
{/if}
```

## Caveats[](#Caveats)

As an experimental feature, the details of how `await` is handled (and related APIs like `$effect.pending()`) are subject to breaking changes outside of a semver major release, though we intend to keep such changes to a bare minimum.

## Breaking changes[](#Breaking-changes)

Effects run in a slightly different order when the `experimental.async` option is `true`. Specifically, *block* effects like `{#if ...}` and `{#each ...}` now run before an `$effect.pre` or `beforeUpdate` in the same component, which means that in [very rare situations](/playground/untitled?#H4sIAAAAAAAAE22R3VLDIBCFX2WLvUhnTHsf0zre-Q7WmfwtFV2BgU1rJ5N3F0jaOuoVcPbw7VkYhK4_URTiGYkMnIyjDjLsFGO3EvdCKkIvipdB8NlGXxSCPt96snbtj0gctab2-J_eGs2oOWBE6VunLO_2es-EDKZ5x5ZhC0vPNWM2gHXGouNzAex6hHH1cPHil_Lsb95YT9VQX6KUAbS2DrNsBdsdDFHe8_XSYjH1SrhELTe3MLpsemajweiWVPuxHSbKNd-8eQTdE0EBf4OOaSg2hwNhhE_ABB_ulJzjj9FULvIcqgm5vnAqUB7wWFMfhuugQWkcAr8hVD-mq8D12kOep24J_IszToOXdveGDsuNnZwbJUNlXsKnhJdhUcTo42s41YpOSneikDV5HL8BktM6yRcCAAA=) it is possible to update a block that should no longer exist, but only if you update state inside an effect, [which you should avoid]($effect#When-not-to-use-$effect).

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/03-template-syntax/19-await-expressions.md) [llms.txt](/docs/svelte/await-expressions/llms.txt)

previous next

[class](/docs/svelte/class) [Scoped styles](/docs/svelte/scoped-styles)

----
url: https://svelte.dev/docs/svelte/svelte-boundary/llms.txt
----

````
```svelte
<svelte:boundary onerror={handler}>...</svelte:boundary>
```

> [!NOTE]
> This feature was added in 5.3.0

Boundaries allow you to 'wall off' parts of your app, so that you can:

- provide UI that should be shown when [`await`](await-expressions) expressions are first resolving
- handle errors that occur during rendering or while running effects, and provide UI that should be rendered when an error happens

If a boundary handles an error (with a `failed` snippet or `onerror` handler, or both) its existing content will be removed.

> [!NOTE] Errors occurring outside the rendering process (for example, in event handlers or after a `setTimeout` or async work) are _not_ caught by error boundaries.

## Properties

For the boundary to do anything, one or more of the following must be provided.

### `pending`

This snippet will be shown when the boundary is first created, and will remain visible until all the [`await`](await-expressions) expressions inside the boundary have resolved (demo:

```svelte
<svelte:boundary>
	<p>{await delayed('hello!')}</p>

	{#snippet pending()}
		<p>loading...</p>
	{/snippet}
</svelte:boundary>
```

The `pending` snippet will _not_ be shown for subsequent async updates — for these, you can use [`$effect.pending()`]($effect#$effect.pending).

> [!NOTE] During server-side rendering, a boundary with a `pending` snippet renders that snippet and ignores the rest of its content. See [Server-side rendering](await-expressions#Server-side-rendering).


### `failed`

If a `failed` snippet is provided, it will be rendered when an error is thrown inside the boundary, with the `error` and a `reset` function that recreates the contents (demo:

```svelte
<svelte:boundary>
	<FlakyComponent />

	{#snippet failed(error, reset)}
		<button onclick={reset}>oops! try again</button>
	{/snippet}
</svelte:boundary>
```

> [!NOTE]
> As with [snippets passed to components](snippet#Passing-snippets-to-components), the `failed` snippet can be passed explicitly as a property...
>
> ```svelte
> <svelte:boundary {failed}>...</svelte:boundary>
> ```
>
> ...or implicitly by declaring it directly inside the boundary, as in the example above.

### `onerror`

If an `onerror` function is provided, it will be called with the same two `error` and `reset` arguments. This is useful for tracking the error with an error reporting service...

```svelte
<svelte:boundary onerror={(e) => report(e)}>
	...
</svelte:boundary>
```

...or using `error` and `reset` outside the boundary itself:

```svelte
<script>
	let error = $state(null);
	let reset = $state(() => {});

	function onerror(e, r) {
		error = e;
		reset = r;
	}
</script>

<svelte:boundary {onerror}>
	<FlakyComponent />
</svelte:boundary>

{#if error}
	<button onclick={() => {
		error = null;
		reset();
	}}>
		oops! try again
	</button>
{/if}
```

If an error occurs inside the `onerror` function (or if you rethrow the error), it will be handled by a parent boundary if such exists.

## Using `transformError`

By default, error boundaries have no effect on the server — if an error occurs during rendering, the render as a whole will fail.

Since 5.51 you can control this behaviour for boundaries with a `failed` snippet, by calling [`render(...)`](imperative-component-api#render) with a `transformError` function.

> [!NOTE] If you're using Svelte via a framework such as SvelteKit, you most likely don't have direct access to the `render(...)` call — the framework must configure `transformError` on your behalf. SvelteKit will add support for this in the near future, via the [`handleError`](../kit/hooks#handleError) hook.

The `transformError` function must return a JSON-stringifiable object which will be used to render the `failed` snippet. This object will be serialized and used to hydrate the snippet in the browser:

```js
// @errors: 1005
import { render } from 'svelte/server';
import App from './App.svelte';

const { head, body } = await render(App, {
	transformError: (error) => {
		// log the original error, with the stack trace...
		console.error(error);

		// ...and return a sanitized user-friendly error
		// to display in the `failed` snippet
		return {
			message: 'An error occurred!'
		};
	};
});
```

If `transformError` throws (or rethrows) an error, `render(...)` as a whole will fail with that error.

> [!NOTE] Errors that occur during server-side rendering can contain sensitive information in the `message` and `stack`. It's recommended to redact these rather than sending them unaltered to the browser.

If the boundary has an `onerror` handler, it will be called upon hydration with the deserialized error object.

The [`mount`](imperative-component-api#mount) and [`hydrate`](imperative-component-api#hydrate) functions also accept a `transformError` option, which defaults to the identity function. As with `render`, this function transforms a render-time error before it is passed to a `failed` snippet or `onerror` handler.
````

----
url: https://svelte.dev/docs/svelte/@attach/llms.txt
----

````
Attachments are functions that run in an [effect]($effect) when an element is mounted to the DOM or when [state]($state) read inside the function updates.

Optionally, they can return a function that is called before the attachment re-runs, or after the element is later removed from the DOM.

> [!NOTE]
> Attachments are available in Svelte 5.29 and newer.

```svelte
<!--- file: App.svelte --->
<script>
	/** @type {import('svelte/attachments').Attachment} */
	function myAttachment(element) {
		console.log(element.nodeName); // 'DIV'

		return () => {
			console.log('cleaning up');
		};
	}
</script>

<div {@attach myAttachment}>...</div>
```

An element can have any number of attachments.

## Attachment factories

A useful pattern is for a function, such as `tooltip` in this example, to _return_ an attachment (demo:

```svelte
<!--- file: App.svelte --->
<script>
	import tippy from 'tippy.js';

	let content = $state('Hello!');

	/**
	 * @param {string} content
	 * @returns {import('svelte/attachments').Attachment}
	 */
	function tooltip(content) {
		return (element) => {
			const tooltip = tippy(element, { content });
			return tooltip.destroy;
		};
	}
</script>

<input bind:value={content} />

<button {@attach tooltip(content)}>
	Hover me
</button>
```

Since the `tooltip(content)` expression runs inside an [effect]($effect), the attachment will be destroyed and recreated whenever `content` changes. The same thing would happen for any state read _inside_ the attachment function when it first runs. (If this isn't what you want, see [Controlling when attachments re-run](#Controlling-when-attachments-re-run).)

## Inline attachments

Attachments can also be created inline (demo:

```svelte
<!--- file: App.svelte --->
<canvas
	width={32}
	height={32}
	{@attach (canvas) => {
		const context = canvas.getContext('2d');

		$effect(() => {
			context.fillStyle = color;
			context.fillRect(0, 0, canvas.width, canvas.height);
		});
	}}
></canvas>
```

> [!NOTE]
> The nested effect runs whenever `color` changes, while the outer effect (where `canvas.getContext(...)` is called) only runs once, since it doesn't read any reactive state.

## Conditional attachments

Falsy values like `false` or `undefined` are treated as no attachment, enabling conditional usage:

```svelte
<div {@attach enabled && myAttachment}>...</div>
```

## Passing attachments to components

When used on a component, `{@attach ...}` will create a prop whose key is a [`Symbol`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol). If the component then [spreads](/tutorial/svelte/spread-props) props onto an element, the element will receive those attachments.

This allows you to create _wrapper components_ that augment elements (demo:

```svelte
<!--- file: Button.svelte --->
<script>
	/** @type {import('svelte/elements').HTMLButtonAttributes} */
	let { children, ...props } = $props();
</script>

<!-- `props` includes attachments -->
<button {...props}>
	{@render children?.()}
</button>
```

```svelte
<!--- file: App.svelte --->
<script>
	import tippy from 'tippy.js';
	import Button from './Button.svelte';

	let content = $state('Hello!');

	/**
	 * @param {string} content
	 * @returns {import('svelte/attachments').Attachment}
	 */
	function tooltip(content) {
		return (element) => {
			const tooltip = tippy(element, { content });
			return tooltip.destroy;
		};
	}
</script>

<input bind:value={content} />

<Button {@attach tooltip(content)}>
	Hover me
</Button>
```

## Controlling when attachments re-run

Attachments, unlike [actions](use), are fully reactive: `{@attach foo(bar)}` will re-run on changes to `foo` _or_ `bar` (or any state read inside `foo`):

```js
// @errors: 7006 2304 2552
function foo(bar) {
	return (node) => {
		veryExpensiveSetupWork(node);
		update(node, bar);
	};
}
```

In the rare case that this is a problem (for example, if `foo` does expensive and unavoidable setup work) consider passing the data inside a function and reading it in a child effect:

```js
// @errors: 7006 2304 2552
function foo(+++getBar+++) {
	return (node) => {
		veryExpensiveSetupWork(node);

+++		$effect(() => {
			update(node, getBar());
		});+++
	}
}
```

## Creating attachments programmatically

To add attachments to an object that will be spread onto a component or element, use [`createAttachmentKey`](svelte-attachments#createAttachmentKey).

## Converting actions to attachments

If you're using a library that only provides actions, you can convert them to attachments with [`fromAction`](svelte-attachments#fromAction), allowing you to (for example) use them with components.
````

----
url: https://svelte.dev/docs/svelte/await
----

[Skip to main content](#main)

```
{#await expression}...{:then name}...{:catch name}...{/await}
```

```
{#await expression}...{:then name}...{/await}
```

```
{#await expression then name}...{/await}
```

```
{#await expression catch name}...{/await}
```

Await blocks allow you to branch on the three possible states of a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) — pending, fulfilled or rejected.

```
{#await promise}
	<!-- promise is pending -->
	<p>waiting for the promise to resolve...</p>
{:then value}
	<!-- promise was fulfilled or not a Promise -->
	<p>The value is {value}</p>
{:catch error}
	<!-- promise was rejected -->
	<p>Something went wrong: {error.message}</p>
{/await}
```

> During server-side rendering, only the pending branch will be rendered.
>
> If the provided expression is not a `Promise`, only the `:then` branch will be rendered, including during server-side rendering.

The `catch` block can be omitted if you don’t need to render anything when the promise rejects (or no error is possible).

```
{#await promise}
	<!-- promise is pending -->
	<p>waiting for the promise to resolve...</p>
{:then value}
	<!-- promise was fulfilled -->
	<p>The value is {value}</p>
{/await}
```

If you don’t care about the pending state, you can also omit the initial block.

```
{#await promise then value}
	<p>The value is {value}</p>
{/await}
```

Similarly, if you only want to show the error state, you can omit the `then` block.

```
{#await promise catch error}
	<p>The error is {error}</p>
{/await}
```

> You can use `#await` with [`import(...)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import) to render components lazily:
>
> ```
> {#await import('./Component.svelte') then { default: Component }}
> 	<Component />
> {/await}
> ```

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/03-template-syntax/05-await.md) [llms.txt](/docs/svelte/await/llms.txt)

previous next

[{#key ...}](/docs/svelte/key) [{#snippet ...}](/docs/svelte/snippet)

----
url: https://svelte.dev/docs/svelte/basic-markup/llms.txt
----

`````
Markup inside a Svelte component can be thought of as HTML++.

## Tags

A lowercase tag, like `<div>`, denotes a regular HTML element. A capitalised tag or a tag that uses dot notation, such as `<Widget>` or `<my.stuff>`, indicates a _component_.

```svelte
<script>
	import Widget from './Widget.svelte';
</script>

<div>
	<Widget />
</div>
```

## Element attributes

By default, attributes work exactly like their HTML counterparts.

```svelte
<div class="foo">
	<button disabled>can't touch this</button>
</div>
```

As in HTML, values may be unquoted.

<!-- prettier-ignore -->
```svelte
<input type=checkbox />
```

Attribute values can contain JavaScript expressions.

```svelte
<a href="page/{p}">page {p}</a>
```

Or they can _be_ JavaScript expressions.

```svelte
<button disabled={!clickable}>...</button>
```

Boolean attributes are included on the element if their value is [truthy](https://developer.mozilla.org/en-US/docs/Glossary/Truthy) and excluded if it's [falsy](https://developer.mozilla.org/en-US/docs/Glossary/Falsy).

All other attributes are included unless their value is [nullish](https://developer.mozilla.org/en-US/docs/Glossary/Nullish) (`null` or `undefined`).

```svelte
<input required={false} placeholder="This input field is not required" />
<div title={null}>This div has no title attribute</div>
```

> [!NOTE] Quoting a singular expression does not affect how the value is parsed, but in Svelte 6 it will cause the value to be coerced to a string:
>
> <!-- prettier-ignore -->
> ```svelte
> <button disabled="{number !== 42}">...</button>
> ```

When the attribute name and value match (`name={name}`), they can be replaced with `{name}`.

```svelte
<button {disabled}>...</button>
<!-- equivalent to
<button disabled={disabled}>...</button>
-->
```

## Component props

By convention, values passed to components are referred to as _properties_ or _props_ rather than _attributes_, which are a feature of the DOM.

As with elements, `name={name}` can be replaced with the `{name}` shorthand.

```svelte
<Widget foo={bar} answer={42} text="hello" />
```

## Spread attributes

_Spread attributes_ allow many attributes or properties to be passed to an element or component at once.

An element or component can have multiple spread attributes, interspersed with regular ones. Order matters — if `things.a` exists it will take precedence over `a="b"`, while `c="d"` would take precedence over `things.c`:

```svelte
<Widget a="b" {...things} c="d" />
```

## Events

Listening to DOM events is possible by adding attributes to the element that start with `on`. For example, to listen to the `click` event, add the `onclick` attribute to a button:

```svelte
<button onclick={() => console.log('clicked')}>click me</button>
```

Event attributes are case sensitive. `onclick` listens to the `click` event, `onClick` listens to the `Click` event, which is different. This ensures you can listen to custom events that have uppercase characters in them.

Because events are just attributes, the same rules as for attributes apply:

- you can use the shorthand form: `<button {onclick}>click me</button>`
- you can spread them: `<button {...thisSpreadContainsEventAttributes}>click me</button>`

Timing-wise, event attributes always fire after events from bindings (e.g. `oninput` always fires after an update to `bind:value`). Under the hood, some event handlers are attached directly with `addEventListener`, while others are _delegated_.

When using `ontouchstart` and `ontouchmove` event attributes, the handlers are [passive](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#using_passive_listeners) for better performance. This greatly improves responsiveness by allowing the browser to scroll the document immediately, rather than waiting to see if the event handler calls `event.preventDefault()`.

In the very rare cases that you need to prevent these event defaults, you should use [`on`](svelte-events#on) instead (for example inside an action).

### Event delegation

To reduce memory footprint and increase performance, Svelte uses a technique called event delegation. This means that for certain events — see the list below — a single event listener at the application root takes responsibility for running any handlers on the event's path.

There are a few gotchas to be aware of:

- when you manually dispatch an event with a delegated listener, make sure to set the `{ bubbles: true }` option or it won't reach the application root
- when using `addEventListener` directly, avoid calling `stopPropagation` or the event won't reach the application root and handlers won't be invoked. Similarly, handlers added manually inside the application root will run _before_ handlers added declaratively deeper in the DOM (with e.g. `onclick={...}`), in both capturing and bubbling phases. For these reasons it's better to use the `on` function imported from `svelte/events` rather than `addEventListener`, as it will ensure that order is preserved and `stopPropagation` is handled correctly.

The following event handlers are delegated:

- `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

A JavaScript expression can be included as text by surrounding it with curly braces.

```svelte
{expression}
```

Expressions that are `null` or `undefined` will be omitted; all others are [coerced to strings](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String#string_coercion).

Curly braces can be included in a Svelte template by using their [HTML entity](https://developer.mozilla.org/docs/Glossary/Entity) strings: `&lbrace;`, `&lcub;`, or `&#123;` for `{` and `&rbrace;`, `&rcub;`, or `&#125;` for `}`.

If you're using a regular expression (`RegExp`) [literal notation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#literal_notation_and_constructor), you'll need to wrap it in parentheses.

<!-- prettier-ignore -->
```svelte
<h1>Hello {name}!</h1>
<p>{a} + {b} = {a + b}.</p>

<div>{(/^[A-Za-z ]+$/).test(value) ? x : y}</div>
```

The expression will be stringified and escaped to prevent code injections. If you want to render HTML, use the `{@html}` tag instead.

```svelte
{@html potentiallyUnsafeHtmlString}
```

> [!NOTE] Make sure that you either escape the passed string or only populate it with values that are under your control in order to prevent [XSS attacks](https://owasp.org/www-community/attacks/xss/)

## Comments

You can use HTML comments inside components.

```svelte
<!-- this is a comment! --><h1>Hello world</h1>
```

Comments beginning with `svelte-ignore` disable warnings for the next block of markup. Usually, these are accessibility warnings; make sure that you're disabling them for a good reason.

```svelte
<!-- svelte-ignore a11y_autofocus -->
<input bind:value={name} autofocus />
```

You can add a special comment starting with `@component` that will show up when hovering over the component name in other files.

````svelte
<!--
@component
- You can use markdown here.
- You can also use code blocks here.
- Usage:
  ```html
  <Main name="Aretha">
  ```
-->
<script>
	let { name } = $props();
</script>

<main>
	<h1>
		Hello, {name}
	</h1>
</main>
````

You can also put JavaScript-style comments within tags between attributes:

```svelte
<div
  // this is a comment!
  data-foo="bar"
>
  foo bar
</div>
```
`````

----
url: https://svelte.dev/docs/svelte/in-and-out
----

[Skip to main content](#main)

The `in:` and `out:` directives are identical to [`transition:`](transition), except that the resulting transitions are not bidirectional — an `in` transition will continue to ‘play’ alongside the `out` transition, rather than reversing, if the block is outroed while the transition is in progress. If an out transition is aborted, transitions will restart from scratch.

```
<script>
  import { fade, fly } from 'svelte/transition';

  let visible = $state(false);
</script>

<label>
  <input type="checkbox" bind:checked={visible}>
  visible
</label>

{#if visible}
	<div in:fly={{ y: 200 }} out:fade>flies in, fades out</div>
{/if}
```

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/03-template-syntax/15-in-and-out.md) [llms.txt](/docs/svelte/in-and-out/llms.txt)

previous next

[transition:](/docs/svelte/transition) [animate:](/docs/svelte/animate)

----
url: https://svelte.dev/docs/svelte/best-practices/llms.txt
----

````
## `$state`

Only use the `$state` rune for variables that should be _reactive_ — in other words, variables that cause an `$effect`, `$derived` or template expression to update. Everything else can be a normal variable.

Objects and arrays (`$state({...})` or `$state([...])`) are made deeply reactive, meaning mutation will trigger updates. This has a trade-off: in exchange for fine-grained reactivity, the objects must be proxied, which has performance overhead. In cases where you're dealing with large objects that are only ever reassigned (rather than mutated), use `$state.raw` instead. This is often the case with API responses, for example.

## `$derived`

To compute something from state, use `$derived` rather than `$effect`:

```js
// @errors: 2451
let num = 0;
// ---cut---
// do this
let square = $derived(num * num);

// don't do this
let square;

$effect(() => {
	square = num * num;
});
```

> [!NOTE] `$derived` is given an expression, _not_ a function. If you need to use a function (because the expression is complex, for example) use `$derived.by`.

Deriveds are writable — you can assign to them, just like `$state`, except that they will re-evaluate when their expression changes.

If the derived expression is an object or array, it will be returned as-is — it is _not_ made deeply reactive. You can, however, use `$state` inside `$derived.by` in the rare cases that you need this.

## `$effect`

Effects are an escape hatch and should mostly be avoided. In particular, avoid updating state inside effects.

- If you need to sync state to an external library such as D3, it is often neater to use [`{@attach ...}`](@attach)
- If you need to run some code in response to user interaction, put the code directly in an event handler or use a [function binding](bind#Function-bindings) as appropriate
- If you need to log values for debugging purposes, use [`$inspect`]($inspect)
- If you need to observe something external to Svelte, use [`createSubscriber`](svelte-reactivity#createSubscriber)

Never wrap the contents of an effect in `if (browser) {...}` or similar — effects do not run on the server.

## `$props`

Treat props as though they will change. For example, values that depend on props should usually use `$derived`:

```js
// @errors: 2451
let { type } = $props();

// do this
let color = $derived(type === 'danger' ? 'red' : 'green');

// don't do this — `color` will not update if `type` changes
let color = type === 'danger' ? 'red' : 'green';
```

## `$inspect.trace`

`$inspect.trace` is a debugging tool for reactivity. If something is not updating properly or running more than it should you can add `$inspect.trace(label)` as the first line of an `$effect` or `$derived.by` (or any function they call) to trace their dependencies and discover which one triggered an update.

## `#key` block

While the `#key` block is useful when you want transitions/animations to run when a certain expression changes, it can be very expensive — it unmounts every element/component inside each time, so should be used sparingly. Instead of using `#key` to cause expressions in a child component's `<script>` block to re-run, for example, consider wrapping those expressions in `$derived`.

## Events

Any element attribute starting with `on` is treated as an event listener:

```svelte
<button onclick={() => {...}}>click me</button>

<!-- attribute shorthand also works -->
<button {onclick}>...</button>

<!-- so do spread attributes -->
<button {...props}>...</button>
```

If you need to attach listeners to `window` or `document` you can use `<svelte:window>` and `<svelte:document>`:

```svelte
<svelte:window onkeydown={...} />
<svelte:document onvisibilitychange={...} />
```

Avoid using `onMount` or `$effect` for this.

## Snippets

[Snippets](snippet) are a way to define reusable chunks of markup that can be instantiated with the [`{@render ...}`](@render) tag, or passed to components as props. They must be declared within the template.

```svelte
{#snippet greeting(name)}
  <p>hello {name}!</p>
{/snippet}

{@render greeting('world')}
```

> [!NOTE] Snippets declared at the top level of a component (i.e. not inside elements or blocks) can be referenced inside `<script>`. A snippet that doesn't reference component state is also available in a `<script module>`, in which case it can be exported for use by other components.

## Each blocks

Prefer to use [keyed each blocks](each#Keyed-each-blocks) — this improves performance by allowing Svelte to surgically insert or remove items rather than updating the DOM belonging to existing items.

> [!NOTE] The key _must_ uniquely identify the object. Do not use the index as a key.

Avoid destructuring if you need to mutate the item (with something like `bind:value={item.count}`, for example).

## Using JavaScript variables in CSS

If you have a JS variable that you want to use inside CSS you can set a CSS custom property with the `style:` directive.

```svelte
<div style:--columns={columns}>...</div>
```

You can then reference `var(--columns)` inside the component's `<style>`.

## Styling child components

The CSS in a component's `<style>` is scoped to that component. If a parent component needs to control the child's styles, the preferred way is to use CSS custom properties:

```svelte
<!-- Parent.svelte -->
<Child --color="red" />

<!-- Child.svelte -->
<h1>Hello</h1>

<style>
	h1 {
		color: var(--color);
	}
</style>
```

If this is impossible (for example, the child component comes from a library) you can use `:global` to override styles:

```svelte
<div>
	<Child />
</div>

<style>
	div :global {
		h1 {
			color: red;
		}
	}
</style>
```

## Context

Consider using context instead of declaring state in a shared module. This will scope the state to the part of the app that needs it, and eliminate the possibility of it leaking between users when server-side rendering.

Use `createContext` rather than `setContext` and `getContext`, as it provides type safety.

## Async Svelte

If using version 5.36 or higher, you can use [await expressions](await-expressions) and [hydratable](hydratable) to use promises directly inside components. Note that these require the `experimental.async` option to be enabled in the plugin options in `vite.config.js` or in the `svelte.config.js` as they are not yet considered fully stable.

## Avoid legacy features

Always use runes mode for new code, and avoid features that have more modern replacements:

- use `$state` instead of implicit reactivity (e.g. `let count = 0; count += 1`)
- use `$derived` and `$effect` instead of `$:` assignments and statements (but only use effects when there is no better solution)
- use `$props` instead of `export let`, `$$props` and `$$restProps`
- use `onclick={...}` instead of `on:click={...}`
- use `{#snippet ...}` and `{@render ...}` instead of `<slot>` and `$$slots` and `<svelte:fragment>`
- use `<DynamicComponent>` instead of `<svelte:component this={DynamicComponent}>`
- use `import Self from './ThisComponent.svelte'` and `<Self>` instead of `<svelte:self>`
- use classes with `$state` fields to share reactivity between components, instead of using stores
- use `{@attach ...}` instead of `use:action`
- use clsx-style arrays and objects in `class` attributes, instead of the `class:` directive
````

----
url: https://svelte.dev/docs/svelte/key
----

[Skip to main content](#main)

```
{#key expression}...{/key}
```

Key blocks destroy and recreate their contents when the value of an expression changes. When used around components, this will cause them to be reinstantiated and reinitialised:

```
{#key value}
	<Component />
{/key}
```

It’s also useful if you want a transition to play whenever a value changes:

```
{#key value}
	<div transition:fade>{value}</div>
{/key}
```

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/03-template-syntax/04-key.md) [llms.txt](/docs/svelte/key/llms.txt)

previous next

[{#each ...}](/docs/svelte/each) [{#await ...}](/docs/svelte/await)

----
url: https://svelte.dev/docs/svelte/animate
----

[Skip to main content](#main)

An animation is triggered when the contents of a [keyed each block](each#Keyed-each-blocks) are re-ordered. Animations do not run when an element is added or removed, only when the index of an existing data item within the each block changes. Animate directives must be on an element that is an *immediate* child of a keyed each block.

Animations can be used with Svelte’s [built-in animation functions](svelte-animate) or [custom animation functions](#Custom-animation-functions).

```
<!-- When `list` is reordered the animation will run -->
{#each list as item, index (item)}
	<li animate:flip>{item}</li>
{/each}
```

## Animation Parameters[](#Animation-Parameters)

As with actions and transitions, animations can have parameters.

(The double `{{curlies}}` aren’t a special syntax; this is an object literal inside an expression tag.)

```
{#each list as item, index (item)}
	<li animate:flip={{ delay: 500 }}>{item}</li>
{/each}
```

## Custom animation functions[](#Custom-animation-functions)

```
animationany = (node(parameter) node: HTMLElement: HTMLElementinterface HTMLElement

The HTMLElement interface represents any HTML element. Some elements directly implement this interface, while others implement it via an interface that inherits it.




MDN Reference


, { from(property) from: any: DOMRect(parameter) DOMRect: any, to(property) to: any: DOMRect(parameter) DOMRect: any } , params(parameter) params: any: any) => {
	delayany?: numberany,
	durationany?: numberany,
	easingany?: (t(parameter) t: number: number) => numberany,
	cssany?: (t(parameter) t: number: number, u(parameter) u: number: number) => stringany,
	tickany?: (t(parameter) t: number: number, u(parameter) u: number: number) => void
}
```

Animations can use custom functions that provide the `node`, an `animation` object and any `parameters` as arguments. The `animation` parameter is an object containing `from` and `to` properties each containing a [DOMRect](https://developer.mozilla.org/en-US/docs/Web/API/DOMRect#Properties) describing the geometry of the element in its `start` and `end` positions. The `from` property is the DOMRect of the element in its starting position, and the `to` property is the DOMRect of the element in its final position after the list has been reordered and the DOM updated.

If the returned object has a `css` method, Svelte will create a [web animation](https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API) that plays on the element.

The `t` argument passed to `css` is a value that goes from `0` and `1` after the `easing` function has been applied. The `u` argument is equal to `1 - t`.

The function is called repeatedly *before* the animation begins, with different `t` and `u` arguments.

App

```
<script>
	import { cubicOut } from 'svelte/easing';

	/**
	 * @param {HTMLElement} node
	 * @param {{ from: DOMRect; to: DOMRect }} states
	 * @param {any} params
	 */
	function whizz(node, { from, to }, params) {
		const dx = from.left - to.left;
		const dy = from.top - to.top;

		const d = Math.sqrt(dx * dx + dy * dy);

		return {
			delay: 0,
			duration: Math.sqrt(d) * 120,
			easing: cubicOut,
			css: (t, u) => `transform: translate(${u * dx}px, ${u * dy}px) rotate(${t * 360}deg);`
		};
	}
</script>

{#each list as item, index (item)}
	<div animate:whizz>{item}</div>
{/each}
```

```
<script lang="ts">
	import { cubicOut } from 'svelte/easing';

	function whizz(node: HTMLElement, { from, to }: { from: DOMRect; to: DOMRect }, params: any) {
		const dx = from.left - to.left;
		const dy = from.top - to.top;

		const d = Math.sqrt(dx * dx + dy * dy);

		return {
			delay: 0,
			duration: Math.sqrt(d) * 120,
			easing: cubicOut,
			css: (t, u) => `transform: translate(${u * dx}px, ${u * dy}px) rotate(${t * 360}deg);`
		};
	}
</script>

{#each list as item, index (item)}
	<div animate:whizz>{item}</div>
{/each}
```

A custom animation function can also return a `tick` function, which is called *during* the animation with the same `t` and `u` arguments.

> If it’s possible to use `css` instead of `tick`, do so — web animations can run off the main thread, preventing jank on slower devices.

App

```
<script>
	import { cubicOut } from 'svelte/easing';

	/**
	 * @param {HTMLElement} node
	 * @param {{ from: DOMRect; to: DOMRect }} states
	 * @param {any} params
	 */
	function whizz(node, { from, to }, params) {
		const dx = from.left - to.left;
		const dy = from.top - to.top;

		const d = Math.sqrt(dx * dx + dy * dy);

		return {
			delay: 0,
			duration: Math.sqrt(d) * 120,
			easing: cubicOut,
			tick: (t, u) => Object.assign(node.style, { color: t > 0.5 ? 'Pink' : 'Blue' })
		};
	}
</script>

{#each list as item, index (item)}
	<div animate:whizz>{item}</div>
{/each}
```

```
<script lang="ts">
	import { cubicOut } from 'svelte/easing';

	function whizz(node: HTMLElement, { from, to }: { from: DOMRect; to: DOMRect }, params: any) {
		const dx = from.left - to.left;
		const dy = from.top - to.top;

		const d = Math.sqrt(dx * dx + dy * dy);

		return {
			delay: 0,
			duration: Math.sqrt(d) * 120,
			easing: cubicOut,
			tick: (t, u) => Object.assign(node.style, { color: t > 0.5 ? 'Pink' : 'Blue' })
		};
	}
</script>

{#each list as item, index (item)}
	<div animate:whizz>{item}</div>
{/each}
```

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/03-template-syntax/16-animate.md) [llms.txt](/docs/svelte/animate/llms.txt)

previous next

[in: and out:](/docs/svelte/in-and-out) [style:](/docs/svelte/style)

----
url: https://svelte.dev/docs/svelte/class/llms.txt
----

````
There are two ways to set classes on elements: the `class` attribute, and the `class:` directive.

## Attributes

Primitive values are treated like any other attribute:

```svelte
<div class={large ? 'large' : 'small'}>...</div>
```

> [!NOTE]
> For historical reasons, falsy values (like `false` and `NaN`) are stringified (`class="false"`), though `class={undefined}` (or `null`) cause the attribute to be omitted altogether. In a future version of Svelte, all falsy values will cause `class` to be omitted.

### Objects and arrays

Since Svelte 5.16, `class` can be an object or array, and is converted to a string using [clsx](https://github.com/lukeed/clsx).

If the value is an object, the truthy keys are added:

```svelte
<script>
	let { cool } = $props();
</script>

<!-- results in `class="cool"` if `cool` is truthy,
     `class="lame"` otherwise -->
<div class={{ cool, lame: !cool }}>...</div>
```

If the value is an array, the truthy values are combined:

```svelte
<!-- if `faded` and `large` are both truthy, results in
     `class="saturate-0 opacity-50 scale-200"` -->
<div class={[faded && 'saturate-0 opacity-50', large && 'scale-200']}>...</div>
```

Note that whether we're using the array or object form, we can set multiple classes simultaneously with a single condition, which is particularly useful if you're using things like Tailwind.

Arrays can contain arrays and objects, and clsx will flatten them. This is useful for combining local classes with props, for example:

```svelte
<!--- file: Button.svelte --->
<script>
	let props = $props();
</script>

<button {...props} class={['cool-button', props.class]}>
	{@render props.children?.()}
</button>
```

The user of this component has the same flexibility to use a mixture of objects, arrays and strings:

```svelte
<!--- file: App.svelte --->
<script>
	import Button from './Button.svelte';
	let useTailwind = $state(false);
</script>

<Button
	onclick={() => useTailwind = true}
	class={{ 'bg-blue-700 sm:w-1/2': useTailwind }}
>
	Accept the inevitability of Tailwind
</Button>
```

Since Svelte 5.19, Svelte also exposes the `ClassValue` type, which is the type of value that the `class` attribute on elements accept. This is useful if you want to use a type-safe class name in component props:

```svelte
<script lang="ts">
	import type { ClassValue } from 'svelte/elements';

	const props: { class: ClassValue } = $props();
</script>

<div class={['original', props.class]}>...</div>
```

## The `class:` directive

Prior to Svelte 5.16, the `class:` directive was the most convenient way to set classes on elements conditionally.

```svelte
<!-- These are equivalent -->
<div class={{ cool, lame: !cool }}>...</div>
<div class:cool={cool} class:lame={!cool}>...</div>
```

As with other directives, we can use a shorthand when the name of the class coincides with the value:

```svelte
<div class:cool class:lame={!cool}>...</div>
```

> [!NOTE] Unless you're using an older version of Svelte, consider avoiding `class:`, since the attribute is more powerful and composable.
````

----
url: https://svelte.dev/docs/svelte/$state
----

[Skip to main content](#main)

The `$state` rune allows you to create *reactive state*, which means that your UI *reacts* when it changes.

```
<script>
	let count = $state(0);
</script>

<button onclick={() => count++}>
	clicks: {count}
</button>
```

Unlike other frameworks you may have encountered, there is no API for interacting with state — `count` is just a number, rather than an object or a function, and you can update it like you would update any other variable.

### Deep state[](#Deep-state)

If `$state` is used with an array or a simple object, the result is a deeply reactive *state proxy*. [Proxies](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy) allow Svelte to run code when you read or write properties, including via methods like `array.push(...)`, triggering granular updates.

State is proxified recursively until Svelte finds something other than an array or simple object (like a class or an object created with `Object.create`). In a case like this...

```
let todoslet todos: {
    done: boolean;
    text: string;
}[] = $statefunction $state<{
    done: boolean;
    text: string;
}[]>(initial: {
    done: boolean;
    text: string;
}[]): {
    done: boolean;
    text: string;
}[] (+1 overload)
namespace $state

Declares reactive state.




Example:



let count = $state(0);

{@link https://svelte.dev/docs/svelte/$state Documentation}


initial 

The initial value


([
	{
		done(property) done: boolean: false,
		text(property) text: string: 'add more todos'
	}
]);
```

...modifying an individual todo’s property will trigger updates to anything in your UI that depends on that specific property:

```
todosmodule todos
let todos: {
    done: boolean;
    text: string;
}[][0].done(property) done: boolean = !todosmodule todos
let todos: {
    done: boolean;
    text: string;
}[][0].done(property) done: boolean;
```

If you push a new object to the array, it will also be proxified:

```
todoslet todos: {
    done: boolean;
    text: string;
}[].push(method) Array<{ done: boolean; text: string; }>.push(...items: {
    done: boolean;
    text: string;
}[]): number

Appends new elements to the end of an array, and returns the new length of the array.


items 

New elements to add to the array.


({
	done(property) done: boolean: false,
	text(property) text: string: 'eat lunch'
});
```

> When you update properties of proxies, the original object is *not* mutated. If you need to use your own proxy handlers in a state proxy, [you should wrap the object *after* wrapping it in `$state`](/playground/hello-world?version=latest#H4sIAAAAAAAACpWR3WoDIRCFX2UqhWyIJL3erAulL9C7XnQLMe5ksbUqOpsfln33YuyGFNJC8UKdc2bOhw7Myk9kJXsJ0nttO9jcR5KEG9AWJDwHdzwxznbaYGTl68Do5JM_FRifuh-9X8Y9Gkq1rYx4q66cJbQUWcmqqIL2VDe2IYMEbvuOikBADi-GJDSkXG-phId0G-frye2DO2psQYDFQ0Ys8gQO350dUkEydEg82T0GOs0nsSG9g2IqgxACZueo2ZUlpdvoDC6N64qsg1QKY8T2bpZp8gpIfbCQ85Zn50Ud82HkeY83uDjspenxv3jXcSDyjPWf9L1vJf0GH666J-jLu1ery4dV257IWXBWGa0-xFDMQdTTn2ScxWKsn86ROsLwQxqrVR5QM84Ij8TKFD2-cUZSm4O2LSt30kQcvwCgCmfZnAIAAA==).

Note that if you destructure a reactive value, the references are not reactive — as in normal JavaScript, they are evaluated at the point of destructuring:

```
let { donelet done: boolean, textlet text: string } = todosmodule todos
let todos: {
    done: boolean;
    text: string;
}[][0];

// this will not affect the value of `done`
todosmodule todos
let todos: {
    done: boolean;
    text: string;
}[][0].done(property) done: boolean = !todosmodule todos
let todos: {
    done: boolean;
    text: string;
}[][0].done(property) done: boolean;
```

### Classes[](#Classes)

Class instances are not proxied. Instead, you can use `$state` in class fields (whether public or private), or as the first assignment to a property immediately inside the `constructor`:

```
class Todoclass Todo {
	done(property) Todo.done: boolean = $statefunction $state<false>(initial: false): false (+1 overload)
namespace $state

Declares reactive state.




Example:



let count = $state(0);

{@link https://svelte.dev/docs/svelte/$state Documentation}


initial 

The initial value


(false);

	constructor(text(parameter) text: any) {
		this.text(property) Todo.text: any = $statefunction $state<any>(initial: any): any (+1 overload)
namespace $state

Declares reactive state.




Example:



let count = $state(0);

{@link https://svelte.dev/docs/svelte/$state Documentation}


initial 

The initial value


(text(parameter) text: any);
	}

	reset(method) Todo.reset(): void() {
		this.text(property) Todo.text: any = '';
		this.done(property) Todo.done: boolean = false;
	}
}
```

> The compiler transforms `done` and `text` into `get` / `set` methods on the class prototype referencing private fields. This means the properties are not enumerable.

When calling methods in JavaScript, the value of [`this`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this) matters. This won’t work, because `this` inside the `reset` method will be the `<button>` rather than the `Todo`:

```
<button onclick={todo.reset}>
	reset
</button>
```

You can either use an inline function...

```
<button onclick={() => todo.reset()}>
	reset
</button>
```

...or use an arrow function in the class definition:

```
class Todoclass Todo {
	done(property) Todo.done: boolean = $statefunction $state<false>(initial: false): false (+1 overload)
namespace $state

Declares reactive state.




Example:



let count = $state(0);

{@link https://svelte.dev/docs/svelte/$state Documentation}


initial 

The initial value


(false);

	constructor(text(parameter) text: any) {
		this.text(property) Todo.text: any = $statefunction $state<any>(initial: any): any (+1 overload)
namespace $state

Declares reactive state.




Example:



let count = $state(0);

{@link https://svelte.dev/docs/svelte/$state Documentation}


initial 

The initial value


(text(parameter) text: any);
	}

	reset(property) Todo.reset: () => void = () => {
		this.text(property) Todo.text: any = '';
		this.done(property) Todo.done: boolean = false;
	}
}
```

### Built-in classes[](#Built-in-classes)

Svelte provides reactive implementations of built-in classes like `Set`, `Map`, `Date` and `URL` that can be imported from [`svelte/reactivity`](svelte-reactivity).

## $state.raw[](#$state.raw)

In cases where you don’t want objects and arrays to be deeply reactive you can use `$state.raw`.

State declared with `$state.raw` cannot be mutated; it can only be *reassigned*. In other words, rather than assigning to a property of an object, or using an array method like `push`, replace the object or array altogether if you’d like to update it:

```
let personlet person: {
    name: string;
    age: number;
} = $statenamespace $state
function $state<T>(initial: T): T (+1 overload)

Declares reactive state.




Example:



let count = $state(0);

{@link https://svelte.dev/docs/svelte/$state Documentation}


initial 

The initial value


.rawfunction $state.raw<{
    name: string;
    age: number;
}>(initial: {
    name: string;
    age: number;
}): {
    name: string;
    age: number;
} (+1 overload)

Declares state that is not made deeply reactive — instead of mutating it,
you must reassign it.




Example:



<script>
  let items = $state.raw([0]);

  const addItem = () => {
    items = [...items, items.length];
  };
</script>

<button onclick={addItem}>
  {items.join(', ')}
</button>

{@link https://svelte.dev/docs/svelte/$state#$state.raw Documentation}


initial 

The initial value


({
	name(property) name: string: 'Heraclitus',
	age(property) age: number: 49
});

// this will have no effect
personlet person: {
    name: string;
    age: number;
}.age(property) age: number += 1;

// this will work, because we're creating a new person
personlet person: {
    name: string;
    age: number;
} = {
	name(property) name: string: 'Heraclitus',
	age(property) age: number: 50
};
```

This can improve performance with large arrays and objects that you weren’t planning to mutate anyway, since it avoids the cost of making them reactive. Note that raw state can *contain* reactive state (for example, a raw array of reactive objects).

As with `$state`, you can declare class fields using `$state.raw`.

## $state.snapshot[](#$state.snapshot)

To take a static snapshot of a deeply reactive `$state` proxy, use `$state.snapshot`:

```
<script>
	let counter = $state({ count: 0 });

	function onclick() {
		// Will log `{ count: ... }` rather than `Proxy { ... }`
		console.log($state.snapshot(counter));
	}
</script>
```

This is handy when you want to pass some state to an external library or API that doesn’t expect a proxy, such as `structuredClone`.

If a value has a `toJSON` method, the snapshot will clone the value returned from `toJSON` instead of the original object.

## $state.eager[](#$state.eager)

When state changes, it may not be reflected in the UI immediately if it is used by an `await` expression, because [updates are synchronized](await-expressions#Synchronized-updates).

In some cases, you may want to update the UI as soon as the state changes. For example, you might want to update a navigation bar when the user clicks on a link, so that they get visual feedback while waiting for the new page to load. To do this, use `$state.eager(value)`:

```
<nav>
	<a href="/" aria-current={$state.eager(pathname) === '/' ? 'page' : null}>home</a>
	<a href="/about" aria-current={$state.eager(pathname) === '/about' ? 'page' : null}>about</a>
</nav>
```

Use this feature sparingly, and only to provide feedback in response to user action — in general, allowing Svelte to coordinate updates will provide a better user experience.

## Passing state into functions[](#Passing-state-into-functions)

JavaScript is a *pass-by-value* language — when you call a function, the arguments are the *values* rather than the *variables*. In other words:

index

```
/**
 * @param {number} a
 * @param {number} b
 */
function addfunction add(a: number, b: number): numberab(a(parameter) a: numbera, b(parameter) b: numberb) {
	return a(parameter) a: numbera + b(parameter) b: numberb;
}

let alet a: number = 1;
let blet b: number = 2;
let totallet total: number = addfunction add(a: number, b: number): numberab(alet a: number, blet b: number);
consolenamespace console
var console: Console

The console module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.




The module exports two specific components:





A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.


A global console instance configured to write to process.stdout and
process.stderr. The global console can be used without importing the node:console module.





Warning: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the note on process I/O for
more information.




Example using the global console:



console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
//   Error: Whoops, something bad happened
//     at [eval]:5:15
//     at Script.runInThisContext (node:vm:132:18)
//     at Object.runInThisContext (node:vm:309:38)
//     at node:internal/process/execution:77:19
//     at [eval]-wrapper:6:22
//     at evalScript (node:internal/process/execution:76:60)
//     at node:internal/main/eval_string:23:3

const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:



const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);

myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err

const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

source


.log(method) Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to printf(3)
(the arguments are all passed to util.format()).



const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.




v0.1.100


(totallet total: number); // 3

alet a: number = 3;
blet b: number = 4;
consolenamespace console
var console: Console

The console module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.




The module exports two specific components:





A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.


A global console instance configured to write to process.stdout and
process.stderr. The global console can be used without importing the node:console module.





Warning: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the note on process I/O for
more information.




Example using the global console:



console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
//   Error: Whoops, something bad happened
//     at [eval]:5:15
//     at Script.runInThisContext (node:vm:132:18)
//     at Object.runInThisContext (node:vm:309:38)
//     at node:internal/process/execution:77:19
//     at [eval]-wrapper:6:22
//     at evalScript (node:internal/process/execution:76:60)
//     at node:internal/main/eval_string:23:3

const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:



const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);

myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err

const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

source


.log(method) Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to printf(3)
(the arguments are all passed to util.format()).



const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.




v0.1.100


(totallet total: number); // still 3!
```

```
function addfunction add(a: number, b: number): number(a(parameter) a: number: number, b(parameter) b: number: number) {
	return a(parameter) a: number + b(parameter) b: number;
}

let alet a: number = 1;
let blet b: number = 2;
let totallet total: number = addfunction add(a: number, b: number): number(alet a: number, blet b: number);
consolenamespace console
var console: Console

The console module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.




The module exports two specific components:





A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.


A global console instance configured to write to process.stdout and
process.stderr. The global console can be used without importing the node:console module.





Warning: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the note on process I/O for
more information.




Example using the global console:



console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
//   Error: Whoops, something bad happened
//     at [eval]:5:15
//     at Script.runInThisContext (node:vm:132:18)
//     at Object.runInThisContext (node:vm:309:38)
//     at node:internal/process/execution:77:19
//     at [eval]-wrapper:6:22
//     at evalScript (node:internal/process/execution:76:60)
//     at node:internal/main/eval_string:23:3

const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:



const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);

myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err

const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

source


.log(method) Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to printf(3)
(the arguments are all passed to util.format()).



const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.




v0.1.100


(totallet total: number); // 3

alet a: number = 3;
blet b: number = 4;
consolenamespace console
var console: Console

The console module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.




The module exports two specific components:





A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.


A global console instance configured to write to process.stdout and
process.stderr. The global console can be used without importing the node:console module.





Warning: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the note on process I/O for
more information.




Example using the global console:



console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
//   Error: Whoops, something bad happened
//     at [eval]:5:15
//     at Script.runInThisContext (node:vm:132:18)
//     at Object.runInThisContext (node:vm:309:38)
//     at node:internal/process/execution:77:19
//     at [eval]-wrapper:6:22
//     at evalScript (node:internal/process/execution:76:60)
//     at node:internal/main/eval_string:23:3

const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:



const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);

myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err

const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

source


.log(method) Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to printf(3)
(the arguments are all passed to util.format()).



const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.




v0.1.100


(totallet total: number); // still 3!
```

If `add` wanted to have access to the *current* values of `a` and `b`, and to return the current `total` value, you would need to use functions instead:

index

```
/**
 * @param {() => number} getA
 * @param {() => number} getB
 */
function addfunction add(getA: () => number, getB: () => number): () => numbergetAgetB(getA(parameter) getA: () => numbergetA, getB(parameter) getB: () => numbergetB) {
	return () => getA(parameter) getA: () => numbergetA() + getB(parameter) getB: () => numbergetB();
}

let alet a: number = 1;
let blet b: number = 2;
let totallet total: () => number = addfunction add(getA: () => number, getB: () => number): () => numbergetAgetB(() => alet a: number, () => blet b: number);
consolenamespace console
var console: Console

The console module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.




The module exports two specific components:





A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.


A global console instance configured to write to process.stdout and
process.stderr. The global console can be used without importing the node:console module.





Warning: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the note on process I/O for
more information.




Example using the global console:



console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
//   Error: Whoops, something bad happened
//     at [eval]:5:15
//     at Script.runInThisContext (node:vm:132:18)
//     at Object.runInThisContext (node:vm:309:38)
//     at node:internal/process/execution:77:19
//     at [eval]-wrapper:6:22
//     at evalScript (node:internal/process/execution:76:60)
//     at node:internal/main/eval_string:23:3

const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:



const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);

myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err

const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

source


.log(method) Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to printf(3)
(the arguments are all passed to util.format()).



const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.




v0.1.100


(totallet total: () => number()); // 3

alet a: number = 3;
blet b: number = 4;
consolenamespace console
var console: Console

The console module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.




The module exports two specific components:





A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.


A global console instance configured to write to process.stdout and
process.stderr. The global console can be used without importing the node:console module.





Warning: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the note on process I/O for
more information.




Example using the global console:



console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
//   Error: Whoops, something bad happened
//     at [eval]:5:15
//     at Script.runInThisContext (node:vm:132:18)
//     at Object.runInThisContext (node:vm:309:38)
//     at node:internal/process/execution:77:19
//     at [eval]-wrapper:6:22
//     at evalScript (node:internal/process/execution:76:60)
//     at node:internal/main/eval_string:23:3

const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:



const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);

myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err

const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

source


.log(method) Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to printf(3)
(the arguments are all passed to util.format()).



const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.




v0.1.100


(totallet total: () => number()); // 7
```

```
function addfunction add(getA: () => number, getB: () => number): () => number(getA(parameter) getA: () => number: () => number, getB(parameter) getB: () => number: () => number) {
	return () => getA(parameter) getA: () => number() + getB(parameter) getB: () => number();
}

let alet a: number = 1;
let blet b: number = 2;
let totallet total: () => number = addfunction add(getA: () => number, getB: () => number): () => number(() => alet a: number, () => blet b: number);
consolenamespace console
var console: Console

The console module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.




The module exports two specific components:





A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.


A global console instance configured to write to process.stdout and
process.stderr. The global console can be used without importing the node:console module.





Warning: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the note on process I/O for
more information.




Example using the global console:



console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
//   Error: Whoops, something bad happened
//     at [eval]:5:15
//     at Script.runInThisContext (node:vm:132:18)
//     at Object.runInThisContext (node:vm:309:38)
//     at node:internal/process/execution:77:19
//     at [eval]-wrapper:6:22
//     at evalScript (node:internal/process/execution:76:60)
//     at node:internal/main/eval_string:23:3

const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:



const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);

myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err

const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

source


.log(method) Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to printf(3)
(the arguments are all passed to util.format()).



const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.




v0.1.100


(totallet total: () => number()); // 3

alet a: number = 3;
blet b: number = 4;
consolenamespace console
var console: Console

The console module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.




The module exports two specific components:





A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.


A global console instance configured to write to process.stdout and
process.stderr. The global console can be used without importing the node:console module.





Warning: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the note on process I/O for
more information.




Example using the global console:



console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
//   Error: Whoops, something bad happened
//     at [eval]:5:15
//     at Script.runInThisContext (node:vm:132:18)
//     at Object.runInThisContext (node:vm:309:38)
//     at node:internal/process/execution:77:19
//     at [eval]-wrapper:6:22
//     at evalScript (node:internal/process/execution:76:60)
//     at node:internal/main/eval_string:23:3

const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:



const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);

myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err

const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

source


.log(method) Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to printf(3)
(the arguments are all passed to util.format()).



const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.




v0.1.100


(totallet total: () => number()); // 7
```

State in Svelte is no different — when you reference something declared with the `$state` rune...

```
let alet a: number = $statefunction $state<1>(initial: 1): 1 (+1 overload)
namespace $state

Declares reactive state.




Example:



let count = $state(0);

{@link https://svelte.dev/docs/svelte/$state Documentation}


initial 

The initial value


(1);
let blet b: number = $statefunction $state<2>(initial: 2): 2 (+1 overload)
namespace $state

Declares reactive state.




Example:



let count = $state(0);

{@link https://svelte.dev/docs/svelte/$state Documentation}


initial 

The initial value


(2);
```

...you’re accessing its *current value*.

Note that ‘functions’ is broad — it encompasses properties of proxies and [`get`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get)/[`set`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/set) properties...

index

```
/**
 * @param {{ a: number, b: number }} input
 */
function addfunction add(input: {
    a: number;
    b: number;
}): {
    readonly value: number;
}input(input(parameter) input: {
    a: number;
    b: number;
}input) {
	return {
		get value(getter) value: number() {
			return input(parameter) input: {
    a: number;
    b: number;
}input.a(property) a: number + input(parameter) input: {
    a: number;
    b: number;
}input.b(property) b: number;
		}
	};
}

let inputmodule input
let input: {
    a: number;
    b: number;
} = $statefunction $state<{
    a: number;
    b: number;
}>(initial: {
    a: number;
    b: number;
}): {
    a: number;
    b: number;
} (+1 overload)
namespace $state

Declares reactive state.




Example:



let count = $state(0);

{@link https://svelte.dev/docs/svelte/$state Documentation}


initial 

The initial value


({ a(property) a: number: 1, b(property) b: number: 2 });
let totallet total: {
    readonly value: number;
} = addfunction add(input: {
    a: number;
    b: number;
}): {
    readonly value: number;
}input(inputmodule input
let input: {
    a: number;
    b: number;
});
consolenamespace console
var console: Console

The console module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.




The module exports two specific components:





A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.


A global console instance configured to write to process.stdout and
process.stderr. The global console can be used without importing the node:console module.





Warning: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the note on process I/O for
more information.




Example using the global console:



console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
//   Error: Whoops, something bad happened
//     at [eval]:5:15
//     at Script.runInThisContext (node:vm:132:18)
//     at Object.runInThisContext (node:vm:309:38)
//     at node:internal/process/execution:77:19
//     at [eval]-wrapper:6:22
//     at evalScript (node:internal/process/execution:76:60)
//     at node:internal/main/eval_string:23:3

const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:



const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);

myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err

const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

source


.log(method) Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to printf(3)
(the arguments are all passed to util.format()).



const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.




v0.1.100


(totallet total: {
    readonly value: number;
}.value(property) value: number); // 3

inputmodule input
let input: {
    a: number;
    b: number;
}.a(property) a: number = 3;
inputmodule input
let input: {
    a: number;
    b: number;
}.b(property) b: number = 4;
consolenamespace console
var console: Console

The console module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.




The module exports two specific components:





A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.


A global console instance configured to write to process.stdout and
process.stderr. The global console can be used without importing the node:console module.





Warning: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the note on process I/O for
more information.




Example using the global console:



console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
//   Error: Whoops, something bad happened
//     at [eval]:5:15
//     at Script.runInThisContext (node:vm:132:18)
//     at Object.runInThisContext (node:vm:309:38)
//     at node:internal/process/execution:77:19
//     at [eval]-wrapper:6:22
//     at evalScript (node:internal/process/execution:76:60)
//     at node:internal/main/eval_string:23:3

const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:



const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);

myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err

const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

source


.log(method) Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to printf(3)
(the arguments are all passed to util.format()).



const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.




v0.1.100


(totallet total: {
    readonly value: number;
}.value(property) value: number); // 7
```

```
function addfunction add(input: {
    a: number;
    b: number;
}): {
    readonly value: number;
}(input(parameter) input: {
    a: number;
    b: number;
}: { a(property) a: number: number, b(property) b: number: number }) {
	return {
		get value(getter) value: number() {
			return input(parameter) input: {
    a: number;
    b: number;
}.a(property) a: number + input(parameter) input: {
    a: number;
    b: number;
}.b(property) b: number;
		}
	};
}

let inputlet input: {
    a: number;
    b: number;
} = $statefunction $state<{
    a: number;
    b: number;
}>(initial: {
    a: number;
    b: number;
}): {
    a: number;
    b: number;
} (+1 overload)
namespace $state

Declares reactive state.




Example:



let count = $state(0);

{@link https://svelte.dev/docs/svelte/$state Documentation}


initial 

The initial value


({ a(property) a: number: 1, b(property) b: number: 2 });
let totallet total: {
    readonly value: number;
} = addfunction add(input: {
    a: number;
    b: number;
}): {
    readonly value: number;
}(inputlet input: {
    a: number;
    b: number;
});
consolenamespace console
var console: Console

The console module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.




The module exports two specific components:





A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.


A global console instance configured to write to process.stdout and
process.stderr. The global console can be used without importing the node:console module.





Warning: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the note on process I/O for
more information.




Example using the global console:



console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
//   Error: Whoops, something bad happened
//     at [eval]:5:15
//     at Script.runInThisContext (node:vm:132:18)
//     at Object.runInThisContext (node:vm:309:38)
//     at node:internal/process/execution:77:19
//     at [eval]-wrapper:6:22
//     at evalScript (node:internal/process/execution:76:60)
//     at node:internal/main/eval_string:23:3

const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:



const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);

myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err

const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

source


.log(method) Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to printf(3)
(the arguments are all passed to util.format()).



const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.




v0.1.100


(totallet total: {
    readonly value: number;
}.value(property) value: number); // 3

inputlet input: {
    a: number;
    b: number;
}.a(property) a: number = 3;
inputlet input: {
    a: number;
    b: number;
}.b(property) b: number = 4;
consolenamespace console
var console: Console

The console module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.




The module exports two specific components:





A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.


A global console instance configured to write to process.stdout and
process.stderr. The global console can be used without importing the node:console module.





Warning: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the note on process I/O for
more information.




Example using the global console:



console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
//   Error: Whoops, something bad happened
//     at [eval]:5:15
//     at Script.runInThisContext (node:vm:132:18)
//     at Object.runInThisContext (node:vm:309:38)
//     at node:internal/process/execution:77:19
//     at [eval]-wrapper:6:22
//     at evalScript (node:internal/process/execution:76:60)
//     at node:internal/main/eval_string:23:3

const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:



const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);

myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err

const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

source


.log(method) Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to printf(3)
(the arguments are all passed to util.format()).



const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.




v0.1.100


(totallet total: {
    readonly value: number;
}.value(property) value: number); // 7
```

...though if you find yourself writing code like that, consider using [classes](#Classes) instead.

## Passing state across modules[](#Passing-state-across-modules)

You can declare state in `.svelte.js` and `.svelte.ts` files, but you can only *export* that state if it’s not directly reassigned. In other words you can’t do this:

state.svelte

```
export let countlet count: number = $statefunction $state<0>(initial: 0): 0 (+1 overload)
namespace $state

Declares reactive state.




Example:



let count = $state(0);

{@link https://svelte.dev/docs/svelte/$state Documentation}


initial 

The initial value


(0);

export function incrementfunction increment(): void() {
	countlet count: number += 1;
}
```

That’s because every reference to `count` is transformed by the Svelte compiler — the code above is roughly equivalent to this:

state.svelte

```
export let countlet count: Signal<number> = $const $: Svelte.state(method) Svelte.state<number>(value?: number | undefined): Signal<number>(0);

export function incrementfunction increment(): void() {
	$const $: Svelte.set(method) Svelte.set<number>(source: Signal<number>, value: number): void(countlet count: Signal<number>, $const $: Svelte.get(method) Svelte.get<number>(source: Signal<number>): number(countlet count: Signal<number>) + 1);
}
```

> You can see the code Svelte generates by clicking the ‘JS Output’ tab in the [playground](/playground).

Since the compiler only operates on one file at a time, if another file imports `count` Svelte doesn’t know that it needs to wrap each reference in `$.get` and `$.set`:

```
import { count(alias) let count: number
import count } from './state.svelte.js';

consolenamespace console
var console: Console

The console module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.




The module exports two specific components:





A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.


A global console instance configured to write to process.stdout and
process.stderr. The global console can be used without importing the node:console module.





Warning: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the note on process I/O for
more information.




Example using the global console:



console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
//   Error: Whoops, something bad happened
//     at [eval]:5:15
//     at Script.runInThisContext (node:vm:132:18)
//     at Object.runInThisContext (node:vm:309:38)
//     at node:internal/process/execution:77:19
//     at [eval]-wrapper:6:22
//     at evalScript (node:internal/process/execution:76:60)
//     at node:internal/main/eval_string:23:3

const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:



const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);

myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err

const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

source


.log(method) Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to printf(3)
(the arguments are all passed to util.format()).



const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.




v0.1.100


(typeof count(alias) let count: number
import count); // 'object', not 'number'
```

This leaves you with two options for sharing state between modules — either don’t reassign it...

```
// This is allowed — since we're updating
// `counter.count` rather than `counter`,
// Svelte doesn't wrap it in `$.state`
export const counterconst counter: {
    count: number;
} = $statefunction $state<{
    count: number;
}>(initial: {
    count: number;
}): {
    count: number;
} (+1 overload)
namespace $state

Declares reactive state.




Example:



let count = $state(0);

{@link https://svelte.dev/docs/svelte/$state Documentation}


initial 

The initial value


({
	count(property) count: number: 0
});

export function incrementfunction increment(): void() {
	counterconst counter: {
    count: number;
}.count(property) count: number += 1;
}
```

...or don’t directly export it:

```
let countlet count: number = $statefunction $state<0>(initial: 0): 0 (+1 overload)
namespace $state

Declares reactive state.




Example:



let count = $state(0);

{@link https://svelte.dev/docs/svelte/$state Documentation}


initial 

The initial value


(0);

export function getCountfunction getCount(): number() {
	return countlet count: number;
}

export function incrementfunction increment(): void() {
	countlet count: number += 1;
}
```

[Edit this page on GitHub](https://github.com/sveltejs/svelte/edit/main/documentation/docs/02-runes/02-$state.md) [llms.txt](/docs/svelte/$state/llms.txt)

previous next

[What are runes?](/docs/svelte/what-are-runes) [$derived](/docs/svelte/$derived)