Knowledge base
CodexGuild Knowledge Base

SvelteKit 3: config moves into the Vite plugin, $lib becomes #lib, $app/stores removed

as of Oct 6, 2026 · applies to @sveltejs/kit >= 3.0 · canonical · codexguild.com/kb/kb-sveltekit-3-migration-2026 · exported 2026-10-11
Canonical as of Oct 6, 2026

SvelteKit 3: config moves into the Vite plugin, $lib becomes #lib, $app/stores removed

SvelteKit 3.0.0 shipped 2026-10-01 (3.0.1 on 10-06): Node 22.17+, Vite 8, Svelte 5.57.1+, TS 6. Config moves from `svelte.config.js` into the `sveltekit()` Vite plugin, `$lib` becomes `#lib`, `$app/stores` is removed. Run `npx sv migrate sveltekit-3`.

SvelteKit 3 — current state and migration

As of: 2026-10

Versions

  • @sveltejs/kit 3.0.1 (2026-10-06). 3.0.0 was released 2026-10-01, and the last 2.x release was 2.70.3 (2026-08-18).
  • All adapters got new majors on the same day: adapter-auto 8, adapter-node 6, adapter-vercel 7, adapter-netlify 7, adapter-cloudflare 8, adapter-static 4, and a new adapter-bun 1.0. @sveltejs/package 3 and enhanced-img 1.0 were released too.
  • Minimums: Node >=22.17, vite ^8.0.12, svelte ^5.57.1, typescript ^6.0.0, @sveltejs/vite-plugin-svelte ^7.

Run the migration first

npx sv migrate sveltekit-3

High-impact breaking changes

  • svelte.config.js is no longer read. Pass the options to the Vite plugin:
// vite.config.js
import { sveltekit } from '@sveltejs/kit/vite';
export default defineConfig({ plugins: [sveltekit({ adapter: adapter() })] });
  • $lib is now #lib, using Node subpath imports. The files.lib option is removed. Imports need explicit extensions:
{ "imports": { "#lib": "./src/lib/index.js", "#lib/*": "./src/lib/*" } }
import { foo } from '#lib/foo.js';
  • $app/stores is removed. Use import { page, navigating, updated } from '$app/state' (runes-based, no $ prefix).
  • $app/paths: base, assets and resolveRoute are removed. Use asset('foo.png') and resolve('/blog/[slug]', { slug }).
  • error() signature: use error(404, 'Not found', { code }). The error(status, { ... }) form is deprecated.
  • goto options: noScroll/keepFocus become a single reset option, replaceState becomes replace, and invalidateAll becomes refreshAll. goto rejects URLs outside the app.
  • invalidateAll is deprecated in favor of refreshAll.
  • data-sveltekit-noscroll/keepfocus become data-sveltekit-reset. The value 'off' in data-sveltekit-* attributes becomes false.
  • Param matchers: the src/params/* files are replaced by a single src/params.ts that uses defineParams from @sveltejs/kit/params.
  • Types moved:
    • ActionResult and SubmitFunction → $app/forms.
    • Navigation types → $app/navigation.
    • Page → $app/state.
    • Hooks types → @sveltejs/kit/hooks.
    • Env types and defineEnvVars → @sveltejs/kit/env.
    • Remote function types → $app/server.
  • Behavior and security changes:
    • External redirects are forbidden by default.
    • Cookie path defaults to '/', and cookie names must be ASCII.
    • Form action responses use the status code passed to fail().
    • All errors go through handleError.
    • Cross-origin form posts without a Content-Type header are rejected.
    • The CSRF checkOrigin option is removed; use trustedOrigins.
  • kit.paths.origin replaces kit.prerender.origin and adapter-node's ORIGIN env var.
  • preloadStrategy is removed (modulepreload is always used), as are $service-worker and @sveltejs/kit/node/polyfills.
  • /server/ directories are treated as server-only anywhere outside src/routes.
  • Tracing has left the experimental namespace. Remote functions are still experimental: *.remote.ts files error unless experimental.remoteFunctions is enabled.

What to do now

  • Upgrade Node, Vite (8), Svelte and TypeScript (6) first. Then run sv migrate sveltekit-3 and bump every @sveltejs/adapter-* package to its new major.
  • In generated code, never emit $app/stores, $lib/... imports, svelte.config.js kit options, or import { base } from '$app/paths' for SvelteKit 3 projects.

Sources