Svelte
Overview
Svelte is a compiler-based UI framework that shifts work from runtime to build time, producing minimal JavaScript with no virtual DOM. Svelte 5 introduces runes for explicit, fine-grained reactivity. SvelteKit is the full-stack framework built on Svelte, providing file-based routing, server-side rendering, and deployment adapters.
When to use: Full-stack web apps, static sites, progressive enhancement, SSR/SSG, projects needing small bundle sizes, migration from Svelte 4 to 5.
When NOT to use: React/Vue ecosystem lock-in, projects requiring extensive third-party component libraries only available for other frameworks, teams with no Svelte experience on tight deadlines.
Quick Reference
| Pattern |
API / Syntax |
Key Points |
| Reactive state |
let count = $state(0) |
Replaces let reactivity from Svelte 4 |
| Derived state |
const double = $derived(count * 2) |
Replaces $: reactive declarations |
| Complex derivation |
const value = $derived.by(() => { ... }) |
Multi-statement derived computations |
| Side effects |
$effect(() => { ... }) |
Runs after DOM update, auto-tracks dependencies |
| Component props |
let { name, age = 25 } = $props() |
Replaces export let, supports defaults |
| Bindable props |
let { value = $bindable() } = $props() |
Two-way binding with bind:value |
| Debug inspection |
$inspect(value) |
Dev-only logging, stripped in production |
| Snippets |
{#snippet name(params)}...{/snippet} |
Replaces slots, reusable template blocks |
| Render snippet |
{@render name(args)} |
Invoke a snippet with arguments |
| Event handling |
<button> |
Properties replace on:click directive |
| Each blocks |
{#each items as item (item.id)}...{/each} |
Keyed iteration for efficient updates |
| Await blocks |
{#await promise}...{:then}...{:catch}... |
Inline async rendering |
| Server load |
export function load({ params }) in +page.server.ts |
Runs server-side only, accesses DB/secrets |
| Universal load |
export function load({ fetch }) in +page.ts |
Runs on server and client |
| Form actions |
export const actions in +page.server.ts |
Progressive enhancement with use:enhance |
| Layout |
+layout.svelte / +layout.server.ts |
Shared UI and data across child routes |
| Server hooks |
handle() in src/hooks.server.ts |
Request middleware, auth, redirects |
| Error page |
+error.svelte |
Per-route error boundaries |
| Adapters |
adapter-auto, adapter-node, adapter-static |
Deploy to Vercel, Node, static hosting |
| API routes |
+server.ts with GET, POST, etc. |
Standalone endpoints, not tied to pages |
| Page options |
export const prerender = true |
Per-route SSR, CSR, prerender control |
| Shared state |
$state() in .svelte.ts modules |
Replaces writable stores for cross-component state |
| Raw state |
$state.raw(data) |
Opts out of deep proxying for large datasets |
Svelte 4 to 5 Migration
| Svelte 4 (Legacy) |
Svelte 5 (Current) |
let count = 0 (reactive) |
let count = $state(0) |
$: double = count * 2 |
const double = $derived(count * 2) |
$: { sideEffect() } |
$effect(() => { sideEffect() }) |
export let name |
let { name } = $props() |
<slot /> |
{#snippet children()}{/snippet} + {@render} |
on:click={handler} |
onclick={handler} |
createEventDispatcher() |
Callback props: let { onclick } = $props() |
import { writable } from 'svelte/store' |
$state() in .svelte.ts modules |
$store auto-subscription |
Direct value access from rune-based state |
Common Mistakes
| Mistake |
Correct Pattern |
Using $state on non-primitives without care |
$state deeply proxies objects; use $state.raw() for large read-only data |
Destructuring $props() loses reactivity |
Destructure at declaration only: let { x } = $props() |
Reading $effect dependencies conditionally |
Ensure all tracked reads happen unconditionally |
Returning cleanup from $effect incorrectly |
Return a function: $effect(() => { return () => cleanup() }) |
Mixing on:click and onclick in Svelte 5 |
Use onclick exclusively in Svelte 5 components |
| Using stores in new Svelte 5 code |
Use $state() in .svelte.ts modules for shared state |
Forgetting (key) in {#each} blocks |
Always key: {#each items as item (item.id)} |
Exporting load from .svelte files |
Load functions belong in +page.ts or +page.server.ts |
Not awaiting parent load in layouts |
Use await parent() when child load depends on layout |
Using goto() in server load functions |
Use redirect(303, '/path') from @sveltejs/kit |
Delegation
- Pattern discovery: Use
Explore agent
- Code review: Delegate to
code-reviewer agent
- Build configuration: Delegate to
Task agent
If the tailwind skill is available, delegate Tailwind CSS utility class patterns and configuration to it.
If the vitest-testing skill is available, delegate Svelte component unit testing patterns to it.
If the playwright skill is available, delegate end-to-end testing of SvelteKit routes and form actions to it.
If the drizzle-orm skill is available, delegate database schema and query patterns used in SvelteKit server load functions to it.
If the vite skill is available, delegate Vite build configuration and plugin setup to it.
References
- Runes and reactivity patterns ($state, $derived, $effect, $props)
- Snippets, rendering, and component composition
- SvelteKit routing, load functions, and layouts
- Form actions, progressive enhancement, and validation
- Hooks, middleware, and error handling
- Svelte 4 to 5 migration patterns
- SvelteKit adapters and deployment
1---2name: svelte3description: Svelte 5 and SvelteKit framework patterns. Covers runes ($state, $derived, $effect, $props, $bindable, $inspect), snippets, fine-grained reactivity, component composition, and event handling. SvelteKit coverage includes file-based routing, server and universal load functions, form actions, hooks, adapters, and error handling. Includes Svelte 4 to 5 migration guidance (stores to runes, on:event to onevent, slots to snippets). Use when building Svelte 5 components, configuring SvelteKit routing, implementing form actions, migrating from Svelte 4, or debugging reactivity issues.4license: MIT5---6
7# Svelte
8
9## Overview
10
11Svelte is a **compiler-based UI framework** that shifts work from runtime to build time, producing minimal JavaScript with no virtual DOM. Svelte 5 introduces runes for explicit, fine-grained reactivity. SvelteKit is the full-stack framework built on Svelte, providing file-based routing, server-side rendering, and deployment adapters.
12
13**When to use:** Full-stack web apps, static sites, progressive enhancement, SSR/SSG, projects needing small bundle sizes, migration from Svelte 4 to 5.
14
15**When NOT to use:** React/Vue ecosystem lock-in, projects requiring extensive third-party component libraries only available for other frameworks, teams with no Svelte experience on tight deadlines.
16
17## Quick Reference
18
19| Pattern | API / Syntax | Key Points |
20| ------------------ | ------------------------------------------------------- | -------------------------------------------------- |
21| Reactive state | `let count = $state(0)` | Replaces `let` reactivity from Svelte 4 |
22| Derived state | `const double = $derived(count * 2)` | Replaces `$:` reactive declarations |
23| Complex derivation | `const value = $derived.by(() => { ... })` | Multi-statement derived computations |
24| Side effects | `$effect(() => { ... })` | Runs after DOM update, auto-tracks dependencies |
25| Component props | `let { name, age = 25 } = $props()` | Replaces `export let`, supports defaults |
26| Bindable props | `let { value = $bindable() } = $props()` | Two-way binding with `bind:value` |
27| Debug inspection | `$inspect(value)` | Dev-only logging, stripped in production |
28| Snippets | `{#snippet name(params)}...{/snippet}` | Replaces slots, reusable template blocks |
29| Render snippet | `{@render name(args)}` | Invoke a snippet with arguments |
30| Event handling | `<button onclick={handler}>` | Properties replace `on:click` directive |
31| Each blocks | `{#each items as item (item.id)}...{/each}` | Keyed iteration for efficient updates |
32| Await blocks | `{#await promise}...{:then}...{:catch}...` | Inline async rendering |
33| Server load | `export function load({ params })` in `+page.server.ts` | Runs server-side only, accesses DB/secrets |
34| Universal load | `export function load({ fetch })` in `+page.ts` | Runs on server and client |
35| Form actions | `export const actions` in `+page.server.ts` | Progressive enhancement with `use:enhance` |
36| Layout | `+layout.svelte` / `+layout.server.ts` | Shared UI and data across child routes |
37| Server hooks | `handle()` in `src/hooks.server.ts` | Request middleware, auth, redirects |
38| Error page | `+error.svelte` | Per-route error boundaries |
39| Adapters | `adapter-auto`, `adapter-node`, `adapter-static` | Deploy to Vercel, Node, static hosting |
40| API routes | `+server.ts` with `GET`, `POST`, etc. | Standalone endpoints, not tied to pages |
41| Page options | `export const prerender = true` | Per-route SSR, CSR, prerender control |
42| Shared state | `$state()` in `.svelte.ts` modules | Replaces writable stores for cross-component state |
43| Raw state | `$state.raw(data)` | Opts out of deep proxying for large datasets |
44
45## Svelte 4 to 5 Migration
46
47| Svelte 4 (Legacy) | Svelte 5 (Current) |
48| ----------------------------------------- | ----------------------------------------------- |
49| `let count = 0` (reactive) | `let count = $state(0)` |
50| `$: double = count * 2` | `const double = $derived(count * 2)` |
51| `$: { sideEffect() }` | `$effect(() => { sideEffect() })` |
52| `export let name` | `let { name } = $props()` |
53| `<slot />` | `{#snippet children()}{/snippet}` + `{@render}` |
54| `on:click={handler}` | `onclick={handler}` |
55| `createEventDispatcher()` | Callback props: `let { onclick } = $props()` |
56| `import { writable } from 'svelte/store'` | `$state()` in `.svelte.ts` modules |
57| `$store` auto-subscription | Direct value access from rune-based state |
58
59## Common Mistakes
60
61| Mistake | Correct Pattern |
62| --------------------------------------------- | ---------------------------------------------------------------------------- |
63| Using `$state` on non-primitives without care | `$state` deeply proxies objects; use `$state.raw()` for large read-only data |
64| Destructuring `$props()` loses reactivity | Destructure at declaration only: `let { x } = $props()` |
65| Reading `$effect` dependencies conditionally | Ensure all tracked reads happen unconditionally |
66| Returning cleanup from `$effect` incorrectly | Return a function: `$effect(() => { return () => cleanup() })` |
67| Mixing `on:click` and `onclick` in Svelte 5 | Use `onclick` exclusively in Svelte 5 components |
68| Using stores in new Svelte 5 code | Use `$state()` in `.svelte.ts` modules for shared state |
69| Forgetting `(key)` in `{#each}` blocks | Always key: `{#each items as item (item.id)}` |
70| Exporting load from `.svelte` files | Load functions belong in `+page.ts` or `+page.server.ts` |
71| Not awaiting parent `load` in layouts | Use `await parent()` when child load depends on layout |
72| Using `goto()` in server load functions | Use `redirect(303, '/path')` from `@sveltejs/kit` |
73
74## Delegation
75
76- **Pattern discovery**: Use `Explore` agent
77- **Code review**: Delegate to `code-reviewer` agent
78- **Build configuration**: Delegate to `Task` agent
79
80> If the `tailwind` skill is available, delegate Tailwind CSS utility class patterns and configuration to it.
81> If the `vitest-testing` skill is available, delegate Svelte component unit testing patterns to it.
82> If the `playwright` skill is available, delegate end-to-end testing of SvelteKit routes and form actions to it.
83> If the `drizzle-orm` skill is available, delegate database schema and query patterns used in SvelteKit server load functions to it.
84> If the `vite` skill is available, delegate Vite build configuration and plugin setup to it.
85
86## References
87
88- [Runes and reactivity patterns ($state, $derived, $effect, $props)](references/runes-reactivity.md)
89- [Snippets, rendering, and component composition](references/component-patterns.md)
90- [SvelteKit routing, load functions, and layouts](references/sveltekit-routing.md)
91- [Form actions, progressive enhancement, and validation](references/form-actions.md)
92- [Hooks, middleware, and error handling](references/hooks-errors.md)
93- [Svelte 4 to 5 migration patterns](references/migration-guide.md)
94- [SvelteKit adapters and deployment](references/adapters-deployment.md)