emin@budak: ~/blog — zsh

emin@budak ~/blog % cat sveltekit-3-migration.md

SvelteKit 3 Migration: The Fast, Painful Parts

SvelteKit 3 migration workflow diagram

A SvelteKit 3 migration is mostly a cleanup job, but it is not a lazy dependency bump. The stable release keeps the framework familiar while it moves configuration, raises the toolchain floor, and removes several APIs that old projects may still have in their muscle memory.

The release arrived on October 1. The headline is modest: SvelteKit 3 is the same framework with tighter types and less leftover machinery. That description is fair. The migration guide is also long enough to make clear where the work hides. I would treat this as a planned maintenance change, not an afternoon of clicking through compiler errors.

What does a SvelteKit 3 migration actually change?

The main change is that SvelteKit configuration now belongs inside the Vite plugin in vite.config.ts, not in svelte.config.js. That is more than a file move. It puts framework configuration where Vite and related tooling can resolve it together, instead of maintaining a separate async configuration path.

The second change is the one most likely to leak across a mature codebase: $lib becomes #lib. The replacement uses Node subpath imports, which Vite and TypeScript understand directly. The catch is that imports need explicit file extensions. A project with hundreds of tidy $lib/foo imports will not be broken conceptually, but it will have plenty of mechanical edits.

The third change is the dependency floor. The official guide requires Node 22.17, TypeScript 6, Svelte 5.57.1, Vite 8.0.12, and version 7 of the Svelte Vite plugin. That makes this release partly a SvelteKit migration and partly a build environment upgrade. If a CI image or deployment host is pinned to an older Node release, start there.

Area What changes What to check first
Configuration Settings move into the SvelteKit Vite plugin Custom adapters, aliases, compiler options
Imports $lib becomes explicit #lib subpath imports Extensions, generated code, test imports
Toolchain Node 22.17, TypeScript 6, Svelte 5.57.1, Vite 8.0.12 CI image, local versions, deployment runtime
Navigation Several APIs change or are deprecated Shallow routing, refresh behavior, form actions

The project also removes old paths such as $app/stores and $service-worker, changes parts of shallow routing, and updates form behavior to match native navigation more closely. None of this reads as gratuitous. It does mean that the SvelteKit 3 migration needs a full test run, especially for apps that leaned hard on client navigation.

How should a SvelteKit 3 migration be staged?

Upgrade the existing app to the latest 2.x release first. That is the maintainers’ recommendation, and it is the sensible path because targeted deprecation warnings are cheaper than discovering every removal after the major bump. Then run the migration command with all tasks enabled and inspect its TODO output as a review queue, not as proof that the job is finished.

I would split the work into three passes. First, make the environment boring: Node, TypeScript, Svelte, Vite, and the plugin versions. Second, let the automated migration perform the repetitive edits. Third, review the changes where a codemod cannot know intent: configuration, route behavior, service workers, and deployment assumptions.

SvelteKit 3 migration checklist diagram
A SvelteKit 3 migration should separate toolchain changes, automated edits, and behavioral verification.

The final pass matters because a successful build is a weak signal. For example, goto now has different shallow-routing options, and preloadData can return an error result. A compiler will find the obvious type mismatch. It will not tell you whether a modal still preserves state after a reload or whether a cross-page enhanced form now lands somewhere users do not expect.

That is where the new default deployment checks deserve attention too. SvelteKit 3 detects fresh deployments more often, including after navigation and remote-function activity, with a one-hour polling default. That is reasonable behavior, but teams with skew protection or unusual caching should test it in an environment that resembles production.

Are remote functions ready to drive the upgrade?

No. Remote functions are interesting, but they remain experimental in SvelteKit 3. They provide typed client-server calls that execute on the server and can access server-only modules. Combined with Svelte’s experimental async support, they let components load or change data directly through generated endpoints.

The design is worth following. A remote query can be called from a component, deduplicated, refreshed, and type-checked without writing a separate endpoint wrapper by hand. It is a clearer shape for many application interactions. But the official documentation still asks developers to opt in to experimental flags and warns that the feature may change. That is not a foundation I would introduce during the same release window as a major migration unless a team has a specific experiment in mind.

Keep the concerns separate. A SvelteKit 3 migration buys a maintained framework baseline and cleaner boundaries. Remote functions are a later product decision. Mixing them makes a regression harder to explain and a rollback harder to make.

Who should move to SvelteKit 3 now?

New projects should start on SvelteKit 3. The supported baseline is clear, the configuration model is simpler, and there is no reason to begin a codebase on a branch that now carries migration debt.

Existing applications should move soon if their runtime can run Node 22.17 and their test suite covers routes, form actions, service workers, and deployment behavior. The release announcement says migration support can automate much of the codebase and leave a TODO list for the rest. That is a good deal, provided the TODO list receives actual review.

Teams without that coverage should prepare before they upgrade. Inventory $lib imports, record the current deployment and caching behavior, and add tests around the pages that use shallow routing or enhanced forms. The official migration guide is the checklist, while the release announcement explains the intended direction. The release notes are useful for the detailed breaking-change trail.

SvelteKit 3 does not ask developers to relearn the framework. It asks them to remove the bits that made the old version harder to reason about. That is still work. It is the useful kind.