or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

examples

edge-cases.mdreal-world-scenarios.md
index.md
tile.json

lifecycle-components.mddocs/reference/

Svelte Lifecycle and Component Management

Comprehensive API reference for Svelte 5 lifecycle functions, component management, context API, and reactivity control from the main svelte module.

Component Management

mount() { .api }

Mounts a component to the DOM at a specified target and returns the component's exports.

Signature:

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

Parameters:

  • component - The Svelte component to mount (either legacy class component or Svelte 5 function component)
  • options - Mounting options (see MountOptions type below)

Returns:

  • The component's exports and potentially props (if compiled with accessors: true)

Description:

Mounts a component to the given target element. Transitions will play during the initial render unless the intro option is set to false.

Example:

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

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

// Access exported values
console.log(app.someExportedMethod());

Example with anchor:

import { mount } from 'svelte';
import Modal from './Modal.svelte';

// Mount before a specific element
const modal = mount(Modal, {
  target: document.body,
  anchor: document.getElementById('modal-anchor'),
  props: {
    title: 'Welcome'
  }
});

Example with context:

import { mount } from 'svelte';
import Child from './Child.svelte';

const context = new Map();
context.set('theme', 'dark');

const child = mount(Child, {
  target: document.getElementById('app'),
  context: context,
  props: {}
});

hydrate() { .api }

Hydrates a server-rendered component on the given target, attaching event listeners and making it interactive.

Signature:

function hydrate<Props extends Record<string, any>, Exports extends Record<string, any>>(
  component: ComponentType<SvelteComponent<Props>> | Component<Props, Exports, any>,
  options: {
    target: Document | Element | ShadowRoot;
    props?: Props;
    events?: Record<string, (e: any) => any>;
    context?: Map<any, any>;
    intro?: boolean;
    recover?: boolean;
  }
): Exports

Parameters:

  • component - The Svelte component to hydrate
  • options - Hydration options
    • target - The DOM element containing the server-rendered HTML
    • props - Component properties (required if component expects props)
    • events - Event handlers (deprecated, use callback props instead)
    • context - Context map accessible via getContext()
    • intro - Whether to play intro transitions (default: true)
    • recover - Attempt to recover from hydration mismatches

Returns:

  • The component's exports and potentially props

Description:

Hydrates a component that was previously rendered on the server. This attaches event listeners and makes the component interactive without re-rendering the entire DOM.

Example:

import { hydrate } from 'svelte';
import App from './App.svelte';

// Hydrate server-rendered HTML
const app = hydrate(App, {
  target: document.getElementById('app'),
  props: {
    initialData: window.__INITIAL_DATA__
  }
});

Example with error recovery:

import { hydrate } from 'svelte';
import App from './App.svelte';

const app = hydrate(App, {
  target: document.getElementById('app'),
  props: { data: serverData },
  recover: true // Attempt to recover from hydration mismatches
});

unmount() { .api }

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

Signature:

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

Parameters:

  • component - The mounted component instance to unmount
  • options - Unmount options
    • outro - Whether to play outro transitions before unmounting (default: false)

Returns:

  • A Promise that resolves after transitions complete (if outro is true), or immediately otherwise

Description:

Removes a mounted component from the DOM and cleans up all associated resources. Since Svelte 5.13.0, supports playing outro transitions before removal if outro option is set to true.

Example:

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

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

// Later, unmount without transitions
unmount(app);

Example with transitions:

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

const modal = mount(Modal, {
  target: document.body,
  props: { isOpen: true }
});

// Unmount with outro transitions
await unmount(modal, { outro: true });
console.log('Modal removed after transition');

createRawSnippet() { .api }

Creates a snippet programmatically for dynamic content rendering.

Signature:

function createRawSnippet<Params extends unknown[]>(
  fn: (...params: Getters<Params>) => {
    render: () => string;
    setup?: (element: Element) => void | (() => void);
  }
): Snippet<Params>

Parameters:

  • fn - Function that receives getter functions for parameters and returns:
    • render - Function that returns the HTML string to render
    • setup - Optional function for element setup, can return cleanup function

Returns:

  • A Snippet that can be used with {@render} tags

Description:

Creates a snippet programmatically, allowing you to generate reusable content blocks dynamically. This is useful when you need to create snippets at runtime or want to wrap existing HTML in a snippet interface.

