Published Build3 min read
SvelteKit 3 hits RC with breaking changes: run the codemod now, not after stable
The Svelte team says stable will follow the release candidate with no further breaking changes. That makes the RC window the cheapest time to move a SvelteKit 2 app, not the riskiest.
Written for builders.See today for builders

What happened
- SvelteKit 3 is now in the Release Candidate phase.
- The SvelteKit team says that if people try out the RC and find it works as expected, they will follow it with a stable release in the near future, with no further breaking changes.
- There are breaking changes in SvelteKit 3 relative to SvelteKit 2; the team says it is using the release to prune the codebase and lay groundwork for future evolution.
- Existing apps can be migrated with the next version of sv migrate: npx sv@next migrate sveltekit-3 --tasks all --confirm
- The migration tool automatically migrates as much code as possible and generates a TODO list for everything else.
Compiled by The EngineerSomething wrong?How this is made
Why it matters
SvelteKit 3 has entered its release candidate phase, and it carries real breaking changes relative to SvelteKit 2 [1][3]. The team says that if people try the RC and it works as expected, a stable release will follow with no further breaking changes [2], which is the whole scheduling argument: work you do now against the RC should not need redoing against the tag.
The migration path is a codemod. `npx sv@next migrate sveltekit-3 --tasks all --confirm` converts as much of an existing app as it can and emits a TODO list for the rest [4][5]. For code that has not been updated, SvelteKit says it will print diagnostic warnings and errors at runtime wherever possible [6]. New projects use `npx sv@next create` [7], and the SvelteKit 3 documentation and full migration guide live on next.svelte.dev until the stable release [8]. Read that: the docs are not on the main site yet, so treat anything you find on svelte.dev as SvelteKit 2 until it moves.
Four file-level surfaces are touched [24], which is what makes this a scheduled task rather than an afternoon.
Configuration no longer goes through `svelte.config.js` [9]. The stated reason is that the Vite plugin benefits from having the config immediately rather than through an asynchronous resolution process, which cannot begin until the entire Vite config is resolved, because tools like Vitest may run with a working directory that is not the project root [10]. The post argues for config in one place rather than two but the excerpt does not name the destination file.
The `$lib` alias is replaced by Node subpath imports, which Vite and TypeScript support natively and which let SvelteKit delete the code that coordinated aliases between the two [11][12]. The gotcha is specifier precision: Node and TypeScript require unambiguous subpaths, so `#lib/foo` becomes `#lib/foo.ts` or `#lib/foo/index.ts` [13]. In a large codebase, that is the change most likely to leave residue after the codemod.
`tsconfig.json` now extends `$app/tsconfig` instead of `./.svelte-kit/tsconfig.json`, with the generated file written to `node_modules/$app` [14][15]. It no longer needs the `$lib` alias in `paths` and ships more recommended compiler options, so most projects can delete their own `compilerOptions` [16]. You are expected to specify `include` and `exclude` explicitly, and `exclude` should cover your service worker [17].
Service workers drop the `$service-worker` module in favour of imports from `$app/env`, `$app/paths` and a new `$app/manifest` [18]. Importing `self` from `$app/service-worker` gives typed fetch events, provided you add a `tsconfig.json` next to the worker that extends `$app/tsconfig/service-worker` [19]. The team says caching-strategy helpers may come later [20], which means offline behaviour is still hand-rolled for now.
The one addition rather than subtraction: explicit environment variables leave the experimental flag [21]. You declare dependencies in `src/env.ts`, marking each as public or not and as resolved at build time or at boot [22], and you can validate them with Standard Schema libraries [23]. Build-time resolution is what enables dead code elimination [22], so the declaration is not paperwork.
What to watch: whether stable actually arrives with no further breaking changes, since that promise is conditional on RC feedback [2]; how much of your subpath-import fallout the codemod leaves behind [13]; and whether the caching helpers materialise before you commit to a hand-written service worker [20].
Claim ledger
Ranked by verification strength, evidence, and original report placement.
- [1]
SvelteKit 3 is now in the Release Candidate phase.
- [2]
The SvelteKit team says that if people try out the RC and find it works as expected, they will follow it with a stable release in the near future, with no further breaking changes.
- [3]
There are breaking changes in SvelteKit 3 relative to SvelteKit 2; the team says it is using the release to prune the codebase and lay groundwork for future evolution.
- [4]
Existing apps can be migrated with the next version of sv migrate: npx sv@next migrate sveltekit-3 --tasks all --confirm
ReportedView cited source - [5]
The migration tool automatically migrates as much code as possible and generates a TODO list for everything else.
ReportedView cited source - [6]
Wherever possible, SvelteKit will print useful diagnostic warnings and errors if you run code that has not yet been updated.
ReportedView cited source
Sources & coverage · 1 publisher
The reporting this story was synthesized from, earliest first. Every link goes to the original.
- svelte.devThe Svelte teamAug 12The SvelteKit 3 Release Candidate is here
Cited in this coverage: svelte.dev blog

