Skip to main content



As well as runes, Svelte 5 introduces a handful of new things you can import, alongside existing ones like getContext, setContext and tick.



Forces any pending effects (including DOM updates) to be applied immediately, rather than in the future. This is mainly useful in a testing context — you'll rarely need it in application code.

	import { flushSync } from 'svelte';

	let count = $state(0);
	let element;

	function onclick() {
		flushSync(() => (count += 1));

		// without `flushSync`, the DOM would be updated in the future
		console.log(element.textContent === String(count));

<span bind:this={element}>{count}</span>
<button {onclick}>update</button>


Instantiates a component and mounts it to the given target:

import { mount } from 'svelte';
import App from './App.svelte';
const app = mount(App, {
target: document.querySelector('#app'),
props: { some: 'property' }


Like mount, but will reuse up any HTML rendered by Svelte's SSR output (from the render function) inside the target and make it interactive:

import { hydrate } from 'svelte';
import App from './App.svelte';
const app = hydrate(App, {
target: document.querySelector('#app'),
props: { some: 'property' }


Unmounts a component created with mount or hydrate:

import { mount, unmount } from 'svelte';
import App from './App.svelte';
const app = mount(App, {...});
// later


To prevent something from being treated as an $effect/$derived dependency, use untrack:

	import { untrack } from 'svelte';

	let { a, b } = $props();

	$effect(() => {
		// this will run when `a` changes,
		// but not when `b` changes
		console.log(untrack(() => b));


Svelte provides reactive Map, Set, Date and URL classes. These can be imported from svelte/reactivity and used just like their native counterparts. Demo:

	import { URL } from 'svelte/reactivity';

	const url = new URL('');

<!-- 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} />


Where possible, event handlers added with attributes like onclick use a technique called event delegation. It works by creating a single handler for each event type on the root DOM element, rather than creating a handler for each element, resulting in better performance and memory usage.

Delegated event handlers run after other event handlers. In other words, a handler added programmatically with addEventListener will run before a handler added declaratively with onclick, regardless of their relative position in the DOM (demo). It also means that calling event.stopPropagation() inside a declarative handler won't prevent the programmatic handler (created inside an action, for example) from running.

To preserve the relative order, use on rather than addEventListener (demo):

import { on } from 'svelte/events';
const off = on(element, 'click', () => {
console.log('element was clicked');
// later, if we need to remove the event listener:

on also accepts an optional fourth argument which matches the options argument for addEventListener.



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 } from 'svelte/server';
import App from './App.svelte';
const result = render(App, {
props: { some: 'property' }


Svelte provides built-in DOM types. A common use case for DOM types is forwarding props to an HTML element. To properly type your props and get full intellisense, your props interface should extend the attributes type for your HTML element:

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

	interface Props extends HTMLAttributes<HTMLDivElement> {
		username: string;

	let { username, }: Props = $props();

<div {}>
	Hi, {username}!

You can use ComponentProps<ImportedComponent>, if you wish to forward props to a Svelte component.

Svelte provides a best-effort of all the HTML DOM types that exist. If an attribute is missing from our type definitions, you are welcome to open an issue and/or a PR fixing it. For experimental attributes, you can augment the existing types locally by creating a .d.ts file:

import { HTMLButtonAttributes } from 'svelte/elements';
declare module 'svelte/elements' {
export interface SvelteHTMLElements {
'custom-button': HTMLButtonAttributes;
// allows for more granular control over what element to add the typings to
export interface HTMLButtonAttributes {
veryexperimentalattribute?: string;
export {}; // ensure this is not an ambient module, else types will be overridden instead of augmented

The .d.ts file must be included in your tsconfig.json file. If you are using the standard "include": ["src/**/*"], this just means the file should be placed in the src directory.