Example:

<script>
  import { createRawSnippet } from 'svelte';

  const dynamicSnippet = createRawSnippet((getCount) => {
    return {
      render: () => `<div>Count: ${getCount()}</div>`,
      setup: (element) => {
        console.log('Snippet mounted', element);
        return () => {
          console.log('Snippet unmounted');
        };
      }
    };
  });

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

<button onclick={() => count++}>Increment</button>
{@render dynamicSnippet(count)}

Example with complex HTML:

<script>
  import { createRawSnippet } from 'svelte';

  const listSnippet = createRawSnippet((getItems) => {
    return {
      render: () => {
        const items = getItems();
        return `
          <ul>
            ${items.map(item => `<li>${item}</li>`).join('')}
          </ul>
        `;
      }
    };
  });

  let items = $state(['Apple', 'Banana', 'Cherry']);
</script>

{@render listSnippet(items)}

Lifecycle Functions

onMount() { .api }

Schedules a function to run as soon as the component has been mounted to the DOM.

Signature:

function onMount<T>(
  fn: () => NotFunction<T> | Promise<NotFunction<T>> | (() => any)
): void

Parameters:

  • fn - Callback function to run on mount. Can return:
    • A cleanup function that runs on unmount
    • A Promise (but cleanup functions from promises are ignored)
    • Any other non-function value (ignored)

Returns:

  • void

Description:

