name: best-practices-svelte5 description: "Use when creating, editing, reviewing, or refactoring .svelte components, .svelte.ts/.svelte.js modules, or SvelteKit applications" license: MIT metadata: author: ejirocodes version: '2.1.0'
Svelte 5 Best Practices
Workflow
Follow this sequence when working on Svelte 5 code:
- Check project version — Inspect
package.jsonfor Svelte version. If < 5, consult migration.md before writing any code. - Read relevant references — Before writing or modifying a component, read the reference file(s) matching your task from the table below.
- Write code — Apply patterns from references and the quick patterns below.
- Validate — Run the autofixer on modified components:
npx @sveltejs/mcp svelte-autofixer ./src/lib/Component.svelte
CLI Tools
npx @sveltejs/mcp list-sections # List doc sections
npx @sveltejs/mcp get-documentation "$state,$derived,$effect" # Fetch specific docs
npx @sveltejs/mcp svelte-autofixer ./path/Component.svelte # Validate component (escape $ as \$)
Reference Lookup
Read the matching file before writing code for that topic.
| Topic | When to Read | File |
|---|---|---|
| Runes | $state, $derived, $effect, $props, $bindable, $inspect | runes.md |
| Snippets | Replacing slots, {#snippet}, {@render} | snippets.md |
| Events | onclick handlers, callback props, context API | events.md |
| TypeScript | Props typing, generic components | typescript.md |
| Migration | Svelte 4→5, stores→runes, slots→snippets | migration.md |
| SvelteKit | Load functions, form actions, SSR, page typing | sveltekit.md |
| Performance | Universal reactivity, avoiding over-reactivity, streaming | performance.md |
Essential Patterns
Reactive State
<script>
let count = $state(0); // Reactive state
let doubled = $derived(count * 2); // Computed value
</script>
Component Props
<script>
let { name, count = 0 } = $props();
let { value = $bindable() } = $props(); // Two-way binding
</script>
Snippets (replacing slots)
<script>
let { children, header } = $props();
</script>
{@render header?.()}
{@render children()}
Event Handlers
<!-- Svelte 5: use onclick, not on:click -->
<button onclick={() => count++}>Click</button>
Callback Props (replacing createEventDispatcher)
<script>
let { onclick } = $props();
</script>
<button onclick={() => onclick?.({ data })}>Click</button>
Common Mistakes
letwithout$state— Variables are not reactive without$state()$effectfor derived values — Use$derivedinsteadon:clicksyntax — Useonclickin Svelte 5createEventDispatcher— Use callback props instead<slot>— Use snippets with{@render}- Missing
$bindable()— Required forbind:to work - Module-level state in SSR — Causes cross-request data leaks
- Sequential awaits in load — Use
Promise.allfor parallel requests - Mixing Svelte 4/5 patterns — Check project version first; don't mix syntaxes