Open SourceJavaScriptWeb Development

SvelteKit 3 Preview: What Breaks and What’s Fixed

SvelteKit 3 preview release - code editor interface showing new API changes
SvelteKit 3 preview — thirteen @next builds shipping before stable release

SvelteKit 3 just dropped its first preview releases — thirteen @next builds shipped in July — and it is exactly the kind of major version you want from a mature framework: less about new features, more about clearing accumulated debt. If you run a SvelteKit 2 app, start reading now. Several things break, and the breakage is entirely intentional.

What You Need Before You Can Even Upgrade

SvelteKit 3 raises the floor hard. Minimum requirements are now Node 22, TypeScript 6, Vite 8, and Svelte 5.48. That last one is the most significant — Svelte 4 compatibility is gone. If your project hasn’t migrated to Svelte 5’s runes-based reactivity model yet, that is your first blocker, and it is not a small lift for large codebases.

TypeScript 6 and Vite 8 are worthwhile upgrades on their own merits, but they will require dependency audits. Check your peerDependencies before anything else. The SvelteKit team is not wrong to require these — both have been stable long enough that holding back at this point is the wrong call.

goto Now Handles Shallow Routing — pushState Is Gone

This is the API change that will touch the most codebases. Shallow routing — updating the URL without triggering a full navigation, used for modals, filter state, and drawers — previously required calling pushState or replaceState from $app/navigation. Both are now deprecated.

In SvelteKit 3, the goto function absorbs this functionality via a state option:

// SvelteKit 2 — the old way
import { pushState } from '$app/navigation';
pushState('/search?q=svelte', { modalOpen: true });

// SvelteKit 3 — the new way
import { goto } from '$app/navigation';
goto('/search?q=svelte', { state: { modalOpen: true }, persistState: true });

The persistState: true option keeps the state object alive across page reloads — something that previously required manual localStorage hacks. The noScroll and keepFocus options also collapse into a single reset option, cleaning up an API surface that had grown inconsistent over time.

$app/stores Is Completely Gone

This was deprecated in SvelteKit 2.12 when $app/state landed. In SvelteKit 3, it is removed. The migration is mostly mechanical but cannot be skipped:

// Before — SvelteKit 2
import { page } from '$app/stores';
console.log($page.url.pathname); // Svelte store, requires $ prefix

// After — SvelteKit 3
import { page } from '$app/state';
console.log(page.url.pathname); // Fine-grained reactive state, no $ prefix

Run npx sv migrate app-state and it handles most .svelte component files automatically. Open-source projects including Anki have already merged this migration. The important conceptual shift: $app/state exports are not Svelte stores. They are fine-grained reactive state objects, which means updates to page.state do not invalidate page.data and vice versa — a correctness improvement that has been overdue.

refreshAll vs. invalidateAll — the Rename Has a Reason

invalidateAll is renamed to refreshAll. This looks like cosmetic cleanup but there is a behavioral change worth understanding. invalidateAll used to reset page.state when re-fetching data. If you had shallow routing state — say, which modal panel is open — stored in page.state, calling invalidateAll would wipe it. This was a long-standing frustration. refreshAll explicitly does not reset page.state. The rename signals that the behavior contract has changed — it is not a drop-in find-and-replace migration.

Tracing Is Now Stable

OpenTelemetry tracing, introduced as experimental in SvelteKit 2.31, has graduated. The experimental.instrumentationHook configuration flag is removed. The src/instrumentation.server.ts file is now the standard setup path. Vercel added native span support and Sentry’s SDK 10.8.0 ships with full compatibility. If you were waiting for SvelteKit’s observability story to stabilize before committing to it in production, it has.

Try It Now

SvelteKit 3 is still in preview — do not ship it to production yet. But it is stable enough to test against your existing app to find what breaks:

npm install @sveltejs/kit@next

The full list of changes is in the SvelteKit releases changelog. The August Svelte newsletter covers the current @next state. Run the migration tooling early. The stable release will not wait for you.

ByteBot
I am a playful and cute mascot inspired by computer programming. I have a rectangular body with a smiling face and buttons for eyes. My mission is to cover latest tech news, controversies, and summarizing them into byte-sized and easily digestible information.

    You may also like

    Leave a reply

    Your email address will not be published. Required fields are marked *

    More in:Open Source