Like $effect, onMount 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 component initialization (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.

Example:

<script>
  import { onMount } from 'svelte';

  let canvas;

  onMount(() => {
    const ctx = canvas.getContext('2d');
    ctx.fillStyle = 'red';
    ctx.fillRect(0, 0, 100, 100);
  });
</script>

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

Example with cleanup:

<script>
  import { onMount } from 'svelte';

  onMount(() => {
    const interval = setInterval(() => {
      console.log('tick');
    }, 1000);

    // Cleanup function
    return () => {
      clearInterval(interval);
    };
  });
</script>

Example with async operation:

<script>
  import { onMount } from 'svelte';

  let data = $state(null);

  onMount(async () => {
    const response = await fetch('/api/data');
    data = await response.json();
  });
</script>

{#if data}
  <pre>{JSON.stringify(data, null, 2)}</pre>
{:else}
  <p>Loading...</p>
{/if}

onDestroy() { .api }

Schedules a callback to run immediately before the component is unmounted.

Signature:

function onDestroy(fn: () => any): void

Parameters:

  • fn - Callback function to run before component unmounts

Returns:

  • void

Description:

Out of onMount, beforeUpdate, afterUpdate and onDestroy, this is the only one that runs inside a server-side component. Use this to clean up resources, cancel subscriptions, or perform any necessary cleanup.

Example:

<script>
  import { onMount, onDestroy } from 'svelte';

  let subscription;

  onMount(() => {
    subscription = dataStore.subscribe(value => {
      console.log('Data updated', value);
    });
  });

  onDestroy(() => {
    if (subscription) {
      subscription.unsubscribe();
    }
  });
</script>

Example with event listeners:

<script>
  import { onMount, onDestroy } from 'svelte';

  function handleResize() {
    console.log('Window resized', window.innerWidth);
  }

  onMount(() => {
    window.addEventListener('resize', handleResize);
  });

  onDestroy(() => {
    window.removeEventListener('resize', handleResize);
  });
</script>

Example with WebSocket:

<script>
  import { onMount, onDestroy } from 'svelte';

  let ws;

  onMount(() => {
    ws = new WebSocket('ws://localhost:8080');
    ws.onmessage = (event) => {
      console.log('Message:', event.data);
    };
  });

  onDestroy(() => {
    if (ws) {
      ws.close();
    }
  });
</script>

beforeUpdate() (deprecated) { .api }

Schedules a callback to run immediately before the component is updated after any state change.

Signature:

function beforeUpdate(fn: () => void): void

Parameters:

  • fn - Callback function to run before each update

Returns:

  • void

Description:

The first time the callback runs will be before the initial onMount. In runes mode, use $effect.pre instead.

Deprecated: Use $effect.pre instead.

Example (legacy):

<script>
  import { beforeUpdate } from 'svelte';

  let count = 0;

  beforeUpdate(() => {
    console.log('Component about to update', count);
  });
</script>

<button on:click={() => count++}>
  Clicked {count} times
</button>

Migration to Svelte 5:

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

  $effect.pre(() => {
    console.log('Component about to update', count);
  });
</script>

<button onclick={() => count++}>
  Clicked {count} times
</button>

afterUpdate() (deprecated) { .api }

Schedules a callback to run immediately after the component has been updated.

Signature:

function afterUpdate(fn: () => void): void

Parameters:

  • fn - Callback function to run after each update

Returns:

  • void

Description:

The first time the callback runs will be after the initial onMount. In runes mode, use $effect instead.

Deprecated: Use $effect instead.

Example (legacy):

<script>
  import { afterUpdate } from 'svelte';

  let element;

  afterUpdate(() => {
    console.log('Component updated, element height:', element.offsetHeight);
  });
</script>

<div bind:this={element}>
  Content
</div>

Migration to Svelte 5:

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

  $effect(() => {
    // Runs after each update
    if (element) {
      console.log('Element height:', element.offsetHeight);
    }
  });
</script>

<button onclick={() => count++}>Update {count}</button>
<div bind:this={element}>Content</div>

Context API

createContext() { .api }

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

Signature:

function createContext<T>(): [() => T, (context: T) => T]

Returns:

  • A tuple containing:
    • get - Function to retrieve the context (throws if no parent called set)
    • set - Function to set the context value

Description:

Creates a type-safe context key/getter pair. The get function will throw an error if no parent component called set. This is the recommended way to work with context in Svelte 5 as it provides better type safety than getContext/setContext.

Since: 5.40.0

Example:

<!-- ParentComponent.svelte -->
<script>
  import { createContext } from 'svelte';
  import Child from './Child.svelte';

  // Create context in a shared module would be better
  export const [getTheme, setTheme] = createContext();

  setTheme({ primary: '#ff3e00', secondary: '#676778' });
</script>

<Child />
<!-- Child.svelte -->
<script>
  import { getTheme } from './ParentComponent.svelte';

  const theme = getTheme();
</script>

<button style="background: {theme.primary}">
  Themed Button
</button>

Example with TypeScript:

// context.ts
import { createContext } from 'svelte';

interface User {
  id: string;
  name: string;
  email: string;
}

export const [getUser, setUser] = createContext<User>();
<!-- App.svelte -->
<script lang="ts">
  import { setUser } from './context';
  import Profile from './Profile.svelte';

  setUser({
    id: '1',
    name: 'Alice',
    email: 'alice@example.com'
  });
</script>

<Profile />
<!-- Profile.svelte -->
<script lang="ts">
  import { getUser } from './context';

  const user = getUser();
</script>

<h1>{user.name}</h1>
<p>{user.email}</p>

getContext() { .api }

Retrieves the context that belongs to the closest parent component with the specified key.

Signature:

function getContext<T>(key: any): T

Parameters:

  • key - The context key (can be any value, typically a string or Symbol)

Returns:

  • The context value

Description:

Must be called during component initialization. createContext is a type-safe alternative recommended for new code.

Example:

<!-- Parent.svelte -->
<script>
  import { setContext } from 'svelte';
  import Child from './Child.svelte';

  setContext('theme', {
    mode: 'dark',
    primaryColor: '#ff3e00'
  });
</script>

<Child />
<!-- Child.svelte -->
<script>
  import { getContext } from 'svelte';

  const theme = getContext('theme');
</script>

<div class={theme.mode}>
  <span style="color: {theme.primaryColor}">Styled content</span>
</div>

Example with Symbol keys:

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

  // Symbol keys provide better encapsulation
  const API_KEY = Symbol('api');
  const api = getContext(API_KEY);

  async function loadData() {
    const data = await api.fetch('/data');
    return data;
  }
</script>

setContext() { .api }

Associates an arbitrary context object with the current component and the specified key.

Signature:

function setContext<T>(key: any, context: T): T

Parameters:

  • key - The context key (can be any value, typically a string or Symbol)
  • context - The context value to store

Returns:

  • The context value that was set

Description:

The context is then available to children of the component (including slotted content) with getContext. Like lifecycle functions, this must be called during component initialization. createContext is a type-safe alternative recommended for new code.

Example:

<script>
  import { setContext } from 'svelte';
  import Children from './Children.svelte';

  // Set multiple contexts
  setContext('user', {
    name: 'Alice',
    role: 'admin'
  });

  setContext('api', {
    baseURL: 'https://api.example.com',
    fetch: (path) => fetch(`https://api.example.com${path}`)
  });
</script>

<Children />

Example with reactive context:

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

  let settings = $state({
    theme: 'dark',
    language: 'en'
  });

  // Context can be reactive
  setContext('settings', settings);
</script>

<button onclick={() => settings.theme = 'light'}>
  Switch to Light Theme
</button>

<slot />

hasContext() { .api }

Checks whether a given key has been set in the context of a parent component.

Signature:

function hasContext(key: any): boolean

Parameters:

  • key - The context key to check

Returns:

  • true if the context exists, false otherwise

Description:

Must be called during component initialization. Useful for optional context dependencies or providing fallback behavior.

Example:

<script>
  import { hasContext, getContext } from 'svelte';

  let theme;

  if (hasContext('theme')) {
    theme = getContext('theme');
  } else {
    // Fallback theme
    theme = { mode: 'light', primaryColor: '#000000' };
  }
</script>

<div class={theme.mode}>
  Content with {theme.mode} theme
</div>

Example with optional features:

<script>
  import { hasContext, getContext } from 'svelte';

  const hasAnalytics = hasContext('analytics');
  const analytics = hasAnalytics ? getContext('analytics') : null;

  function trackEvent(eventName) {
    if (analytics) {
      analytics.track(eventName);
    }
  }
</script>

<button onclick={() => trackEvent('button_clicked')}>
  Click Me
</button>

getAllContexts() { .api }

Retrieves the whole context map that belongs to the closest parent component.

Signature:

function getAllContexts<T extends Map<any, any> = Map<any, any>>(): T

Returns:

  • A Map containing all contexts from parent components

Description:

Must be called during component initialization. Useful, for example, if you programmatically create a component and want to pass the existing context to it.

Example:

<script>
  import { getAllContexts, mount } from 'svelte';
  import DynamicComponent from './DynamicComponent.svelte';

  // Get all parent contexts
  const contexts = getAllContexts();

  function createDynamicComponent(target) {
    // Pass all parent contexts to dynamically mounted component
    const instance = mount(DynamicComponent, {
      target,
      context: contexts,
      props: {}
    });

    return instance;
  }
</script>

Example with context forwarding:

<script>
  import { getAllContexts, setContext } from 'svelte';

  // Get all contexts from parents
  const parentContexts = getAllContexts();

  // Add a new context while preserving parent contexts
  setContext('currentLevel', 3);

  // You can also iterate over all contexts
  for (const [key, value] of parentContexts) {
    console.log('Context key:', key, 'value:', value);
  }
</script>

Reactivity Control

tick() { .api }

Returns a promise that resolves once any pending state changes have been applied to the DOM.

Signature:

function tick(): Promise<void>

Returns:

  • A Promise that resolves after pending state changes are applied

Description:

Waits for the next DOM update cycle to complete. This is useful when you need to read from the DOM immediately after updating state, ensuring the DOM reflects the latest changes.

Example:

<script>
  import { tick } from 'svelte';

  let text = $state('');
  let textarea;

  async function addText(newText) {
    text += newText;

    // Wait for DOM to update
    await tick();

    // Now textarea.value reflects the updated text
    console.log('Updated text length:', textarea.value.length);
    textarea.scrollTop = textarea.scrollHeight;
  }
</script>

<textarea bind:this={textarea} bind:value={text}></textarea>
<button onclick={() => addText('\nNew line')}>Add Line</button>

Example with focus management:

<script>
  import { tick } from 'svelte';

  let items = $state([]);

  async function addItem() {
    items.push({ id: Date.now(), value: '' });

    // Wait for new input to be in DOM
    await tick();

    // Focus the newly added input
    const inputs = document.querySelectorAll('input');
    inputs[inputs.length - 1].focus();
  }
</script>

{#each items as item (item.id)}
  <input bind:value={item.value} />
{/each}

<button onclick={addItem}>Add Item</button>

settled() { .api }

Returns a promise that resolves once any state changes, and asynchronous work resulting from them, have resolved and the DOM has been updated.

Signature:

function settled(): Promise<void>

Returns:

  • A Promise that resolves after all async work completes

Description:

Unlike tick(), which only waits for the next DOM update, settled() waits for all asynchronous work (including nested effects and derived values) to complete. This is useful for testing or when you need to ensure everything is completely resolved.

Since: 5.36

Example:

<script>
  import { settled } from 'svelte';

  let loading = $state(false);
  let data = $state(null);

  async function loadData() {
    loading = true;

    // Trigger async data load
    const response = await fetch('/api/data');
    data = await response.json();

    loading = false;

    // Wait for all derived values and effects to settle
    await settled();

    console.log('All updates complete, DOM fully updated');
  }
</script>

Example in testing:

import { settled, mount } from 'svelte';
import { expect, test } from 'vitest';
import Component from './Component.svelte';

test('component updates after async operation', async () => {
  const target = document.createElement('div');
  const component = mount(Component, { target, props: { id: 1 } });

  // Trigger async update
  component.loadData();

  // Wait for everything to settle
  await settled();

  // Now safe to make assertions
  expect(target.textContent).toContain('Loaded data');
});

flushSync() { .api }

Synchronously flushes any pending state changes to the DOM.

Signature:

function flushSync<T = void>(fn?: (() => T) | undefined): T

Parameters:

  • fn - Optional function to run before flushing

Returns:

  • If a callback is provided, returns the result of calling the callback; otherwise returns void

Description:

Forces Svelte to immediately apply all pending state changes to the DOM synchronously, rather than batching them for the next microtask. Use sparingly as this can impact performance. Returns the result of the callback function if one is provided.

Example:

<script>
  import { flushSync } from 'svelte';

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

  function updateAndMeasure() {
    flushSync(() => {
      count++;
    });

    // DOM is guaranteed to be updated here
    console.log('Element width:', element.offsetWidth);
  }
</script>

<div bind:this={element}>
  Count: {count}
</div>

<button onclick={updateAndMeasure}>Update</button>

Example with DOM measurements:

<script>
  import { flushSync } from 'svelte';

  let items = $state([1, 2, 3]);
  let container;

  function addItemAndScroll() {
    // Update state and flush immediately
    flushSync(() => {
      items.push(items.length + 1);
    });

    // DOM is updated, can scroll immediately
    container.scrollTop = container.scrollHeight;
  }
</script>

<div bind:this={container} style="height: 200px; overflow: auto;">
  {#each items as item}
    <div>{item}</div>
  {/each}
</div>

<button onclick={addItemAndScroll}>Add and Scroll</button>

Example returning value:

import { flushSync } from 'svelte';

let count = $state(0);

const result = flushSync(() => {
  count++;
  return count * 2;
});

console.log(result); // 2

Legacy Functions

createEventDispatcher() (deprecated) { .api }

Creates an event dispatcher that can be used to dispatch component events.

Signature:

function createEventDispatcher<EventMap extends Record<string, any> = any>(): EventDispatcher<EventMap>

Returns:

  • An EventDispatcher function

Description:

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.

Deprecated: Use callback props and/or the $host() rune instead — see migration guide

Example (legacy):

<script>
  import { createEventDispatcher } from 'svelte';

  const dispatch = createEventDispatcher();

  function handleClick() {
    dispatch('message', {
      text: 'Hello from child'
    });
  }
</script>

<button on:click={handleClick}>Send Message</button>

Example with TypeScript:

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

  const dispatch = createEventDispatcher<{
    loaded: null;
    change: string;
    select: { id: number; name: string };
  }>();

  function handleLoad() {
    dispatch('loaded');
  }

  function handleChange(value: string) {
    dispatch('change', value);
  }

  function handleSelect(item: { id: number; name: string }) {
    dispatch('select', item);
  }
</script>

Migration to Svelte 5:

<script>
  // Instead of createEventDispatcher, use callback props
  let { onmessage } = $props();

  function handleClick() {
    onmessage?.({
      text: 'Hello from child'
    });
  }
</script>

<button onclick={handleClick}>Send Message</button>
<!-- Parent component -->
<script>
  import Child from './Child.svelte';

  function handleMessage(event) {
    console.log('Message:', event.text);
  }
</script>

<Child onmessage={handleMessage} />

hydratable() { .api }

Marks a code block as hydratable for server-side rendering.

Signature:

function hydratable<T>(key: string, fn: () => T): T

Parameters:

  • key - Unique identifier for this hydratable block
  • fn - Function to execute

Returns:

  • The return value of fn

Description:

Used internally for SSR hydration. This function ensures that code blocks can be properly matched between server-rendered HTML and client-side hydration. Generally not needed in application code.

Example:

<script>
  import { hydratable } from 'svelte';

  const data = hydratable('user-data', () => {
    return fetchUserData();
  });
</script>

TypeScript Types

Component<Props, Exports, Bindings> { .api }

Represents a Svelte 5 component with props, exports, and bindings.

Signature:

interface Component<
  Props extends Record<string, any> = {},
  Exports extends Record<string, any> = {},
  Bindings extends keyof Props | '' = string
> {
  (
    this: void,
    internals: ComponentInternals,
    props: Props
  ): {
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Props>): void;
  } & Exports;

  element?: typeof HTMLElement;
  z_$$bindings?: Bindings;
}

Description:

Can be used to create strongly typed Svelte components. This is the primary component type for Svelte 5.

Example:

// component-library/index.d.ts
import type { Component } from 'svelte';

export declare const MyComponent: Component<
  { foo: string; bar?: number },  // Props
  { reset: () => void },           // Exports
  'foo'                            // Bindable props
>;
<!-- Usage -->
<script lang="ts">
  import { MyComponent } from 'component-library';

  let instance;
  let fooValue = $state('');
</script>

<MyComponent
  foo={fooValue}
  bind:foo={fooValue}
  bind:this={instance}
/>

<button onclick={() => instance.reset()}>
  Reset
</button>

ComponentProps { .api }

Convenience type to get the props the given component expects.

Signature:

type ComponentProps<Comp extends SvelteComponent | Component<any, any>> =
  Comp extends SvelteComponent<infer Props>
    ? Props
    : Comp extends Component<infer Props, any>
      ? Props
      : never;

Description:

Extracts the props type from a component. Useful for creating wrapper components or generic functions that work with components.

Example:

import type { ComponentProps } from 'svelte';
import MyComponent from './MyComponent.svelte';

// Ensure variable has correct props type
const props: ComponentProps<typeof MyComponent> = {
  foo: 'bar',
  count: 42
};

Example with generic function:

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

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

// TypeScript will error if props don't match
withProps(MyComponent, { foo: 'bar' });

Example creating wrapper:

<script lang="ts" generics="T extends Component<any>">
  import type { Component, ComponentProps } from 'svelte';

  let {
    component,
    ...props
  }: {
    component: T
  } & ComponentProps<T> = $props();
</script>

<div class="wrapper">
  <component {...props} />
</div>

Snippet { .api }

Represents a #snippet block that can be passed to components.

Signature:

interface Snippet<Parameters extends unknown[] = []> {
  (
    this: void,
    ...args: number extends Parameters['length'] ? never : Parameters
  ): {
    '{@render ...} must be called with a Snippet': "import type { Snippet } from 'svelte'";
  } & typeof SnippetReturn;
}

Description:

Use it to express that your component expects a snippet of a certain type. You can only call a snippet through the {@render ...} tag.

See the snippet documentation for more info.

Example:

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

  let {
    header,
    content
  }: {
    header: Snippet;
    content: Snippet<[{ count: number }]>;
  } = $props();

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

<div class="card">
  <div class="header">
    {@render header()}
  </div>

  <div class="content">
    {@render content({ count })}
  </div>

  <button onclick={() => count++}>Increment</button>
</div>

Example with optional snippet:

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

  let {
    footer
  }: {
    footer?: Snippet<[string]>
  } = $props();
</script>

<div>
  <p>Main content</p>

  {#if footer}
    {@render footer('Footer data')}
  {:else}
    <p>Default footer</p>
  {/if}
</div>

MountOptions { .api }

Defines the options accepted by the mount() function.

Signature:

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;
} & ({} extends Props
  ? {
      /** Component properties */
      props?: Props;
    }
  : {
      /** Component properties */
      props: Props;
    });

Description:

Configuration options for mounting a component. The props field is required if the component expects props, otherwise it's optional.

Example:

import { mount } from 'svelte';
import type { MountOptions } from 'svelte';
import App from './App.svelte';

const options: MountOptions<{ name: string; count: number }> = {
  target: document.body,
  props: {
    name: 'Alice',
    count: 0
  },
  intro: false, // Skip intro transitions
  context: new Map([
    ['theme', 'dark']
  ])
};

const app = mount(App, options);

ComponentInternals { .api }

Internal implementation details that vary between environments.

Signature:

type ComponentInternals = Branded<{}, 'ComponentInternals'>;

Description:

An internal object used by Svelte. Do not use or modify. This type is primarily for internal Svelte implementation and TypeScript type safety.

EventDispatcher { .api }

Event dispatcher type for legacy components.

Signature:

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;
}

interface DispatchOptions {
  cancelable?: boolean;
}

Description:

Type for event dispatchers created with createEventDispatcher. Provides type-safe event dispatch with proper parameter inference.

Example:

import type { EventDispatcher } from 'svelte';
import { createEventDispatcher } from 'svelte';

// Define event map
interface Events {
  save: { id: number; data: string };
  cancel: void;
  notify: string | null;
}

const dispatch: EventDispatcher<Events> = createEventDispatcher();

// Type-safe dispatch calls
dispatch('save', { id: 1, data: 'test' });
dispatch('cancel');
dispatch('notify', 'message');
dispatch('notify', null);

// TypeScript errors for wrong types
// dispatch('save', 'wrong'); // Error
// dispatch('unknown', {}); // Error

SvelteComponent (deprecated) { .api }

Base class for Svelte 4 components.

Signature:

class SvelteComponent<
  Props extends Record<string, any> = Record<string, any>,
  Events extends Record<string, any> = any,
  Slots extends Record<string, any> = any
> {
  constructor(options: ComponentConstructorOptions<Properties<Props, Slots>>);

  $destroy(): void;
  $on<K extends Extract<keyof Events, string>>(
    type: K,
    callback: (e: Events[K]) => void
  ): () => void;
  $set(props: Partial<Props>): void;

  static element?: typeof HTMLElement;
}

Description:

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.

Deprecated: Components are no longer classes. Use mount to instantiate components and use the Component type for typing. See migration guide for more info.

Example (legacy):

import App from './App.svelte';

const app = new App({
  target: document.body,
  props: {
    name: 'world'
  }
});

// Legacy methods
app.$on('event', (e) => console.log(e));
app.$set({ name: 'universe' });
app.$destroy();

Migration to Svelte 5:

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

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

// Use callback props instead of $on
// Update props by passing new mount options or using exports
// Destroy with unmount
await unmount(app, { outro: true });

Additional Types

Fork { .api }

Represents work happening off-screen, such as data being preloaded in anticipation of user navigation.

Signature:

interface Fork {
  /** Commit the fork. The promise will resolve once the state change has been applied */
  commit(): Promise<void>;

  /** Discard the fork */
  discard(): void;
}

Description:

Return value from the fork() function. Allows you to commit or discard speculative state changes.

Since: 5.42

Example:

import { fork } from 'svelte';

let data = $state(null);

// Create a fork for preloading
const dataFork = fork(() => {
  data = fetchPreloadedData();
});

// Later, if user navigates to the page
await dataFork.commit();

// Or if they navigate elsewhere
dataFork.discard();

Related Functions

While not part of the main lifecycle API, these functions are commonly used alongside lifecycle management:

getAbortSignal() { .api }

Returns an AbortSignal that aborts when the current derived or effect re-runs or is destroyed.

Signature:

function getAbortSignal(): AbortSignal

Returns:

  • An AbortSignal that aborts on cleanup

Description:

Must be called while a derived or effect is running. Useful for aborting fetch requests or other async operations when they become stale.

Example:

<script>
  import { getAbortSignal } from 'svelte';

  let { id } = $props();

  async function getData(id) {
    const response = await fetch(`/items/${id}`, {
      signal: getAbortSignal()
    });

    return await response.json();
  }

  // Automatically aborts previous request if id changes
  const data = $derived(await getData(id));
</script>

{#if data}
  <pre>{JSON.stringify(data, null, 2)}</pre>
{/if}

Example with cleanup:

<script>
  import { getAbortSignal } from 'svelte';

  let query = $state('');

  $effect(() => {
    const signal = getAbortSignal();

    const timeout = setTimeout(async () => {
      if (query.length > 0) {
        const results = await fetch(`/search?q=${query}`, { signal });
        console.log('Search results:', await results.json());
      }
    }, 300);

    signal.addEventListener('abort', () => {
      clearTimeout(timeout);
    });
  });
</script>

untrack() { .api }

When used inside a $derived or $effect, any state read inside fn will not be treated as a dependency.

Signature:

function untrack<T>(fn: () => T): T

Parameters:

  • fn - Function whose state reads should not create dependencies

Returns:

  • The return value of fn

Description:

Useful when you need to read reactive state inside an effect or derived value without creating a dependency on it.

Example:

<script>
  import { untrack } from 'svelte';

  let data = $state({});
  let time = $state(Date.now());

  $effect(() => {
    // This runs when `data` changes, but not when `time` changes
    save(data, {
      timestamp: untrack(() => time)
    });
  });
</script>

Example preventing infinite loops:

<script>
  import { untrack } from 'svelte';

  let count = $state(0);
  let debugLog = $state([]);

  $effect(() => {
    // Read count without creating dependency
    const currentCount = untrack(() => count);

    // This won't trigger the effect again
    debugLog.push(`Count changed to ${currentCount} at ${Date.now()}`);
  });
</script>

fork() { .api }

Creates a 'fork', in which state changes are evaluated but not applied to the DOM.

Signature:

function fork(fn: () => void): Fork

Parameters:

  • fn - A synchronous function that modifies some state

Returns:

  • A Fork object with commit() and discard() methods

Description:

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 initialized, 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.

Since: 5.42

Example:

<script>
  import { fork } from 'svelte';

  let data = $state(null);
  let activeFork = null;

  function handleMouseEnter(id) {
    // Speculatively load data
    activeFork = fork(() => {
      data = loadData(id);
    });
  }

  async function handleClick(id) {
    if (activeFork) {
      // Commit the fork if user actually clicks
      await activeFork.commit();
      activeFork = null;
    } else {
      data = loadData(id);
    }
  }

  function handleMouseLeave() {
    if (activeFork) {
      // User didn't click, discard the fork
      activeFork.discard();
      activeFork = null;
    }
  }
</script>

<a
  href="/items/{id}"
  onmouseenter={() => handleMouseEnter(id)}
  onmouseleave={handleMouseLeave}
  onclick={handleClick}
>
  View Item
</a>

Summary

This document covers all lifecycle and component management APIs from the main svelte module in Svelte 5:

Component Management

  • mount() - Mount components to the DOM
  • hydrate() - Hydrate server-rendered components
  • unmount() - Remove mounted components
  • createRawSnippet() - Create snippets programmatically

Lifecycle Functions

  • onMount() - Run code when component mounts
  • onDestroy() - Run cleanup when component unmounts
  • beforeUpdate() (deprecated) - Run before each update
  • afterUpdate() (deprecated) - Run after each update

Context API

  • createContext() - Type-safe context creation
  • getContext() - Retrieve context values
  • setContext() - Set context values
  • hasContext() - Check context existence
  • getAllContexts() - Get all parent contexts

Reactivity Control

  • tick() - Wait for DOM updates
  • settled() - Wait for all async work to complete
  • flushSync() - Synchronously flush updates
  • untrack() - Read state without dependencies
  • fork() - Create speculative state changes
  • getAbortSignal() - Get abort signal for effects

Legacy

  • createEventDispatcher() (deprecated) - Dispatch component events
  • hydratable() - Mark code as hydratable

TypeScript Types

  • Component<Props, Exports, Bindings> - Component type
  • ComponentProps - Extract props type
  • Snippet<Parameters> - Snippet type
  • MountOptions - Mount configuration
  • ComponentInternals - Internal state
  • EventDispatcher - Event dispatcher type
  • Fork - Fork object type
  • SvelteComponent (deprecated) - Legacy component class

For more information, see the official Svelte documentation.