Svelte Documentation

repository·main·Indexed Apr 15, 2026

https://github.com/sveltejs/svelte

Official documentation for Svelte, a compiler-based framework that transforms declarative components into efficient JavaScript without a virtual DOM. Covers core concepts including Runes ($state, $derived, $effect), dependency tracking, push-pull reactivity, and template syntax features like snippets. Includes guides for setup with Vite, editor tooling, and TypeScript integration.

Tokens
40.5K
Snippets
125
Records
195
Agent score
100%

What's inside svelte

  1. What is Svelte?

    main
    Svelte is a compiler-based framework for building web applications. Unlike traditional frameworks that perform reconciliation in the browser, Svelte converts declarative components into highly efficient JavaScript at build time. This resulting code performs surgical updates to the DOM, minimizing runtime overhead.
  2. Create a new SvelteKit application

    main

    The recommended way to start a new project is using SvelteKit, the official application framework powered by Vite. Run the following commands to scaffold, install dependencies, and start the development server:

    npx sv create myapp
    cd myapp
    npm install
    npm run dev

    You can start using SvelteKit even if you are not familiar with Svelte yet. You can ignore advanced SvelteKit features initially and explore them later.

    Sources: documentation/docs/01-introduction/02-getting-started.md

  3. Minimize use of `$effect`

    main

    $effect is an escape hatch and should be avoided for standard state synchronization.

    • Avoid updating state inside an effect.
    • For external libraries (e.g., D3): Use {@attach ...}.
    • For user interaction: Use event handlers or function bindings.
    • For debugging: Use $inspect.
    • For observing external systems: Use createSubscriber.
    • Note: Effects do not run on the server; do not wrap them in if (browser) checks.
  4. Reactivity of `$derived` values and destructuring

    main

    Object/Array Reactivity

    Unlike $state, which creates deeply reactive proxies, $derived values are returned as-is. However, if the derived value is an object or array, mutating its properties (or using bind:) will affect the underlying source state if that source is deeply reactive.

    Reactive Destructuring

    When you destructure a $derived declaration, the resulting individual variables remain reactive.

    // This:
    let { a, b, c } = $derived(stuff());
    
    // Is equivalent to:
    let _stuff = $derived(stuff());
    let a = $derived(_stuff.a);
    let b = $derived(_stuff.b);
    let c = $derived(_stuff.c);
  5. When to use stores vs runes

    main

    With the introduction of Svelte 5 runes, the need for stores has diminished for many common use cases:

    • Extracting logic: Use runes in .svelte.js or .svelte.ts files to leverage universal reactivity outside of components.
    • Shared state: Create a $state object in a JavaScript/TypeScript file and export it.

    When to still use stores:

    • When handling complex asynchronous data streams.
    • When you require manual control over updating values or listening to changes.
    • When integrating with libraries like RxJS.
    /// file: state.svelte.js
    export const userState = $state({
    	name: 'name',
    	/* ... */
    });
    <!--- 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>
  6. Use `$state` for reactive variables

    main

    Use the $state rune only for variables that need to be reactive (i.e., they trigger updates in $effect, $derived, or templates). For large objects or arrays that are reassigned rather than mutated (like API responses), use $state.raw to avoid the performance overhead of deep reactivity proxies.

    // Deeply reactive (mutations trigger updates)
    let user = $state({ name: 'John' });
    user.name = 'Jane';
    
    // Shallowly reactive (only reassignment triggers updates)
    let apiData = $state.raw({ items: [] });
    apiData = { items: [1, 2, 3] };
  7. Store reactive state in context

    main

    You can pass reactive $state objects through context to allow multiple components to share and react to the same state.

    Important: When using context with state, avoid reassigning the context variable itself (e.g., counter = { count: 0 }), as this 'breaks the link' to the original reactive object. Instead, mutate the properties of the existing state object (e.g., counter.count = 0). Svelte will issue a warning if you attempt to reassign the object instead of mutating it.

    import { createContext } from 'svelte';
    
    interface Counter {
    	count: number;
    }
    
    export const [getCounter, setCounter] = createContext<Counter>();
    <!--- 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.svelte --->
    <script>
    	import { getCounter } from './context.ts';
    	const counter = getCounter();
    </script>
    
    <p>{counter.count}</p>
  8. Making classes reactive in Svelte 5

    main

    In Svelte 5, reactivity is determined at runtime. Simply instantiating a class does not make its properties reactive. To make a class reactive, you must define its properties using the $state rune inside the class definition.

    Incorrect (Svelte 4 style):

    <script>
      let foo = new Foo();
    </script>
    <button on:click={() => (foo.value = 1)}>{foo.value}</button>

    Correct (Svelte 5 style):

    class Foo {
      value = $state(0);
    }

    Note: Wrapping a class instance in $state(new Foo()) does not make the class properties reactive; only vanilla objects and arrays are made deeply reactive by $state.

  9. How Svelte 5 lifecycle works compared to Svelte 4

    main

    In Svelte 5, the component lifecycle is simplified to just two parts: creation and destruction.

    In Svelte 4, hooks like beforeUpdate and afterUpdate ran whenever a component updated. In Svelte 5, the smallest unit of change is the render effect set up during initialization. Consequently, there are no component-wide update hooks. Instead, you use runes to react to specific state changes:

    • Instead of beforeUpdate: Use $effect.pre to run code before the DOM is updated. To ensure it only runs when specific state changes, explicitly reference that state inside the effect.
    • Instead of afterUpdate: Use $effect to run code after the DOM has been updated.

    This approach provides more granular control and prevents unnecessary code execution when unrelated state (like a theme toggle) changes.