# Svelte
## Introduction
Svelte is a modern frontend framework that takes a fundamentally different approach to building user interfaces. Unlike traditional frameworks that do the bulk of their work in the browser, Svelte is a compiler that converts declarative component code into highly efficient imperative JavaScript that surgically updates the DOM. This compilation step eliminates the need for a virtual DOM and runtime overhead, resulting in smaller bundle sizes and faster performance. Components are written in `.svelte` files using an intuitive syntax that combines HTML, CSS, and JavaScript, making it accessible to web developers while providing powerful reactive primitives. As of version 5.45, Svelte continues to evolve with new features for reactivity, performance optimization, and developer experience.
The Svelte ecosystem consists of multiple packages and tools that work together seamlessly. The core `svelte` package provides the component framework and compiler, while `svelte/store` offers state management utilities, `svelte/motion` handles animations, and `svelte/transition` provides built-in transition effects. Svelte 5 introduces runes—a new reactivity system using `$state`, `$derived`, and `$effect`—that offers fine-grained control over reactive behavior. The framework also includes `svelte/reactivity` with reactive data structures and window bindings, `svelte/events` for enhanced event handling, and `svelte/attachments` for modern DOM behavior patterns. A comprehensive compiler API enables parsing and transforming Svelte components, server-side rendering capabilities support universal applications, and integration with modern build tools ensures optimal development workflows. SvelteKit, the official application framework, builds on top of Svelte to provide routing, server-side rendering, and full-stack capabilities.
## APIs and Functions
### Component Mounting and Lifecycle
**mount** - Mount a component to a DOM element
```javascript
import { mount } from 'svelte';
import App from './App.svelte';
// Basic mounting
const app = mount(App, {
target: document.getElementById('app'),
props: {
name: 'World',
count: 42
}
});
// Advanced mounting with context and events
const instance = mount(App, {
target: document.body,
anchor: document.querySelector('#insertion-point'),
props: { user: { id: 1, name: 'Alice' } },
context: new Map([['theme', 'dark']]),
intro: true, // Play transitions on mount (default: true)
events: {
// Deprecated: prefer callback props instead
customEvent: (e) => console.log('Event:', e.detail)
}
});
// Access exported values from the component
console.log(instance.someExportedFunction());
```
**unmount** - Unmount a component instance
```javascript
import { mount, unmount } from 'svelte';
import Modal from './Modal.svelte';
const modal = mount(Modal, {
target: document.body,
props: { title: 'Confirm Action' }
});
// Unmount without playing outro transitions
await unmount(modal);
// Unmount with outro transitions (Svelte 5.13+)
await unmount(modal, { outro: true });
```
**hydrate** - Hydrate server-rendered HTML with a component
```javascript
import { hydrate } from 'svelte';
import App from './App.svelte';
// Hydrate server-rendered content
const app = hydrate(App, {
target: document.getElementById('app'),
props: { data: window.__INITIAL_DATA__ }
});
// With recover mode (attempts to fix mismatches)
const appWithRecovery = hydrate(App, {
target: document.getElementById('app'),
props: { data: window.__INITIAL_DATA__ },
recover: true // Default: true. Set false to strictly fail on mismatch
});
```
**onMount** - Run code when component mounts to DOM
```javascript
```
**onDestroy** - Run cleanup code when component unmounts
```javascript
```
**tick** - Wait for pending state changes to apply
```javascript
{count}
```
**settled** - Wait for all state changes and async work to complete
```javascript
```
**flushSync** - Synchronously apply pending state changes
```javascript
```
**setContext / getContext** - Share data between parent and child components
```javascript
Themed content
```
**hasContext** - Check if context exists
```javascript
```
**getAllContexts** - Retrieve all contexts from parent
```javascript
```
### Reactivity and State Management
**untrack** - Read state without creating dependencies
```javascript
```
**getAbortSignal** - Get signal that aborts when effect/derived re-runs
```javascript
```
**fork** - Create a fork for off-screen work (experimental)
```javascript
import { fork } from 'svelte';
// Create a fork for preloading data without affecting the DOM
async function preloadRoute(routeData) {
const forked = fork(() => {
// State changes here are evaluated but not applied to DOM
someState = routeData;
// Run effects and deriveds
});
// Later, when the user navigates, commit the fork
await forked.commit(); // Applies all state changes to DOM
// Or discard if navigation was cancelled
// forked.discard();
}
// Example: Preload data on hover
function handleHover(link) {
const forked = fork(() => {
// Fetch and process data in isolation
fetchPageData(link.href);
});
link.addEventListener('click', async () => {
// Commit the preloaded state
await forked.commit();
});
link.addEventListener('mouseleave', () => {
// Discard if user doesn't click
forked.discard();
}, { once: true });
}
```
**createSubscriber** - Integrate external event systems with reactivity
```javascript
```
### Store APIs
**writable** - Create a writable store
```javascript
import { writable } from 'svelte/store';
// Simple store
const count = writable(0);
// Subscribe to changes
const unsubscribe = count.subscribe(value => {
console.log('Count:', value);
});
// Update the value
count.set(5);
count.update(n => n + 1);
unsubscribe();
// Store with start/stop logic
const websocket = writable(null, (set, update) => {
const ws = new WebSocket('wss://example.com/socket');
ws.addEventListener('message', (event) => {
set(JSON.parse(event.data));
});
ws.addEventListener('open', () => {
console.log('WebSocket connected');
});
// Cleanup function
return () => {
ws.close();
console.log('WebSocket disconnected');
};
});
// In Svelte components, use $ prefix for auto-subscription
//
//
{$count}
```
**readable** - Create a read-only store
```javascript
import { readable } from 'svelte/store';
// Simple readable
const time = readable(new Date(), (set) => {
const interval = setInterval(() => {
set(new Date());
}, 1000);
return () => clearInterval(interval);
});
// Geolocation store
const location = readable(null, (set) => {
if (!navigator.geolocation) {
set({ error: 'Geolocation not supported' });
return;
}
const watchId = navigator.geolocation.watchPosition(
(position) => {
set({
latitude: position.coords.latitude,
longitude: position.coords.longitude,
accuracy: position.coords.accuracy
});
},
(error) => set({ error: error.message })
);
return () => navigator.geolocation.clearWatch(watchId);
});
```
**derived** - Create a store derived from other stores
```javascript
import { writable, derived } from 'svelte/store';
const firstName = writable('Alice');
const lastName = writable('Smith');
// Synchronous derived
const fullName = derived(
[firstName, lastName],
([$first, $last]) => `${$first} ${$last}`
);
// Asynchronous derived with set callback
const user = derived(
fullName,
($fullName, set) => {
fetch(`/api/users?name=${$fullName}`)
.then(r => r.json())
.then(data => set(data))
.catch(err => set({ error: err.message }));
// Optional: return cleanup
return () => {
console.log('Cleanup for', $fullName);
};
},
{ loading: true } // Initial value
);
// Derived from single store
const doubled = derived(count, $count => $count * 2);
// Complex derived with multiple stores
const cart = writable([
{ id: 1, name: 'Item 1', price: 10, quantity: 2 },
{ id: 2, name: 'Item 2', price: 15, quantity: 1 }
]);
const taxRate = writable(0.08);
const cartTotal = derived(
[cart, taxRate],
([$cart, $taxRate]) => {
const subtotal = $cart.reduce((sum, item) =>
sum + item.price * item.quantity, 0);
const tax = subtotal * $taxRate;
return {
subtotal,
tax,
total: subtotal + tax
};
}
);
```
**readonly** - Make a store read-only
```javascript
import { writable, readonly } from 'svelte/store';
const _count = writable(0);
// Export readonly version
export const count = readonly(_count);
// Export methods to modify the store
export function increment() {
_count.update(n => n + 1);
}
export function reset() {
_count.set(0);
}
```
**get** - Get current store value without subscribing
```javascript
import { writable, get } from 'svelte/store';
const count = writable(5);
// Get current value
const currentCount = get(count);
console.log(currentCount); // 5
// Warning: Creates temporary subscription
// Don't use in reactive contexts (use $count instead)
function handleClick() {
const value = get(count);
console.log('Clicked with count:', value);
count.set(value + 1);
}
```
**toStore / fromStore** - Bridge between runes and stores
```javascript
import { toStore, fromStore } from 'svelte/store';
// Convert $state to store
let count = $state(0);
const countStore = toStore(
() => count,
(v) => count = v
);
// Read-only version
const readonlyStore = toStore(() => count);
// Use in non-runes code
countStore.subscribe(value => console.log('Count:', value));
// Convert store to runes-compatible object
import { writable } from 'svelte/store';
const externalStore = writable(42);
const runeState = fromStore(externalStore);
$effect(() => {
console.log('Value:', runeState.current);
});
// For writable stores, you can set the value
runeState.current = 100; // Updates the store
```
### Reactive Data Structures
**SvelteMap** - Reactive Map implementation
```javascript
Total users: {users.size}
{#each users as [id, user]}
{user.name} ({user.role})
{/each}
```
**SvelteSet** - Reactive Set implementation
```javascript
Tags: {tags.size}
{#each tags as tag}
{tag}
{/each}
```
**SvelteDate** - Reactive Date wrapper
```javascript
Current time: {now.toLocaleTimeString()}
Unix timestamp: {now.getTime()}
Date: {now.toLocaleDateString()}
```
**SvelteURL** - Reactive URL and URLSearchParams
```javascript
`;
const result = await preprocess(source, [
{
// TypeScript preprocessor
script: ({ content, attributes }) => {
if (attributes.lang !== 'ts') return;
// Use TypeScript compiler or esbuild
const code = transformTypeScript(content);
return { code };
}
},
{
// SCSS preprocessor
style: async ({ content, attributes }) => {
if (attributes.lang !== 'scss') return;
const { css } = await compileSass(content);
return { code: css };
}
},
{
// Markup preprocessor (e.g., add JSDoc comments)
markup: ({ content }) => {
const enhanced = content.replace(
/
{@render dynamicSnippet(() => userName)}
{@render counter(() => count, () => count++)}
```
### Easing Functions
**Built-in easing functions** - Animation timing functions
```javascript
import {
linear,
cubicOut,
cubicInOut,
quintOut,
elasticOut,
bounceOut
} from 'svelte/easing';
import { tweened } from 'svelte/motion';
import { fly } from 'svelte/transition';
const linearValue = tweened(0, { easing: linear });
const smoothValue = tweened(0, { easing: cubicOut });
const elasticValue = tweened(0, { easing: elasticOut });
const bounceValue = tweened(0, { easing: bounceOut });
// Available easing functions:
// linear, backIn, backOut, backInOut
// bounceIn, bounceOut, bounceInOut
// circIn, circOut, circInOut
// cubicIn, cubicOut, cubicInOut
// elasticIn, elasticOut, elasticInOut
// expoIn, expoOut, expoInOut
// quadIn, quadOut, quadInOut
// quartIn, quartOut, quartInOut
// quintIn, quintOut, quintInOut
// sineIn, sineOut, sineInOut
```
## Summary
Svelte provides a comprehensive and modern approach to building reactive web applications through its compilation-based architecture. The framework's APIs are designed to be intuitive and ergonomic, reducing boilerplate while maintaining full type safety. Core runtime functions like `mount`, `hydrate`, and the lifecycle hooks (`onMount`, `onDestroy`) give developers fine-grained control over component behavior. The context API enables clean dependency injection patterns, while the reactivity system—powered by runes (`$state`, `$derived`, `$effect`)—provides automatic tracking of dependencies with options for optimization through `untrack` and `getAbortSignal`. Async utilities like `tick` and `settled` help coordinate DOM updates and state changes. The experimental `fork` API enables off-screen state evaluation for advanced use cases like route preloading. The store APIs (`writable`, `readable`, `derived`) offer robust state management that integrates seamlessly with the runes system via `toStore` and `fromStore` bridges.
Beyond basic reactivity, Svelte includes a rich ecosystem of utilities for common frontend tasks. The reactive data structures (`SvelteMap`, `SvelteSet`, `SvelteDate`, `SvelteURL`, `SvelteURLSearchParams`) wrap built-in JavaScript objects with automatic change tracking. The `createSubscriber` API allows seamless integration of external event systems (WebSockets, IntersectionObserver, etc.) with Svelte's reactivity. Window properties (`scrollX`, `scrollY`, `innerWidth`, `innerHeight`, `online`, etc.) are available as reactive values through `svelte/reactivity/window`, making it trivial to build responsive and scroll-aware interfaces. Built-in transitions (`fade`, `fly`, `slide`, `scale`) and animations (`flip`, `crossfade`) make UI polish straightforward, while `Spring` and `tweened` enable physics-based and interpolated animations with minimal code. The action system (`use:action`) provides a powerful way to encapsulate reusable DOM behaviors, while the newer attachment API (`createAttachmentKey`, `fromAction`) offers a modern alternative for library authors. Event handling is enhanced with the `on` function that preserves proper event delegation ordering. On the tooling side, the compiler API (`compile`, `parse`, `preprocess`) enables custom build pipelines and editor integrations, while server-side rendering through the `render` function supports universal/isomorphic applications. This combination of compiler intelligence, reactive primitives, and practical utilities makes Svelte an excellent choice for projects ranging from simple widgets to complex full-stack applications.