svelte5
Svelte 5 Syntax
Always use Svelte 5 runes. Never use Svelte 4 patterns.
Svelte 4 → Svelte 5
| Svelte 4 ❌ | Svelte 5 ✅ |
|---|---|
export let foo |
let { foo } = $props() |
export let foo = 'default' |
let { foo = 'default' } = $props() |
$: doubled = x * 2 |
let doubled = $derived(x * 2) |
$: { sideEffect() } |
$effect(() => { sideEffect() }) |
on:click={handler} |
onclick={handler} |
on:input={handler} |
oninput={handler} |
on:click|preventDefault={h} |
onclick={e => { e.preventDefault(); h(e) }} |
<slot /> |
{@render children()} |
<slot name="x" /> |
{@render x?.()} |
$$props |
Use $props() with rest: let { ...rest } = $props() |
$$restProps |
let { known, ...rest } = $props() |
createEventDispatcher() |
Pass callback props: let { onchange } = $props() |
Stores → Runes
| Svelte 4 ❌ | Svelte 5 ✅ |
|---|---|
import { writable } from 'svelte/store' |
Remove import |
const count = writable(0) |
let count = $state(0) |
$count (auto-subscribe) |
count (direct access) |
count.set(1) |
count = 1 |
count.update(n => n + 1) |
count += 1 |
Quick Reference
<script>
// Props (with defaults and rest)
let { required, optional = 'default', ...rest } = $props();
// Two-way bindable prop
let { value = $bindable() } = $props();
// Reactive state
let count = $state(0);
let items = $state([]); // arrays are deeply reactive
let user = $state({ name: '' }); // objects too
// Derived values
let doubled = $derived(count * 2);
let complex = $derived.by(() => {
// multi-line logic here
return expensiveCalc(count);
});
// Side effects
$effect(() => {
console.log(count);
return () => cleanup(); // optional cleanup
});
</script>
<!-- Events: native names, no colon -->
<button onclick={() => count++}>Click</button>
<input oninput={e => value = e.target.value} />
<!-- Render snippets (replaces slots) -->
{@render children?.()}
Snippets (Replace Slots)
<!-- Parent passes snippets -->
<Dialog>
{#snippet header()}
<h1>Title</h1>
{/snippet}
{#snippet footer(close)}
<button onclick={close}>Done</button>
{/snippet}
</Dialog>
<!-- Child renders them -->
<script>
let { header, footer, children } = $props();
</script>
{@render header?.()}
{@render children?.()}
{@render footer?.(() => open = false)}
References
Load these when needed:
- references/typescript.md — Typing props, state, derived, snippets, events, context
- references/patterns.md — Context API, controlled inputs, forwarding props, async data, debouncing
- references/gotchas.md — Reactivity edge cases, effect pitfalls, binding quirks
More from trevors/dot-claude
jj-workflow
Jujutsu (jj) version control, load skill when hook output shows vcs=jj-colocated or vcs=jj in the system-reminder.
93notion-formatter
Format markdown content for Notion import with proper syntax for toggles, code blocks, and tables. Use when formatting responses for Notion, creating Notion-compatible documentation, or preparing markdown for Notion paste/import.
47book-reader
Read and search digital books (PDF, EPUB, MOBI, TXT). Use when answering questions about a book, finding quotes or passages, navigating to specific pages or chapters, or extracting information from documents.
44using-jj
Advanced jj/jujutsu workflows — revsets, absorb, evolog, op restore/undo, immutable_heads bypass, divergent-change resolution, jj split, parallel jj new, conflict-after-rebase, force-push recovery. Contains non-obvious rules (e.g., always `-m` to avoid editor) that prevent broken workflows. Skip for simple commit/push/rebase.
43maintaining-claude-code
Create, validate, and improve Claude Code configuration — SKILL.md files, CLAUDE.md, rules, hooks, and settings.json. Use when creating a new skill, writing a SKILL.md, adding a hook, editing rules, auditing skill descriptions, checking config quality, debugging hook behavior, or deciding between skills vs rules vs CLAUDE.md. Also auto-loads when working in ~/.claude/ on skills, rules, hooks, or settings.
32glhf
>-
28