Skip to content

Move the client to SvelteKit 3 - #321

Merged
Serraniel merged 2 commits into
mainfrom
build/sveltekit-3
Oct 21, 2026
Merged

Serraniel merged 2 commits into
mainfrom
build/sveltekit-3

Conversation

@Serraniel

Copy link
Copy Markdown
Owner

Replaces #316 and #317, which could not pass individually and were not two
problems.

The red CI was one install, counted three times

@sveltejs/adapter-static 3 requires @sveltejs/kit ^2, and version 4
requires ^3. Dependabot opened one pull request for each half:

kit adapter-static what npm ci said
#316 3.1.0 3.0.10 adapter-static wants kit ^2.0.0
#317 2.70.3 4.0.0 adapter-static wants kit ^3.0.0-next.0

Both died in npm ci before a single test ran, which is why Unit tests,
Cross-language crypto vectors and Playwright flows were all red on both:
three jobs reporting the same install. Neither pull request could ever have
gone green, and no amount of rebasing would have changed that.

Four breaking changes

svelte.config.js is no longer read. Its contents move into the
sveltekit() plugin in vite.config.ts, and the kit nesting disappears with
it — every option sat one level deeper before. The comments move with their
options, including the account of #260, which is why the version name is the
commit and not a timestamp.

The generated tsconfig is a virtual module now, $app/tsconfig. It no
longer writes into .svelte-kit, no longer supplies include/exclude, and
no longer survives an overridden types array, so all three are stated in
tsconfig.json.

$lib is removed. SvelteKit offers alias: { '$lib': 'src/lib' } to keep
it working, but that option is itself deprecated and slated for removal, so
taking it would only move this same work to the next major. This migrates to
the #lib subpath imports it points at instead — 46 specifiers across 16
files.

cookie had to stop being overridden. The entry existed because kit 2
asked for ^0.6.0, below the release that fixed a name-parsing flaw. Kit 3
asks for ^2.0.1, so it had nothing left to do — and it had become actively
harmful, pinning cookie back to a CommonJS 0.7.2 that lacks the named exports
kit 3 imports. The build failed on parseCookie until it was gone.
npm ls cookie now resolves to 2.0.1 unaided and npm audit reports nothing.
docs/workflows/dependabot.md set the condition for dropping it, and that is
the condition that was met.

The specifiers carry file extensions, because the tools disagree

"#lib/*": "./src/lib/*" is an exact mapping — Node subpath imports add no
extensions. The obvious fix is a fallback list, and it does satisfy TypeScript:

"#lib/*": ["./src/lib/*.ts", "./src/lib/*.svelte", "./src/lib/*"]

svelte-check went to 0 errors on that, and then the build failed, because
Rolldown takes only the first entry and never reaches the second:

Rolldown failed to resolve import "#lib/BrowserCheck.svelte"

Two tools reading one declaration differently is not something to ship, so the
extension is written at each import site and the mapping stays single and
exact. CONTRIBUTING.md records it, because #lib/protection looks correct
and resolves to nothing.

So it does not happen again

.github/dependabot.yml gains a sveltekit group covering the whole peer ring
across every update type, majors included. The configuration already had this
shape for vitest, added when @vitest/coverage-v8 did the same thing in #99;
this is that reasoning applied to the set that just demonstrated it needs it.
vite is in the group because kit declares it as a peer with a major range, so
a vite major on its own fails identically.

docs/workflows/dependabot.md was missing the general case entirely — it
explained which dependencies are kept out of groups and said nothing about
the ones forced into them. It now also records the symptom, since a wall of
ERESOLVE is not a breaking change and reading the upstream changelog first
costs an afternoon.

One warning is accepted, not silenced

svelte-kit sync prints tsconfig_invalid, asking for the service worker to
leave this type-check program. It is already excluded as an entry point — but
src/service-worker.test.ts imports it, and exclude only limits the root
set, so it comes back. tsc --listFiles shows both files.

Silencing it means excluding the test too, and then nothing type-checks the
file that answers download requests. That is the worse trade, so the warning
stays and tsconfig.json says why. #320 has the fix worth making — the worker
needs its own project with lib: ["ESNext", "WebWorker"], which touches
check, verify.sh and the CI job, so it is not folded in here. Note that
SvelteKit 2 behaved the same way; the only new thing is that it now mentions
it.

Verified

svelte-check 0 errors over 416 files · 572 unit tests · biome · vite build
· npm ci · notices · toolchains · workflows · asset audit · go build ·
go vet · go test · golangci-lint 0 issues.

