| name | svelte |
| description | Svelte 5 and SvelteKit documentation lookup and code analysis. Use when writing or debugging Svelte components. |
Svelte
Svelte 5 and SvelteKit documentation and code analysis via the official Svelte MCP server, exposed as simple CLI tools.
When to Use
- Before writing Svelte code: fetch relevant docs with
svelte-docs.js
- After writing Svelte code: validate with
svelte-fix.js
- When unsure about Svelte 5 syntax (runes, snippets, etc.)
- When working with SvelteKit routing, load functions, or hooks
List Documentation Sections
/home/jacob/code/living-dictionaries/.claude/skills/svelte/svelte-docs.js --list
Lists all available Svelte 5 and SvelteKit documentation sections with use_cases and paths. Use this FIRST to discover what documentation is available, then fetch the relevant sections.
Get Documentation
/home/jacob/code/living-dictionaries/.claude/skills/svelte/svelte-docs.js "$state"
/home/jacob/code/living-dictionaries/.claude/skills/svelte/svelte-docs.js routing
/home/jacob/code/living-dictionaries/.claude/skills/svelte/svelte-docs.js "$state" "load functions" routing
/home/jacob/code/living-dictionaries/.claude/skills/svelte/svelte-docs.js cli/overview
Fetches full documentation for one or more sections. Accepts titles (e.g., "$state", "routing") or file paths (e.g., "cli/overview"). Pass multiple section names to fetch them all at once.
Analyze Svelte Code
/home/jacob/code/living-dictionaries/.claude/skills/svelte/svelte-fix.js site/src/lib/export/Progress.svelte
Analyzes a Svelte component file and returns issues and suggestions. Always use this after writing Svelte code to catch problems.
Svelte Core Best Practices
$state
Only use the $state rune for variables that should be reactive — in other words, variables that cause an $effect, $derived or template expression to update. Everything else can be a normal variable.
Objects and arrays ($state({...}) or $state([...])) are made deeply reactive, meaning mutation will trigger updates. This has a trade-off: in exchange for fine-grained reactivity, the objects must be proxied, which has performance overhead. In cases where you're dealing with large objects that are only ever reassigned (rather than mutated), use $state.raw instead. This is often the case with API responses, for example.
$derived
To compute something from state, use $derived rather than $effect:
let square = $derived(num * num);
let square;
$effect(() => {
square = num * num;
});
[!NOTE] $derived is given an expression, not a function. If you need to use a function (because the expression is complex, for example) use $derived.by.
Deriveds are writable — you can assign to them, just like $state, except that they will re-evaluate when their expression changes.
If the derived expression is an object or array, it will be returned as-is — it is not made deeply reactive. You can, however, use $state inside $derived.by in the rare cases that you need this.
$effect
Effects are an escape hatch and should mostly be avoided. In particular, avoid updating state inside effects.
- If you need to sync state to an external library such as D3, it is often neater to use
{@attach ...}
- If you need to run some code in response to user interaction, put the code directly in an event handler or use a function binding as appropriate
- If you need to log values for debugging purposes, use
$inspect
- If you need to observe something external to Svelte, use
createSubscriber
Never wrap the contents of an effect in if (browser) {...} or similar — effects do not run on the server.
$props
In SvelteKit +page.svelte and +layout.svelte files, don't manually type page props — they're automatically typed by SvelteKit. Just use let { data } = $props() without a type annotation.
Treat props as though they will change. For example, values that depend on props should usually use $derived:
let { type } = $props();
let color = $derived(type === 'danger' ? 'red' : 'green');
let color = type === 'danger' ? 'red' : 'green';
$inspect.trace
$inspect.trace is a debugging tool for reactivity. If something is not updating properly or running more than it should you can add $inspect.trace(label) as the first line of an $effect or $derived.by (or any function they call) to trace their dependencies and discover which one triggered an update.
Events
Any element attribute starting with on is treated as an event listener:
<button onclick={() => {...}}>click me</button>
<!-- attribute shorthand also works -->
<button {onclick}>...</button>
<!-- so do spread attributes -->
<button {...props}>...</button>
If you need to attach listeners to window or document you can use <svelte:window> and <svelte:document>:
<svelte:window onkeydown={...} />
<svelte:document onvisibilitychange={...} />
Avoid using onMount or $effect for this.
Snippets
Snippets are a way to define reusable chunks of markup that can be instantiated with the {@render ...} tag, or passed to components as props. They must be declared within the template.
{#snippet greeting(name)}
<p>hello {name}!</p>
{/snippet}
{@render greeting('world')}
[!NOTE] Snippets declared at the top level of a component (i.e. not inside elements or blocks) can be referenced inside <script>. A snippet that doesn't reference component state is also available in a <script module>, in which case it can be exported for use by other components.
Each blocks
Prefer to use keyed each blocks — this improves performance by allowing Svelte to surgically insert or remove items rather than updating the DOM belonging to existing items.
[!NOTE] The key must uniquely identify the object. Do not use the index as a key.
Avoid destructuring if you need to mutate the item (with something like bind:value={item.count}, for example).
Using JavaScript variables in CSS
If you have a JS variable that you want to use inside CSS you can set a CSS custom property with the style: directive.
<div style:--columns={columns}>...</div>
You can then reference var(--columns) inside the component's <style>.
Context
Consider using context instead of declaring state in a shared module. This will scope the state to the part of the app that needs it, and eliminate the possibility of it leaking between users when server-side rendering.
Use createContext rather than setContext and getContext, as it provides type safety.