Skip to content
Back to skills

Svelte

ASecurity

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.

  • 4 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 24, 2026
developmentjavascriptjavareactnodeexpresstestingapi

Works with

  • cli
  • api

Security analysis

A100/100

Pro scans all 9 files and shows the line behind each finding

Scanned September 24, 2026

npx -y skills add chrishuffman5/domain-expert --skill svelte --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Svelte?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Svelte
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/chrishuffman5-svelte/badge)](https://www.skillsdirectory.com/skills/chrishuffman5-svelte)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
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.md9 KB
  • assets/svelte.config.js1.8 KB
  • assets/vite.config.ts1.2 KB
  • references/architecture.md8.7 KB
  • references/best-practices.md7.5 KB
  • references/diagnostics.md5.2 KB
  • references/patterns/deployment.md5.8 KB
  • references/patterns/routing.md7.2 KB
  • references/patterns/runes.md6.9 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…