From svelte-5
Enforces Svelte code style rules: optional snippet rendering, derived state over effects, sync async wrappers, declarative events over addEventListener, slot props for Svelte 4 children. Auto-invokes on .svelte creation or edits.
npx claudepluginhub fubits1/svelte-skills --plugin svelte-5This skill uses the workspace's default tool permissions.
Use `{@render snippet?.()}` instead of `{#if snippet}{@render snippet()}{/if}`. The optional chaining form is shorter and idiomatic Svelte 5.
Mandates invoking relevant skills via tools before any response in coding sessions. Covers access, priorities, and adaptations for Claude Code, Copilot CLI, Gemini CLI.
Share bugs, ideas, or general feedback.
Use {@render snippet?.()} instead of {#if snippet}{@render snippet()}{/if}. The optional chaining form is shorter and idiomatic Svelte 5.
$effect for setting stateNEVER use $effect to set state. If you need derived state, use $derived instead. Effects that write to state create unnecessary re-renders and are a sign of wrong reactive design.
async in onMount or $effectNEVER pass an async function directly to onMount or $effect:
// BAD — cleanup function is lost, dependency tracking breaks
onMount(async () => { ... });
$effect(async () => { ... });
// GOOD — async IIFE inside a sync wrapper
onMount(() => {
(async () => { ... })();
return () => { /* cleanup */ };
});
Two reasons:
onMount and $effect expect the callback to optionally return a teardown function. An async function always returns a Promise, so the teardown never runs — intervals won't clear, subscriptions won't unsubscribe, listeners won't detach.$effect only). $effect tracks reactive dependencies that are read synchronously. Anything read after an await is invisible to the tracker and won't trigger re-runs.addEventListener / removeEventListenerNEVER use addEventListener or removeEventListener in Svelte components. Svelte 5 has multiple declarative mechanisms for event handling — on* attributes, callback props, svelte:window, svelte:document, svelte:body, and the on action from svelte/events. These handle cleanup automatically and integrate with Svelte's reactivity.
When unsure which pattern to use, invoke the Svelte MCP autofixer (mcp__svelte__svelte-autofixer) or fetch the relevant docs via mcp__svelte__get-documentation (sections: svelte-events, svelte-special-elements).
slot=, not {#snippet}TODO: verify this is still needed after sveltejs/language-tools#2716 is resolved
When a Svelte 5 (runes mode) component renders a Svelte 4 child
that uses <slot name="...">, pass content with slot="name"
attribute syntax — NOT {#snippet name()}.
<!-- GOOD — slot= works in runes mode and passes svelte-check -->
<CollapsibleCard>
<div slot="header">Header content</div>
<div slot="body">Body content</div>
</CollapsibleCard>
<!-- BAD — runtime works but svelte-check rejects it -->
<CollapsibleCard>
{#snippet header()}Header content{/snippet}
{#snippet body()}Body content{/snippet}
</CollapsibleCard>
Why: svelte-check does not resolve named snippet props on
legacy components (sveltejs/language-tools#2716,
open as of 2026-04-09). The {#snippet} approach produces
'header' does not exist in type errors. The slot= attribute
is still valid in runes-mode components and passes all checks.
When to use {#snippet}: Only when the child component is
also Svelte 5 and accepts snippet props via $props().
Events from Svelte 4 children: on:click, on:change, etc.
still work in a Svelte 5 parent. Use on: for Svelte 4 children,
onclick/callback props for Svelte 5 children.
Verified 2026-04-09 with svelte ^5.55.2, svelte-check ^4.4.6.
Svelte supports standard HTML comments in component markup. <!-- stylelint-disable -->, <!-- svelte-ignore ... -->, and other tool-control comments work in .svelte files.
@component)Every new .svelte component file MUST start with a <!-- @component --> comment block on the very first line that documents the component's purpose. This follows JSDoc conventions — the @component tag is picked up by the Svelte language server (svelte2tsx) to display documentation on hover in IDEs, similar to how /** @description */ works in JSDoc for JS/TS files.
Format:
<!--
@component
Brief description of what this component does.
Additional details if needed.
-->
The @component tag must appear inside the HTML comment. The description follows on subsequent lines, indented with a tab. Keep it concise but informative — someone reading this should understand the component's role without reading the implementation.
You can use other JSDoc tags inside the comment block where useful (e.g. @example, @see, @deprecated).
Excluded: pages, layouts, tests, and stories (.stories.svelte) do not need this comment.
frontend:code-style — General code style rules (variable naming, braces, data attributes). Applies to all code including Svelte.svelte:svelte-code-writer — Svelte 5 documentation lookup and code analysis. MUST invoke when creating or editing .svelte / .svelte.ts / .svelte.js files.svelte:svelte-core-bestpractices — Reactivity, events, styling, and integration patterns for modern Svelte.svelte-5:testing-svelte — Vitest + Playwright testing patterns for Svelte 5 components.