svelte
Svelte
Work from current Svelte 5 idioms. Optimize for components and reactive state that stay easy to reason about as they grow.
Do not spend time explaining basic syntax unless the user asks. Focus on best practices, sharp edges, and the shortest correct implementation.
Scope
Use this skill when the problem is mostly inside components or shared reactive view logic.
- Reach for this skill for runes, props, snippets, component APIs, context, styling, local state, shared client-side reactive objects, and reactivity debugging.
- If the hard part is route boundaries,
load, form actions, auth, cookies, SSR navigation behavior, or invalidation, switch to thesveltekitskill.
Workflow
- Establish the local style before changing code.
- Inspect nearby components, shared UI primitives, and
package.json. - Prefer the repo's current conventions in touched files unless the task is an explicit migration.
- For new code, default to runes mode and current event syntax.
- Choose the ownership boundary before writing code.
- Decide whether truth should live in props, component state, context, or a shared reactive module.
- Keep leaf components presentational when possible.
- Move persistence, networking, and app orchestration out of leaf UI components.
- Model data flow before polishing markup.
- Prefer deriving state over synchronizing copies of state.
- Treat props as live inputs, not initialization values.
- Add effects only for real side effects outside Svelte.
- Keep SSR compatibility in mind even at component level.
- Components in SvelteKit may render on the server first.
- Avoid browser-only assumptions during render.
- Prefer stable markup that can hydrate without surprises.
Core Svelte Patterns
- Use runes-first patterns in new code:
$state,$derived,$props, snippets, and current event attributes such asonclick={...}. - Use
$stateonly for values that truly need reactivity. Keep plain variables plain. - Prefer
$state.rawfor large objects or arrays that are usually replaced wholesale rather than mutated in place. - Prefer
$derivedfor computed values. Use$derived.by(...)when the derivation needs multiple statements. - Remember that objects or arrays returned from
$derivedare not made deeply reactive. - Treat
$effectas an escape hatch for DOM APIs, timers, analytics, imperative libraries, or external subscriptions. - Do not use
$effectto keep one piece of state in sync with another when a clearer source of truth exists. - Prefer event handlers, function bindings,
{@attach ...}, orcreateSubscriber(...)before reaching for an effect. - Use
$inspectand$inspect.trace(...)to debug reactive churn instead of leaving logging effects in place. - Treat props as live values. Derive from them instead of snapshotting them into local variables that silently drift.
- Avoid copying props into mutable local state unless the component intentionally forks from the parent value.
- Prefer snippets and explicit children rendering over legacy slot patterns in new code.
- Top-level snippets can also be referenced from
<script>when that is clearer than creating a tiny helper component. - Use
<svelte:window>and<svelte:document>for global listeners instead of wiring them up manually inonMountor$effect. - Prefer keyed
{#each}blocks for stable identity. Do not use array index as the key. - Avoid destructuring each-block items when the template mutates them.
- Prefer CSS custom properties and
style:--token={value}for JS-to-CSS handoff and parent-controlled styling. - Reach for
:global(...)only when styling third-party output or a boundary you do not control. - Prefer
createContextover ad hocsetContext/getContextpairs when context is the right tool. - Do not default to stores for local sharing. In Svelte 5, a reactive object or class with
$statefields is often simpler. - Keep stores for cases where the store contract matters: async streams, external subscriptions, or ecosystem integrations.
Component Design Best Practices
- Keep presentational components narrow: props in, callbacks out, minimal ownership of app state.
- Prefer explicit props and callback props over "smart" components with many optional behaviors.
- In new Svelte 5-style code, prefer callback props over
createEventDispatcher. - Prefer a few well-named props over catch-all config objects unless the object is a real domain shape.
- When a component exposes many booleans or variant combinations, split it or redesign the API around clearer modes.
- Keep render helpers close when they are tiny; extract components only when they create a real boundary.
- Put async loading, auth checks, and persistence in higher-level modules rather than leaf UI components.
Common Gotchas
- Component setup runs once. If a value should update when props or state change, make it reactive with
$derivedinstead of computing it once in plain script. - Do not use
$effectto mirror state. If you writexfromyin an effect, you probably want a derived value or a different source of truth. - Passing a primitive from
$state(...)to a function passes the current value, not a live reference. Pass an updater or a container object when mutation must flow back. - Reactive churn often comes from depending on a whole object when only one stable field matters. Extract the stable field into its own
$derivedbefore building downstream derived state. - Deeply reactive
$stateis convenient, but proxying large graphs has a cost. Prefer smaller state shapes or$state.rawwhen mutation granularity is not needed. - Mutating a property on an object returned from
$derivedaffects the original object only if that original object is already reactive upstream. Do not assume$deriveddeepens reactivity. - Browser-only APIs such as
window,document, storage, observers, and media APIs must be guarded behindonMountor an explicit browser check when SSR is in play.
Review Heuristics
- Remove unnecessary effects before trying micro-optimizations.
- Prefer derived values close to their source over wide mutable state that forces synchronization.
- Watch for components that both orchestrate data flow and render complex UI; split responsibilities before the file turns into a control tower.
- Watch for props copied into state, boolean-heavy APIs, and styling approaches that force parent components to reach through implementation details.
- When debugging reruns, ask what the smallest real dependency is rather than subscribing to a whole object graph.
Debugging Checklist
- If UI is stale, verify the value is
$stateor$derivedrather than a one-time plain variable. - If updates are looping or hard to follow, remove syncing effects and re-establish one source of truth.
- If something reruns more often than expected, add
$inspect.trace(...)to the relevant$derived.by(...)or$effect. - If child state drifts from parent props, stop snapshotting props into local mutable variables.
- If shared reactive state resets or recreates too often, check whether downstream logic depends on an unstable object instead of a stable field.
- If hydration fails, compare SSR markup with browser-only branches, time/randomness, and locale-sensitive formatting.
Migration and Compatibility
- For existing pre-runes code, do not churn files into modern syntax unless the task is migration or the touched code becomes materially clearer.
- When touching legacy code, prefer local consistency plus small targeted improvements over mixing paradigms inside one file.
- Prefer modern replacements in new code: runes over
$:andexport let, snippets over slots, current event attributes overon:click, direct component references over<svelte:component>, and reactive classes or objects over stores when sharing local reactive state. - Use promise-in-template features such as await expressions only when the project is on a compatible Svelte version and has the relevant experimental option enabled.
Official References
Consult the current Svelte docs when behavior matters or seems version-sensitive:
https://svelte.dev/docs/svelte/best-practiceshttps://svelte.dev/docs/svelte/$statehttps://svelte.dev/docs/svelte/$derivedhttps://svelte.dev/docs/svelte/$effecthttps://svelte.dev/docs/svelte/$props
More from sjunepark/custom-skills
summarize
Use the steipete/summarize CLI to summarize URLs, local files, stdin, YouTube links, podcasts, and media with LLM models. Trigger when users ask to install or run summarize, configure model/provider API keys, tune output flags (length/language/json/extract/slides), set defaults in ~/.summarize/config.json, or troubleshoot summarize CLI errors.
41skills-cli
Operate the skills CLI to discover, install, list, update, remove, and initialize skills for Codex, Claude Code, and Pi. Use when users ask to manage skills from skills.sh, restore from lock files, sync skills from node_modules, or troubleshoot agent/installation scope (project vs global).
37post-implementation-review
Manually review already-implemented code for design flaws, abstraction issues, structural problems, or refactors that only became clear in real code. Use only when the user explicitly asks for a post-implementation review, explicitly asks whether recent implementation work revealed design or structure problems, or explicitly wants refactor recommendations after the code exists. Do not auto-trigger for ordinary implementation, debugging, explanation, or generic code review requests. Prefer embedded snippets with file-path comments over editor-oriented file and line references. Treat findings as signals about code shape and quality; prioritize root-cause design, ownership, abstraction, and organization improvements, including broad refactors when warranted, over bandage fixes such as tiny helper extractions or local polish.
30architecture-md-writer
Create, update, review, and split ARCHITECTURE.md files that explain a codebase's shape, major components, runtime flow, code map, and important invariants. Use when a repository lacks architecture docs, an existing ARCHITECTURE.md is stale or too detailed, a subsystem needs its own nested ARCHITECTURE.md, or a root architecture doc should link to deeper module architecture docs.
27agents-md-writer
Create, edit, review, and improve AGENTS.md files for repositories used by agentic coding tools with concise, actionable instructions and correct precedence behavior. Use whenever AGENTS.md content is being changed, including updating existing guidance, drafting a new AGENTS.md, migrating legacy instruction files, defining nested overrides in monorepos, or debugging why tools load the wrong guidance.
26source-investigator
Investigate external libraries, frameworks, and unfamiliar repositories by cloning the exact repo into a project-local temp workspace, ignoring that workspace in git, and delegating code reading to focused subagents so the main thread stays clean. Use whenever docs are incomplete, version-specific behavior matters, you need to learn how a codebase works, or exploring lots of source inline would pollute the main context.
24