svelte-sveltekit-best-practices
Check package.json, the lockfile, and configuration before choosing APIs. This guide targets Svelte 5 and Kit 3; retain Kit 2 APIs unless an upgrade is requested, and verify the installed Svelte version supports newer syntax.
Use stable APIs by default. Do not introduce experimental flags or prerelease packages unless requested; preserve required flags for features the project already uses.
For Kit 3 upgrades or compatibility-sensitive changes, read the relevant sections of references/sveltekit-3-migration.md. It covers dependency minimums, old-to-new API mappings, forms, error hooks, service workers, remote functions, and adapters.
Svelte 5
For reactivity bugs, effect lifecycles, state ownership, or reusable component APIs, read the relevant sections of references/svelte-5-pitfalls.md.
- Use
$statefor mutable state and$derivedfor computed values; reserve$effect/$effect.prefor side effects. Put shared reactive logic in.svelte.js/.svelte.ts; useuntrackfor reads that must not subscribe. - Destructure props with
$props(). Expose bindable values with$bindable()and consume them withbind:. - Prefer snippets (
{#snippet}/{@render}) over slots and event attributes (onclick) overon:click. ImportSnippetwhen typing snippet props. - Use
{let ...}and{const ...}for template-local declarations when supported by the installed version. - Return cleanup functions from
$effect; useonMountfor browser-only setup. - Use context for tree-scoped state and
createContextfor typed context pairs. <svelte:boundary>handles rendering/effect errors viafailed/onerrorand can reset its contents. It does not catch event-handler, timer, or detached async errors.- Sanitize untrusted
{@html}content and respect the project's Trusted Types policies.