Back to skills
SKILL.md
Svelte
ASecurityCovers Svelte 5 and SvelteKit 2: the compiler model (no virtual DOM), runes reactivity system ($state, $derived, $effect, $props, $bindable), SvelteKit routing (+page, +layout, +server, load functions, form actions), SSR/hydration, adapters, snippets, testing, and migration from Svelte 4. Use for \"Svelte\", \"svelte\", \"SvelteKit\", \"runes\", \"$state\", \"$derived\", \"$effect\", \"$props\", \"Svelte 5\", \"+page.svelte\", \"load function Svelte\", \"form actions Svelte\" questions.
- 4 stars
- 0 votes
- 0 copies
- 0 views
- Added September 24, 2026
Works with
Security analysis
100/100Pro scans all 9 files and shows the line behind each finding
npx -y skills add chrishuffman5/domain-expert --skill svelte --agent claude-codeAre you the author of Svelte?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/chrishuffman5-svelte)---
name: svelte
description: "Covers Svelte 5 and SvelteKit 2: the compiler model (no virtual DOM), runes reactivity system ($state, $derived, $effect, $props, $bindable), SvelteKit routing (+page, +layout, +server, load functions, form actions), SSR/hydration, adapters, snippets, testing, and migration from Svelte 4. Use for \"Svelte\", \"svelte\", \"SvelteKit\", \"runes\", \"$state\", \"$derived\", \"$effect\", \"$props\", \"Svelte 5\", \"+page.svelte\", \"load function Svelte\", \"form actions Svelte\" questions."
license: MIT
---
# Svelte / SvelteKit
This skill covers Svelte 5 and SvelteKit 2, including:
- Compiler model: no virtual DOM, build-time compilation to surgical DOM updates, fine-grained reactivity via compiler analysis
- Runes system (Svelte 5): `$state`, `$derived`, `$effect`, `$props`, `$bindable`, `$inspect`, `$state.raw`
- Snippets: `{@render children()}` replacing `<slot />`, reusable template fragments
- SvelteKit routing: filesystem-based with `+page.svelte`, `+layout.svelte`, `+server.js`, `+error.svelte`
- Load functions: universal (`+page.js`) and server-only (`+page.server.js`), data flow, typed `PageData`
- Form actions: server-side form handling, `use:enhance` for progressive enhancement, `fail()` for validation
- SSR and rendering modes: `ssr`, `csr`, `prerender` per route, streaming, selective hydration
- Adapters: `adapter-auto`, `adapter-node`, `adapter-static`, `adapter-vercel`, `adapter-cloudflare`
- Hooks: `handle`, `handleError`, `handleFetch` in `hooks.server.js`
- Environment variables: `$env/static/private`, `$env/static/public`, `$env/dynamic/private`, `$env/dynamic/public`
- Shared state: `.svelte.ts` modules with `$state` for cross-component state
- Testing: Vitest + `@testing-library/svelte`, load function testing, form action testing
- Deployment: adapter selection, `ORIGIN` env var, prerendering strategies
- Migration: Svelte 4 to 5 runes conversion (`let` to `$state`, `$:` to `$derived`/`$effect`, `<slot>` to snippets)
## How to Approach Tasks
When you receive a request:
1. **Classify** the request type:
- **Troubleshooting** -- Load `references/diagnostics.md`
- **Routing / Data Flow** -- Load `references/patterns/routing.md`
- **Runes / Reactivity** -- Load `references/patterns/runes.md`
- **Architecture / Design** -- Load `references/architecture.md`
- **Deployment** -- Load `references/patterns/deployment.md`
- **Best Practices** -- Load `references/best-practices.md`
- **Configuration** -- Reference `assets/svelte.config.js` or `assets/vite.config.ts`
2. **Identify context** -- Determine if the question is about Svelte components, SvelteKit routing/data, or server-side features. These have different APIs and patterns.
3. **Load context** -- Read the relevant reference file for deep knowledge.
4. **Analyze** -- Apply Svelte-specific reasoning. Consider the compiler model (no runtime framework), runes semantics, and SvelteKit's server/client boundary.
5. **Recommend** -- Provide actionable guidance with code examples. Use Svelte 5 runes syntax (not Svelte 4 patterns) unless explicitly migrating.
6. **Verify** -- Suggest validation steps (Svelte compiler warnings, SvelteKit type generation, test assertions).
## Core Expertise
### Compiler Model
Svelte is a compiler, not a runtime framework. There is no virtual DOM. `.svelte` files compile at build time into optimized vanilla JavaScript that surgically updates the DOM via direct DOM mutation calls.
The compiler traces which reactive values flow into which DOM expressions and generates minimal update code per expression. A state variable used in three template locations produces three independent update paths.
**Module modes:**
- `.svelte` -- component files compiled by `@sveltejs/vite-plugin-svelte`
- `.svelte.ts` / `.svelte.js` -- non-component modules that can use runes (shared reactive state)
### Runes System (Svelte 5)
Runes are `$`-prefixed compiler directives that declare reactivity.
```svelte
<script lang="ts">
// $state -- reactive state (deep proxy for objects/arrays)
let count = $state(0);
let user = $state({ name: 'Alice', age: 30 });
let items = $state<string[]>([]);
// $state.raw -- opt out of deep reactivity
let data = $state.raw(hugeArray);
// $derived -- computed values (lazy, cached)
let doubled = $derived(count * 2);
let label = $derived.by(() => count > 10 ? 'high' : 'low');
// $effect -- side effects (runs after DOM update)
$effect(() => {
console.log(count); // auto-tracked
return () => { /* cleanup */ };
});
// $props -- component props
let { name, age = 18 }: { name: string; age?: number } = $props();
// $bindable -- two-way bindable props
let { value = $bindable('') } = $props();
</script>
```
### SvelteKit Routing
Filesystem-based routing under `src/routes/`. Every folder maps to a URL segment.
| File | Purpose |
|---|---|
| `+page.svelte` | Page UI component |
| `+page.js` | Universal load (server + client) |
| `+page.server.js` | Server-only load + form actions |
| `+layout.svelte` | Shared UI wrapper |
| `+layout.js` / `+layout.server.js` | Layout load functions |
| `+server.js` | API endpoint (GET, POST, etc.) |
| `+error.svelte` | Error UI |
Route syntax:
```
src/routes/
blog/[slug]/+page.svelte -> /blog/:slug
blog/[...rest]/+page.svelte -> /blog/a/b/c (catch-all)
blog/[[optional]]/+page.svelte -> /blog or /blog/value
(group)/admin/+page.svelte -> /admin (group adds no URL)
```
### Load Functions
```js
// +page.server.js -- server only (has access to cookies, locals, DB)
export async function load({ params, locals, cookies }) {
if (!locals.user) throw redirect(302, '/login');
return { stats: await db.getUserStats(locals.user.id) };
}
```
```svelte
<!-- +page.svelte -->
<script lang="ts">
import type { PageData } from './$types';
let { data }: { data: PageData } = $props();
</script>
<h1>{data.stats.title}</h1>
```
### Form Actions
```js
// +page.server.js
export const actions = {
default: async ({ request }) => {
const data = await request.formData();
const email = data.get('email');
if (!email) return fail(422, { missing: true });
await sendEmail(email);
throw redirect(303, '/success');
}
};
```
```svelte
<script>
import { enhance } from '$app/forms';
let { form } = $props();
</script>
<form method="POST" use:enhance>
<input name="email" value={form?.email ?? ''} />
<button>Send</button>
</form>
```
### Hooks
```js
// src/hooks.server.js
export async function handle({ event, resolve }) {
event.locals.user = await validateSession(event.cookies.get('session'));
return resolve(event);
}
```
## Common Pitfalls
**1. Using Svelte 4 syntax in runes mode**
`$:` reactive declarations, `export let`, and `<slot />` do not work in runes mode. Use `$derived`, `$props`, and `{@render children()}`.
**2. Effect cycles**
Reading and writing the same `$state` in a `$effect` creates an infinite loop. Use `$derived` for computed values.
**3. `$props()` outside component initialization**
`$props()` must be called at the top level of `<script>`, never inside a function.
**4. Missing `$bindable` on bound props**
Parent `bind:value` requires child to declare `let { value = $bindable() } = $props()`.
**5. `window`/`document` in SSR**
These globals do not exist on the server. Use `$effect` (browser-only) or `import { browser } from '$app/environment'`.
**6. Browser-only libraries**
Dynamic import inside `onMount`: `onMount(async () => { const lib = await import('lib'); })`.
**7. Stale `PageData` types**
After adding/changing load functions, restart dev server or run `npx svelte-kit sync`.
**8. CSRF error on form POST**
SvelteKit validates `Origin` header. Set `ORIGIN` env var in production. Disable in test: `csrf: { checkOrigin: false }`.
**9. 404 on direct URL access (static adapter)**
Need `adapter({ fallback: '200.html' })` for SPA-style client routing.
**10. Store `$` shorthand confusion in runes**
Auto-subscription `$myStore` works in runes mode but may behave unexpectedly. Prefer `.svelte.ts` module-level `$state` for new shared state.
## Reference Files
- `references/architecture.md` -- Compiler model, runes, SvelteKit routing, load functions, form actions, SSR, adapters. Read for "how does X work" questions.
- `references/best-practices.md` -- Runes patterns, data flow, deployment, testing. Read for design and quality questions.
- `references/diagnostics.md` -- Compiler errors, SSR issues, runes migration pitfalls. Read when troubleshooting.
## Configuration References
- `assets/svelte.config.js` -- Annotated SvelteKit configuration with adapter, preprocessing, and compiler options
- `assets/vite.config.ts` -- Annotated Vite configuration with SvelteKit plugin and test setup
## Pattern Guides
- `references/patterns/runes.md` -- $state/$derived/$effect patterns, shared state, Svelte 4 migration
- `references/patterns/routing.md` -- +page, +layout, +server, load functions, form actions, hooks
- `references/patterns/deployment.md` -- Adapter selection, env variables, prerendering strategies
Files in this skill
- SKILL.md
- assets/svelte.config.js
- assets/vite.config.ts
- references/architecture.md
- references/best-practices.md
- references/diagnostics.md
- references/patterns/deployment.md
- references/patterns/routing.md
- references/patterns/runes.md
Attribution
Comments
Loading comments…