with-svelte
Unified Svelte 5 + SvelteKit skill. This body is a router: apply the always-on core below, then READ the one reference file that matches the task before writing code. Load only the file(s) you need — not all of them.
Always-on core (every Svelte task)
Write runes-mode Svelte 5. Never reach for a legacy feature that has a modern replacement:
$stateinstead of implicitlet count = 0; count += 1$derived/$effectinstead of$:— and prefer$derivedover$effect(effects are an escape hatch; never set state inside one)$propsinstead ofexport let,$$props,$$restPropsonclick={...}instead ofon:click={...}{#snippet}/{@render}instead of<slot>,$$slots,<svelte:fragment>{@attach ...}instead ofuse:action<DynamicComponent>instead of<svelte:component this={...}>;import Selfinstead of<svelte:self>- classes with
$statefields instead of stores;createContextinstead ofsetContext/getContext - clsx-style class arrays/objects instead of the
class:directive - keyed
{#each}— never use the index as the key
When unsure of current syntax, do not guess — confirm via the @sveltejs/mcp CLI (see references/tooling.md) and run svelte-autofixer before finalizing any component.
Routing table — READ the matching reference before writing
| Task involves… | MANDATORY READ |
|---|---|
Runes — $state, $derived, $effect, choosing between them |
references/runes-core.md |
Runes — $props, $bindable, reactive class fields, createSubscriber, $inspect |
references/runes-props.md |
Runes — await in components, async reactivity, hydratable |
references/runes-async.md |
| Runes — porting Svelte 4 syntax to runes mode | references/runes-migration.md |
| Runes — reactivity that compiles but behaves wrongly | references/runes-antipatterns.md |
Template — {@attach}, migrating use: actions |
references/attachments.md |
Template — {#snippet} / {@render}, replacing slots |
references/snippets.md |
Template — {@html}, {@const}, {@debug}, keyed each, bind:, <svelte:window> |
references/template-tags.md |
| Components — Bits/Ark/Melt UI, web components, custom elements | references/component-libraries.md |
| Components — forms inside components | references/forms.md |
| Components — CSS from JS, styling children, context | references/styling-context.md |
Routing — file naming (+page/+layout/+error/+server), route groups, params |
references/routing-files.md |
| Routing — nested layouts, layout groups, layout data | references/layouts.md |
Routing — +error.svelte, expected vs unexpected errors |
references/error-handling.md |
Routing — <svelte:boundary> |
references/error-boundary.md |
| Routing — SSR, hydration mismatches, browser-only work | references/ssr-hydration.md |
Data — load functions, server vs universal, depends |
references/load-functions.md |
| Data — form actions, progressive enhancement | references/form-actions.md |
Data — fail() / redirect() / error() |
references/errors-redirects.md |
Data — serialization across the boundary, invalidateAll() |
references/serialization-invalidation.md |
Remote — query() / form() in *.remote.ts, schema validation |
references/remote-query-form.md |
Remote — command(), single-flight mutations, prerender(), getRequestEvent() |
references/remote-command-prerender.md |
| Deploy — adapters, Vite/pnpm build setup | references/deployment-adapters.md |
| Deploy — publishing a Svelte library | references/library-authoring.md |
| Deploy — PWA setup, Cloudflare/streaming gotchas | references/pwa-and-cloudflare.md |
| Tooling — confirming syntax, looking up docs, validating/fixing code | references/tooling.md |
If a task spans areas (e.g. a form that uses runes + a server action), read each matching file. Do not load files outside the task's scope. If no reference covers the case, fetch authoritative docs via references/tooling.md rather than guessing.
NEVER
NEVER set
$stateinside an$effectto compute a value Instead: use$derived(or$derived.byfor complex expressions). Why: effect-driven assignment creates extra render passes and update loops;$derivedis glitch-free and runs lazily.NEVER guard effect/lifecycle code with
if (browser) {...}to make it server-safe Instead: effects already don't run on the server; for global listeners use<svelte:window>/<svelte:document>, and for browser-only setup use the right reference's SSR guidance. Why: the guard is dead code inside an effect and signals a misunderstanding that hides real hydration bugs.NEVER return non-serializable values (class instances, functions, symbols) from a SvelteKit
loador remote function Instead: return plain JSON-serializable data; seereferences/serialization-invalidation.md/references/remote-command-prerender.md. Why: load uses JSON and remote functions usedevalue; non-serializable returns fail silently or at runtime across the server→client boundary.NEVER call
redirect()/error()in SvelteKit withoutthrow-ing them Instead:throw redirect(303, '/path')/throw error(404). Why: withoutthrowexecution continues and the navigation/error never happens.NEVER guess current Svelte/SvelteKit API surface from memory for unfamiliar features Instead: run
npx @sveltejs/mcp list-sections+get-documentation, thensvelte-autofixer(seereferences/tooling.md). Why: runes, remote functions, and async Svelte change fast and are version-gated; stale syntax compiles to subtly wrong behavior.