Svelte 5 component and state-module patterns for Epicenter apps. Use when editing `.svelte`, `.svelte.ts`, or Svelte UI state code involving runes, `$props`, snippets, keyed lifecycles, `{#await}`, TanStack Query, `SvelteMap`/`SvelteSet`, `createSubscriber`, `$state.raw`, shadcn-svelte, or workspace observers.
70
86%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
Keep the first pass focused on Svelte runes, component lifecycle, workspace-backed state, TanStack Query usage, and local UI composition.
$props, $bindable, and snippets before changing prop ownership, bind: APIs, or children snippet typing rules.{#key}, {#await}, and lifecycle hooks before changing keyed resource or async readiness guidance.{@attach}, use:, and svelte/attachments before changing reusable DOM behavior, actions, or attachment guidance.svelte/reactivity before changing SvelteMap, SvelteSet, or reactive collection guidance.createMutation and local installed types before changing mutation lifecycle guidance.When Svelte 5 runes, compiler behavior, lifecycle, reactivity, snippets, or template behavior affect correctness, use source-backed grounding before relying on memory. If DeepWiki MCP is available, ask a narrow question against sveltejs/svelte; for SvelteKit integration, ask against sveltejs/kit; for shadcn-svelte or extras component APIs, ask against huntabyte/shadcn-svelte or ieedan/shadcn-svelte-extras. If DeepWiki is unavailable or the repo is not indexed, use upstream source or official docs directly. Treat DeepWiki as orientation, then verify decisive details against local installed types, source, or official docs before changing code.
Skip DeepWiki for stable basics and repo-local patterns already documented here or in references.
query-layer: TanStack Query integrationerror-handling: $lib/report, extractErrorMessage, and component error handlingstyling: CSS and Tailwind conventions, including the flex column scroll trapui-design: visual direction plus loading, empty, pending, tooltip, and component selection patterns$state for reactive values the component mutates in place. Use $state.raw for values that are only ever reassigned wholesale (large arrays, replace-only persisted stores, opaque handles): it stores by reference with no deep proxy, does not freeze, and reacts only to reassignment, so an in-place property write mutates the object without triggering reactivity or persistence (not an error, but not reactive either). Reach for it when the deep proxy buys reactivity you never use, and when stable value identity matters (for example a store whose value is JSON-serialized or compared by reference). Exemplar: createPersistedState in packages/svelte-utils.$derived for computed state. Treat $effect as a browser-only escape hatch for DOM integration, analytics, subscriptions, and external systems. A returned cleanup runs before the effect re-runs and when the component is destroyed.$props() should usually be $derived, not one-time initialization.$bindable only for intentional two-way APIs such as UI wrappers, bind:value, bind:open, and bind:ref.{@render} over slots for new Svelte 5 code. Type exposed snippet props with Snippet from svelte; use tuple parameters such as Snippet<[Row]>.$: declarations, export let, on:click, <slot>, <svelte:component>, <svelte:self>, beforeUpdate, afterUpdate, and createEventDispatcher.onclick={...}, onkeydown={...}, and onSelect={() => ...} style props. Do not add on: directives or dispatch component events in new runes-mode code.{#key} or {#if}; open the resource synchronously in the child. Read lifecycle and reactivity.{#await} in the template instead of a $state(false) flag and a cancellation effect.function, $derived, or one-off const used once in the template). Keep one extracted only when it computes, narrows, or stabilizes something useful, or when a justifying comment plus a semantic name makes the template read better. Read component and UI patterns.satisfies Record lookup, not nested ternaries or $derived.by() switches.SvelteMap for ID-keyed collections where get, has, size, or iteration should update reactively. Values inside a SvelteMap are not deep-proxied, so store reactive row objects or replace values when nested data changes. Convert maps to stable arrays with $derived before passing them to table-like consumers.SvelteSet for an id set whose membership (has, size, iteration) is read in a reactive or template context: add/delete then drive the UI directly, replacing $state<string[]> plus spread/filter reassignment. Reach for SvelteMap instead the moment the set needs to carry per-key data (a timestamp, a last error). Use a plain Set/Map (not the reactive class) when the collection is read only in imperative code, such as a subscription's listener bag: a reactive wrapper read outside any effect is cost with no reader (exemplar: the plain listeners set in createPersistedState).update, chrome.storage, window events, an auth store) into reactivity with createSubscriber from svelte/reactivity, not a hand-rolled $state plus $effect plus listener set: reads inside an effect become reactive and the subscription is ref-counted to effect usage (start on first subscriber, cleanup at zero). Exemplars: from-kv, auth, from-table in packages/svelte-utils. Keep a manual listener set only when the same source also serves imperative .get()/.watch() consumers whose liveness cannot ride on effect ref-counting (again createPersistedState).{@attach} attachments over new use: actions. Keep use: for existing code or libraries that only expose actions..svelte files and call mutation.mutate(...) directly from template handlers unless the action earns a semantic helper. Read mutations and workspace inputs.label="Loading {name}", href="/users/{id}") instead of a JavaScript template literal attribute. Keep expression attributes for non-string values, callbacks, objects, booleans, and cases where the entire attribute is a computed JavaScript expression.Props only when a wrapper, generic relationship, exported contract, or native DOM type composition earns it. Push large view-mode branches into focused child components. Read component and UI patterns.@epicenter/ui loading, empty, pending, and tooltip components before ad hoc markup.$effect cleanup, shallow aliases, value maps, SvelteMap, table state, or .svelte.ts state modules.await, or workspace-backed text inputs.$props typing, $bindable, snippets, DOM attachments, self-contained dialogs, view branching, repetitive markup, single-use helper inlining, loading or empty states, prop-first derivation, or template text gotchas.cb12bcc
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.