| 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.json for 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
npx @sveltejs/mcp get-documentation "$state,$derived,$effect"
npx @sveltejs/mcp svelte-autofixer ./path/Component.svelte
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
let without $state — Variables are not reactive without $state()
$effect for derived values — Use $derived instead
on:click syntax — Use onclick in Svelte 5
createEventDispatcher — Use callback props instead
<slot> — Use snippets with {@render}
- Missing
$bindable() — Required for bind: to work
- Module-level state in SSR — Causes cross-request data leaks
- Sequential awaits in load — Use
Promise.all for parallel requests
- Mixing Svelte 4/5 patterns — Check project version first; don't mix syntaxes