Coverage floors for internal/store and internal/blob fall short locally
because SENDAN_TEST_POSTGRES and SENDAN_TEST_S3 are unset here; the script
says so itself, and neither package is touched.

I also built a kit 2 baseline from origin/main in a worktree to compare
against, because the new index.html references /_app/… absolutely and the
config asks for paths: { relative: true }. The baseline does exactly the same
— 9 absolute references against 11 — so that is how the SPA fallback has always
been emitted and not something this introduced. Same top-level files, same 7
stylesheets.

⚠️ Playwright was not run locally. The browser download would not complete
on this machine, so CI is what confirms the three browser projects. Everything
else above ran here.

Closes #316
Closes #317

🤖 Generated with Claude Code

Serraniel and others added 2 commits October 21, 2026 20:51
Dependabot opened these as #316 and #317, and neither could ever go green:
adapter-static 3 requires kit ^2, adapter-static 4 requires kit ^3, so each
pull request held one half of a pair and `npm ci` failed on the peer conflict
before a single test ran. The three red checks on both were the same install
failing three times. They land together or not at all.

Four breaking changes and one override had to be dealt with.

`svelte.config.js` is no longer read. Its contents move into the `sveltekit()`
plugin in vite.config.ts, and the `kit` nesting is gone with it - every option
sat one level deeper before. The comments move with the options, including the
account of #260, which is the reason the version name is the commit.

The generated tsconfig is now a virtual module, `$app/tsconfig`, and no longer
supplies include/exclude or carries `$app/types` into an overridden `types`
array, so all three are stated in tsconfig.json.

`$lib` is removed. SvelteKit offers `alias: { '$lib': 'src/lib' }` to keep it,
but that option is itself deprecated and will be removed, so this moves to the
`#lib` subpath imports it points at instead - 46 specifiers across 16 files.

The specifiers carry file extensions because the tools disagree about inferring
them. A fallback list of candidate extensions satisfies TypeScript, and
Rolldown takes only the first entry and fails the build on the first `.svelte`
import it meets. One exact path is read the same way by both; CONTRIBUTING.md
records it, because `#lib/protection` looks right and resolves to nothing.

The `cookie` override is removed. It existed because kit 2 asked for `^0.6.0`,
below the version that fixed a name-parsing flaw. Kit 3 asks for `^2.0.1`, so
the entry had nothing left to do - and it had turned harmful, pinning cookie
back to a CommonJS 0.7.2 without the named exports kit 3 imports, which failed
the build on `parseCookie`. `npm ls cookie` now resolves to 2.0.1 unaided and
npm audit reports nothing. docs/workflows/dependabot.md set the condition for
dropping it and that condition is the one that was met.

One warning is accepted rather than silenced. SvelteKit wants the service
worker out of this type-check program, and it is already excluded as an entry
point - but its test imports it, and exclude only limits the root set, so it
comes back. Silencing it means excluding the test too, and then nothing
type-checks the file that answers download requests. #320 has the fix worth
making, which needs its own tsconfig and a change to three gates.

Verified: svelte-check 0 errors over 416 files, 572 unit tests, biome, vite
build, npm ci, notices, toolchains, workflows, asset audit, go build, go vet,
go test, golangci-lint. The built output matches a kit 2 baseline built from
origin/main in a worktree - same files, same absolute /_app references, which
the SPA fallback has always emitted. Playwright was not run locally; the
browser download would not complete here, so CI is what confirms it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: Serraniel <mail@serraniel.dev>
…gether

#316 and #317 were a kit 3 bump and an adapter-static 4 bump in separate pull
requests. adapter-static 4 requires kit ^3 and adapter-static 3 requires kit
^2, so each one failed npm ci on the other's peer range and neither could ever
pass. The three red checks on each were one install failing three times.

The configuration already had this shape for vitest, added when the same thing
happened to @vitest/coverage-v8 in #99, so this is that group's reasoning
applied to the set that just demonstrated it needs it. vite is included because
kit declares it as a peer with a major range, so a vite major alone fails
identically.

docs/workflows/dependabot.md gains the general case, which it was missing: it
documented the dependencies deliberately kept out of groups and said nothing
about the ones deliberately forced into them, so the only record was a comment
in the configuration. It also records the symptom, because a wall of ERESOLVE
is not a breaking change and reading the upstream changelog first wastes the
afternoon.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: Serraniel <mail@serraniel.dev>
@Serraniel
Serraniel merged commit 14876a4 into main Oct 21, 2026
15 checks passed
@Serraniel
Serraniel deleted the build/sveltekit-3 branch October 21, 2026 19:05
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