Svelte runes-first reactivity and SvelteKit fullstack conventions. Invoke whenever task involves any interaction with Svelte code — writing, reviewing, refactoring, debugging, or understanding .svelte, .svelte.js, .svelte.ts files and SvelteKit projects.
Provides expert Svelte and SvelteKit assistance for writing, reviewing, and debugging runes-first reactive code.
npx claudepluginhub xobotyi/cc-foundryThis skill inherits all available tools. When active, it can use any tool Claude has access to.
references/components.mdreferences/runes.mdreferences/sveltekit.mdReactivity is explicit, compiler-driven, and minimal-runtime. Every reactive
declaration uses a $ rune. The compiler transforms declarative code into
surgical DOM updates -- no virtual DOM, no diffing, no hidden magic. References
contain extended examples, rationale, and edge cases for each topic.
| Topic | Reference | Contents |
|---|---|---|
| Runes | references/runes.md | $state, $derived, $effect, $props, $bindable details |
| Components | references/components.md | Snippets, events, context, special elements |
| SvelteKit | references/sveltekit.md | Route files, load functions, form actions, hooks, full key imports table |
$state$state or $state.raw. Plain let
declarations are not reactive.$state objects breaks reactivity -- destructured values are
snapshots, not live references.$state on class fields or as first assignment in constructor. The compiler
transforms these into getter/setter pairs. Use arrow functions to preserve this
in event handlers on classes.$state.raw opts out of deep reactivity -- state can only be reassigned, not
mutated. Use for large arrays/objects you replace wholesale to avoid proxy overhead.$state.snapshot(value) takes a static copy of a reactive proxy for external APIs
that don't expect proxies (e.g., structuredClone, logging).Set, Map, Date, URL from svelte/reactivity when you need
reactive built-in types.Cannot directly export reassignable $state. Two patterns:
$state({ count: 0 }) as a const, mutate
properties, export modifier functions.$state private, export getCount() and increment().Runes only work in .svelte and .svelte.js/.svelte.ts files.
$derived$derived for all computed values -- never synchronize state with $effect.$derived.by(() => { ... }) for complex derivations needing a function body.untrack to exempt specific reads.$derived values are individually reactive.$effect$effect is an escape hatch. Use only for side effects: DOM manipulation,
analytics, third-party library calls, timers.await or inside
setTimeout are NOT tracked.$effect.pre runs before DOM updates -- use for pre-DOM manipulation like
autoscrolling.$effect.tracking() returns true if code is running inside a tracking context.$effect.root(() => { ... }) creates a non-tracked scope for manual effect
lifecycle control. Returns a destroy function.Never use $effect to synchronize state -- use $derived with callback event
handlers or function bindings instead.
$propslet { name, count = 0 } = $props().let { name }: Props = $props().let { class: klass } = $props().let { a, b, ...rest } = $props().let props = $props().$props.id() -- consistent across SSR/hydration.$bindable. Use callback props to communicate changes upward.$bindablelet { value = $bindable() } = $props().bind:value={variable}.$inspect$inspect(count, message) logs when tracked values change.$inspect(value).with((type, ...args) => { ... }) replaces default console.log
with custom callback. Type is "init" or "update".$inspect.trace() traces which reactive state caused a re-execution. Must be first
statement in a function body.$hostOnly available inside custom elements. Provides access to the host element for dispatching custom events.
$props())$state)$derived)$effect, sparingly)<style>)<MyComponent />. Required for dynamic rendering.item.component).<svelte:component> is unnecessary. Just
use <Thing /> where Thing is a reactive variable.onclick={handler}, never on:click={handler}.onclick listens to click, onClick
listens to Click.event.preventDefault() / event.stopPropagation()
in the handler. For capture, append to event name: onclickcapture={...}.let { onEvent } = $props(). Never use createEventDispatcher.click, input, keydown) --
single listener at app root. When manually dispatching events, set
{ bubbles: true }. Prefer on from svelte/events over raw addEventListener.{@render children?.()} for default content. Never use <slot />.{#snippet header()}...{/snippet} in parent, accept
as props, render with {@render header()}.{@render item(entry)} in child, {#snippet item(text)} in parent.{@render children?.()} or {#if children} with fallback.<script module> for cross-component use.Snippet and Snippet<[ParamType]> from svelte.Control flow:
{#if} / {:else if} / {:else} / {/if} for conditional blocks.{#each items as item, index (item.id)} with key expression for lists. Always
provide a key for lists that can change. :else renders when array is empty.{#key value} destroys and recreates contents when value changes -- triggers entry
transitions or resets component state.{#await promise} / {:then value} / {:catch error} for async. Short forms:
{#await promise then value} skips loading state.Special tags:
{@html rawHtml} -- render raw HTML (escape user input to prevent XSS).{@const x = expr} -- declare local constant inside a block scope.{@debug var1, var2} -- trigger debugger when values change.{@render snippet()} -- render a snippet.{@attach action} -- attach an action to an element.Text expressions: {expression} outputs stringified, escaped value. null and
undefined are omitted.
Conditional classes: object syntax like clsx: class={{ cool, lame: !cool }}.
setContext(key, value) / getContext(key) passes data through the component tree
without prop drilling.createContext<T>() from svelte which returns
[getContext, setContext] pair.setContext to maintain reactivity across boundaries.<svelte:boundary> -- error boundary. Use {#snippet failed(error, reset)} for
error UI and {#snippet pending()} for loading state with await expressions.<svelte:window> -- bind to window events and properties (bind:scrollY).<svelte:head> -- insert elements into document.head (SEO meta tags, title).<svelte:element this={tag}> -- render a dynamic HTML element.<svelte:options> -- set compiler options (customElement, namespace).Components are functions, not classes:
mount(Component, { target }) for client-side mounting.unmount(app) to destroy.hydrate instead of mount for server-rendered HTML.$state is shared across
requests during SSR. Use context or event.locals instead.load, don't write to globals. No side effects in load functions.setContext/getContext for data that must
not leak between requests.$derived for reactive computed values in components -- plain assignments in
<script> run once, not reactively..svelte.js / .svelte.ts for reactive modules -- runes only work in .svelte
and .svelte.js/.svelte.ts files.$lib for shared code -- import from $lib/ instead of relative paths climbing
multiple levels.| File | Purpose |
|---|---|
+page.svelte | Page component (receives data from load) |
+page.js | Universal load (server + browser) |
+page.server.js | Server-only load + form actions |
+layout.svelte | Layout wrapper (must render {@render children()}) |
+layout.js | Layout universal load |
+layout.server.js | Layout server load |
+error.svelte | Error boundary |
+server.js | API endpoint (GET, POST, etc.) |
Key rules: all files can run on the server. All run on the client except +server
files. +layout and +error apply to subdirectories too.
Decision tree:
| Need | Use |
|---|---|
| Database, private keys | +page.server.js (PageServerLoad) |
| Non-serializable return values | +page.js (PageLoad) |
| External API, no secrets | +page.js (PageLoad) |
| Both | Both (server data flows to universal) |
Universal vs server:
| Aspect | Universal (+page.js) | Server (+page.server.js) |
|---|---|---|
| Runs on | Server (SSR) + Browser | Server only |
| Access | params, url, fetch | + cookies, locals, request |
| Returns | Any value (classes, components) | Serializable data only |
fetch, not global fetch -- inherits cookies, makes relative
requests work on server, bypasses HTTP overhead for internal requests.+page.js: prerender, ssr, csr.params change, url
properties change, parent() was called and parent reran, or
invalidate()/invalidateAll() called.error() and redirect() from @sveltejs/kit for error and redirect responses.Server-only POST handlers in +page.server.js. Work without JavaScript.
export const actions = { default: async ({ request }) => { ... } }.action="?/login" on form, multiple actions in the actions object.fail(400, { field, missing: true }) from action. Access via
form prop in the page component.use:enhance from $app/forms for JS-enhanced
submission without full page reload.Export HTTP verb handlers from +server.js: GET, POST, PUT, PATCH, DELETE.
Return json() or new Response().
Server hooks (src/hooks.server.js):
handle({ event, resolve }) -- intercept every request. Set event.locals, modify
response headers.handleFetch -- modify server-side fetch calls.handleError -- log and sanitize unexpected errors.init -- run once at server startup.Client hooks (src/hooks.client.js):
handleError -- client-side error handling.Universal hooks (src/hooks.js):
reroute -- rewrite URLs before routing.transport -- serialize/deserialize custom types across server/client boundary.Most-used modules: $app/navigation (goto, invalidate), $app/state (page,
navigating), $app/forms (enhance), $env/static/private and
$env/static/public for environment variables, $lib for shared code. Full imports
table in references/sveltekit.md.
load functions to avoid browser-to-API waterfalls.$derived instead of $effect for computed values.<body>).@sveltejs/enhanced-img for image optimization.import() for conditional code.When writing Svelte code:
When reviewing Svelte code:
This skill provides Svelte-specific conventions. The coding skill governs workflow; for TypeScript projects, the typescript skill handles language-level choices; for CSS concerns, the css skill handles styling conventions.
Applies Anthropic's official brand colors and typography to any sort of artifact that may benefit from having Anthropic's look-and-feel. Use it when brand colors or style guidelines, visual formatting, or company design standards apply.
Creating algorithmic art using p5.js with seeded randomness and interactive parameter exploration. Use this when users request creating art using code, generative art, algorithmic art, flow fields, or particle systems. Create original algorithmic art rather than copying existing artists' work to avoid copyright violations.
Create beautiful visual art in .png and .pdf documents using design philosophy. You should use this skill when the user asks to create a poster, piece of art, design, or other static piece. Create original visual designs, never copying existing artists' work to avoid copyright violations.