Skip to content

chore: migrate to SvelteKit 3 - #107

Open
jis3r wants to merge 4 commits into
mainfrom
claude/sveltekit-3-migration-24e073
Open

jis3r wants to merge 4 commits into
mainfrom
claude/sveltekit-3-migration-24e073

Conversation

@jis3r

@jis3r jis3r commented Oct 2, 2026 •

Copy link
Copy Markdown
Owner

Migrates the repo to SvelteKit 3 following the release post and the migration guide. Started with npx sv migrate sveltekit-3 --tasks all, then did the manual steps and fixed what the tool got wrong.

Changes

Config

  • svelte.config.js removed. Adapter and CSP moved into sveltekit({...}) in vite.config.js. CSP directives are unchanged.
  • tsconfig.json now extends $app/tsconfig. Dropped the options the base already sets. Includes src + root files. tailwind.config.js is excluded (see notes).
  • Deleted jsconfig.json. It was a stale leftover, and the migration tool updated it instead of tsconfig.json.

Aliases -> subpath imports

  • $lib -> #lib, using the imports field in package.json.
  • $lib-docs -> #lib-docs. Kit 3 deprecates config.alias (config_option_deprecated_alias), so this alias moves to a subpath import too.
  • scripts/indexIcons.ts and its spec now emit #lib/icons/..., so npm run index won't bring back $lib.
  • components.json aliases now use #lib-docs. Bumped shadcn-svelte to 1.7, which resolves # aliases through package.json imports.
  • Published dist/ has no #lib/$lib specifiers. The library itself never used aliases.

API renames

  • $app/environment -> $app/env
  • goto(..., { replaceState: true }) -> { replace: true }
  • resolve('/icons') -> resolve('icons'). Pathnames no longer take a leading /.

Deps

  • kit 3.0, adapter-auto 8, @sveltejs/package 3, vite-plugin-svelte 7.3, svelte 5.57.1 (kit's minimum; the migration tool picked 5.56.4), svelte-check 4.7.6, typescript 6.
  • Removed the cookie: 0.7.0 override. It was a CVE patch for kit 2's cookie@^0.6. Kit 3 depends on cookie@^2, so the pin would have forced an incompatible major.
  • Added overrides.runed.@sveltejs/kit = $@sveltejs/kit. runed (via bits-ui) still declares an optional @sveltejs/kit ^2 peer. npm 10 (Node 22, used in CI) installs a nested kit 2 to satisfy it, and npm 11 doesn't, so the lockfile only stayed in sync for one of them. The override makes runed use the root kit 3. Clean npm ci now works with both npm 10 and 11.
  • Node: kit 3 needs >= 22.17. CI's node-version: 22 resolves to the latest 22.x, and release uses 24. No workflow change needed.

CSP fixes (these were already broken on main; the directives used to be copied unchanged)

  • script-src now allows https://eu-assets.i.posthog.com. posthog-js lazy-loads config, recorder, surveys, web-vitals and dead-clicks scripts from there, and all of them were blocked.
  • Added worker-src 'self' blob: data: for the session recorder's compression worker, and https://eu.posthog.com to connect-src for the toolbar.
  • mode-watcher's inline anti-flash script had no nonce, so it was blocked and the page could flash the wrong theme. SvelteKit only fills in %sveltekit.nonce% inside app.html, so the snippet now lives there (<script nonce="%sveltekit.nonce%">%modewatcher.snippet%</script>). src/hooks.server.ts fills it in through transformPageChunk, using mode-watcher's own generateSetInitialModeExpression(), and <ModeWatcher disableHeadScriptInjection /> stops the component from injecting its own copy.
  • Verified with vite preview: every <script> carries the header nonce, no placeholders leak into the HTML, light and dark mode apply before hydration, and the console shows no CSP violations.

Verification

From a clean npm ci, all CI steps pass:

  • npm run check: 0 errors / 0 warnings, no kit deprecation warnings
  • npm run lint: passes
  • npm test: 1120 passed
  • npm run check:icons: 555 conform
  • npm run package: publint "All good"
  • Generated artifacts (registry/static/r) are in sync

Two local Codex review passes; the final one returned no issues.

Smoke test with vite build + vite preview: /, /icons, and /?search=bell all work. The last one redirects to /icons?search=bell with the filter applied.

Notes / follow-ups (not in this PR)

  • tailwind.config.js is never loaded: Tailwind v4 has no @config in app.css. I excluded it from typecheck instead of editing dead code. It can probably be deleted, along with tailwindcss-animate and autoprefixer.
  • tsconfig.json doesn't typecheck scripts/. The old config didn't either, and the generator is covered by its vitest spec.
  • npm audit still lists issues in packages this PR doesn't touch (brace-expansion, undici, nanoid, ...).

Run `sv migrate sveltekit-3` and finish the manual steps from the
migration guide:

- move kit config from svelte.config.js into the sveltekit() vite plugin
- replace $lib and the deprecated $lib-docs alias with #lib / #lib-docs
  subpath imports (package.json "imports"), incl. the icons-meta generator
  and shadcn-svelte components.json (bump to 1.7 for # alias support)
- extend $app/tsconfig, drop stale jsconfig.json
- $app/environment -> $app/env, goto replaceState -> replace,
  resolve() pathnames without leading slash
- bump kit 3, adapter-auto 8, package 3, svelte 5.57.1, typescript 6
- drop cookie 0.7.0 override (kit 3 depends on cookie ^2)
@vercel

vercel Bot commented Oct 2, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
icons Ready Ready Preview Oct 5, 2026 9:29pm UTC

Request Review

npm 10 (Node 22 in CI) installs a nested @sveltejs/kit 2 to satisfy runed's optional peer, so the lockfile written by npm 11 fails npm ci. Override the peer to the root kit 3 so both npm versions resolve the same tree.
Allow PostHog's lazy-loaded scripts from eu-assets.i.posthog.com in script-src. Move mode-watcher's anti-flash snippet into app.html with %sveltekit.nonce% (filled by a hooks.server.ts transformPageChunk), since SvelteKit only substitutes the nonce placeholder in app.html and the component-injected script was being blocked.
Add worker-src 'self' blob: data: so the session recorder's compression worker is not blocked by the script-src fallback, and allow https://eu.posthog.com in connect-src for the toolbar.

This branch was successfully deployed

1 active deployment
Preview — f80a9a28 Deployed Oct 5, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant