svelte
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.
What this skill does
# Svelte
**Reactivity 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.
## References
- **Runes** — [`${CLAUDE_SKILL_DIR}/references/runes.md`]: `$state`, `$derived`, `$effect`, `$props`, `$bindable`
details
- **Components** — [`${CLAUDE_SKILL_DIR}/references/components.md`]: Snippets, events, context, special elements
- **SvelteKit** — [`${CLAUDE_SKILL_DIR}/references/sveltekit.md`]: Routing, load functions, form actions, hooks, imports
## Runes
### `$state`
- Every mutable reactive value must use `$state` or `$state.raw`. Plain `let` declarations are not reactive.
- Arrays and plain objects become deeply reactive proxies. Mutations trigger granular updates.
- Destructuring `$state` objects breaks reactivity -- destructured values are snapshots, not live references.
- Use `$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).
- Import reactive `Set`, `Map`, `Date`, `URL` from `svelte/reactivity` when you need reactive built-in types.
### Sharing State Across Modules
Cannot directly export reassignable `$state`. Two patterns:
- **Object property (preferred):** export `$state({ count: 0 })` as a const, mutate properties, export modifier
functions.
- **Getter function:** keep `$state` private, export `getCount()` and `increment()`.
Runes only work in `.svelte` and `.svelte.js`/`.svelte.ts` files.
### `$derived`
- Use `$derived` for all computed values -- never synchronize state with `$effect`.
- `$derived.by(() => { ... })` for complex derivations needing a function body.
- Only synchronously read values are tracked. Use `untrack` to exempt specific reads.
- Derived values can be temporarily overridden (useful for optimistic UI) -- reverts to derived computation on next
dependency update.
- Destructured `$derived` values are individually reactive.
- Push-pull reactivity: dependents are notified immediately (push) but only recalculated on read (pull). If new value is
referentially identical, downstream updates are skipped.
### `$effect`
- `$effect` is an escape hatch. Use only for side effects: DOM manipulation, analytics, third-party library calls,
timers.
- Return a cleanup function when acquiring resources (intervals, listeners).
- Only synchronously read values are tracked -- values read after `await` or inside `setTimeout` are NOT tracked.
- Conditional reads: only values read in the last execution are dependencies.
- Runs only in the browser, after DOM updates.
- `$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.
### `$props`
- Always destructure props: `let { name, count = 0 } = $props()`.
- Type with an interface in TypeScript: `let { name }: Props = $props()`.
- Renaming: `let { class: klass } = $props()`.
- Rest props: `let { a, b, ...rest } = $props()`.
- All props: `let props = $props()`.
- Unique ID: `$props.id()` -- consistent across SSR/hydration.
- Props can be temporarily overridden by child. Do NOT mutate prop objects unless `$bindable`. Use callback props to
communicate changes upward.
### `$bindable`
- Marks a prop as two-way bindable: `let { value = $bindable() } = $props()`.
- Parent optionally uses `bind:value={variable}`.
- Use sparingly -- overuse makes data flow unpredictable. Prefer callback props for most parent-child communication.
### `$inspect`
- Development-only debugging rune. Re-runs when arguments change. Noop in production.
- `$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.
### `$host`
Only available inside custom elements. Provides access to the host element for dispatching custom events.
## Components
### Structure Order
1. Imports
2. Props (`$props()`)
3. State (`$state`)
4. Derived values (`$derived`)
5. Effects (`$effect`, sparingly)
6. Functions
7. Markup (template)
8. Styles (`<style>`)
### Naming
- Capitalize component names: `<MyComponent />`. Required for dynamic rendering.
- Component names must be capitalized or use dot notation (`item.component`).
- Components are dynamic by default -- `<svelte:component>` is unnecessary. Just use `<Thing />` where `Thing` is a
reactive variable.
### Events
- Use standard event attributes: `onclick={handler}`, never `on:click={handler}`.
- Event attributes are case sensitive -- `onclick` listens to `click`, `onClick` listens to `Click`.
- No event modifiers -- call `event.preventDefault()` / `event.stopPropagation()` in the handler. For capture, append to
event name: `onclickcapture={...}`.
- Callback props for component events -- pass functions as props: `let { onEvent } = $props()`. Never use
`createEventDispatcher`.
- Event forwarding: accept callback props and spread them onto elements.
- Multiple handlers: combine in a single function (no duplicate attributes).
- Svelte uses event delegation for common events (`click`, `input`, `keydown`) -- single listener at app root. When
manually dispatching events, set `{ bubbles: true }`. Prefer `on` from `svelte/events` over raw `addEventListener`.
### Snippets
- Use `{@render children?.()}` for default content. Never use `<slot />`.
- Named snippets: declare with `{#snippet header()}...{/snippet}` in parent, accept as props, render with
`{@render header()}`.
- Snippets with parameters pass data from child to parent: `{@render item(entry)}` in child, `{#snippet item(text)}` in
parent.
- Optional snippets: use `{@render children?.()}` or `{#if children}` with fallback.
- Snippets follow lexical scoping -- visible within their declaring block and children.
- Top-level snippets can be exported from `<script module>` for cross-component use.
- Type snippets with `Snippet` and `Snippet<[ParamType]>` from `svelte`.
### Template Syntax
**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 }}`.
### ContextRelated in Web Dev
generating-lwc-components
IncludedLightning Web Components with PICKLES methodology and 165-point scoring. Use this skill when the user creates or edits LWC components, builds wire service patterns, or writes Jest tests for LWC. TRIGGER when: user creates/edits LWC components, touches lwc/**/*.js, .html, .css, .js-meta.xml files, or asks about wire service, SLDS, or Jest LWC tests. DO NOT TRIGGER when: Apex classes (use generating-apex), Aura components, or Visualforce.
tanstack-query
IncludedManage server state in React with TanStack Query v5. Set up queries with useQuery, mutations with useMutation, configure QueryClient caching strategies, implement optimistic updates, and handle infinite scroll with useInfiniteQuery. Use when: setting up data fetching in React projects, migrating from v4 to v5, or fixing object syntax required errors, query callbacks removed issues, cacheTime renamed to gcTime, isPending vs isLoading confusion, keepPreviousData removed problems.
document-processor-api
IncludedProcess documents with Nutrient DWS. Use when the user wants to generate PDFs from HTML or URLs, convert Office/images/PDFs, assemble or split packets, OCR scans, extract text/tables/key-value pairs, redact PII, watermark, sign, fill forms, optimize PDFs, or produce compliance outputs like PDF/A or PDF/UA. Triggers include convert to PDF, merge these PDFs, OCR this scan, extract tables, redact PII, sign this PDF, make this PDF/A, or linearize for web delivery.
nutrient-document-processing
IncludedProcess documents with Nutrient DWS. Use when the user wants to generate PDFs from HTML or URLs, convert Office/images/PDFs, assemble or split packets, OCR scans, extract text/tables/key-value pairs, redact PII, watermark, sign, fill forms, optimize PDFs, or produce compliance outputs like PDF/A or PDF/UA. Triggers include convert to PDF, merge these PDFs, OCR this scan, extract tables, redact PII, sign this PDF, make this PDF/A, or linearize for web delivery.
tanstack-query
IncludedManage server state in React with TanStack Query v5. Covers useMutationState, simplified optimistic updates, throwOnError, network mode (offline/PWA), and infiniteQueryOptions. Use when setting up data fetching, fixing v4→v5 migration errors (object syntax, gcTime, isPending, keepPreviousData), or debugging SSR/hydration issues with streaming server components.
accelint-nextjs-best-practices
IncludedNext.js performance optimization and best practices. Use when writing Next.js code (App Router or Pages Router); implementing Server Components, Server Actions, or API routes; optimizing RSC serialization, data fetching, or server-side rendering; reviewing Next.js code for performance issues; fixing authentication in Server Actions; or implementing Suspense boundaries, parallel data fetching, or request deduplication.