Skip to content

Upgrade kit/ to Svelte 5, SvelteKit 2, Vite 7, Tailwind 4, ESLint 10 - #792

Merged
mishig25 merged 3 commits into
mainfrom
kit-svelte5-tailwind4-upgrade
Jul 3, 2026
Merged

Upgrade kit/ to Svelte 5, SvelteKit 2, Vite 7, Tailwind 4, ESLint 10#792
mishig25 merged 3 commits into
mainfrom
kit-svelte5-tailwind4-upgrade

Conversation

@mishig25

@mishig25 mishig25 commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

What

Upgrades the whole kit/ toolchain: Svelte 4 → 5.56, SvelteKit 1.20 → 2.68, Vite 4 → 7.3, Tailwind 3 → 4.1, ESLint 8 (.eslintrc) → 10 (flat config), latest Prettier plugins, svelte-check 4, mdsvex 0.12.

Highlights

svelteKitCustomClient/ is gone 🎉

The ~2,100-line fork of SvelteKit's client.js (which existed to make shorthand doc URLs like /docs/lib/page partial-load instead of full-reload) is replaced by ~40 lines of public API:

  • src/hooks.js — SvelteKit 2's reroute universal hook, expanding shorthand paths to the built library/version/lang route.
  • A capture-phase click listener in +layout.svelte that canonicalizes shorthand anchor hrefs before kit's router reads them (needed because kit's external-URL check runs before reroute for URLs outside paths.base).
  • DOCS_LIBRARY/DOCS_VERSION/DOCS_LANGUAGE are injected via Vite define instead of a generated file inside node_modules, so the custom-svelte-client npm script is gone too. No more re-porting the fork on every kit upgrade.

One visible behavior change: clicking a shorthand link now shows the canonical full URL (/docs/lib/main/en/page) in the address bar instead of keeping the shorthand. Navigation is still client-side (verified, see below).

Other adaptations

  • postprocess.js: Svelte 5 no longer emits <!-- HEAD_svelte-*_START --> markers, so the hf:doc:metadata tag is extracted directly; the moon-landing line-1 contract (line 1 = charset + metadata meta, rest = page component) is preserved, including moving the head <link> kit 2 renders inline back to line 2.
  • Tailwind 4 via @tailwindcss/postcss; app.css rewritten to v4 syntax (@utility instead of @variants, ! suffix, slash-opacity instead of --tw-bg-opacity) plus the documented v3-compat base styles. The legacy tailwind.config.cjs theme is kept via @config; plugins load via @plugin. Utility class names in markup are untouched (prod CSS is emptied and comes from the hub build).
  • Tailwind v4 auto-detects sources honoring .gitignore, which excludes src/routes (doc pages are pasted there at build time) — added @source "./routes" so doc-builder preview keeps its styles.
  • cheerio 1.x final dropped its default export → namespace import in the mdsvex preprocessor.
  • @huggingface/inference stays lock-pinned at 4.13.15: newer patches shrink the InferenceProvider type union and break InferenceSnippet.svelte; bump deliberately via npm run update-inference-providers.

Verification

Baseline accelerate e2e build (same as accelerate_doc.yml) was run on the old stack first, then compared against the upgraded build:

  • 48/48 pages: identical hf:doc:metadata, hrefs, image srcs, heading ids, code-block counts. Only diffs: Svelte 5 trims some trailing whitespace in text nodes (invisible), and Python <object object at 0x…> addresses in docstring signatures that differ between any two runs.
  • Browser smoke test (playwright + Chrome, run against both builds): hydration works, full-path links SPA-navigate, shorthand links SPA-navigate with correct content, HfOptions tabs interactive, no new console errors vs baseline.
  • svelte-check: 0 errors · prettier --check: clean · npm ci && npm run build exercised through the full doc-builder python pipeline.

Note: npx eslint . reports 39 pre-existing violations (no-shadow, no-explicit-any, non-null assertions) that the old .eslintrc also declared but never enforced in CI — left untouched here to keep the diff reviewable; happy to fix in a follow-up.

🤖 Generated with Claude Code

mishig25 and others added 3 commits July 3, 2026 21:35
- Replace the svelteKitCustomClient fork of @sveltejs/kit's client.js with
  a `reroute` universal hook (src/hooks.js) + a capture-phase click listener
  in +layout.svelte that canonicalizes shorthand doc links; DOCS_* env vars
  are now injected via Vite `define` instead of a generated hfDocConsts.js
- postprocess.js: extract the hf:doc:metadata tag directly (Svelte 5 dropped
  the HEAD_svelte-* comment markers) and keep moon-landing's line-1 contract
- Tailwind 4: @tailwindcss/postcss, v4 CSS syntax in app.css, legacy config
  kept via @config, explicit @source "./routes" (gitignored, so skipped by
  v4 source auto-detection)
- ESLint 10 flat config replacing .eslintrc.cjs/.eslintignore
- cheerio 1.x namespace import; pin @huggingface/inference to 4.13.15
  (newer patches shrink the InferenceProvider union)

Verified against a pre-upgrade baseline of the accelerate e2e build:
identical metadata/links/ids on all 48 pages, plus a browser smoke test
(hydration, SPA nav, shorthand links, HfOptions tabs) on both builds.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
`npm install ci` installs a package literally named "ci" and re-resolves
the whole tree from the network; with the upgraded dependency tree this
made npm 10 hang for 8 minutes and crash ("Exit handler never called!"),
leaving node_modules incomplete. Use `npm ci` (lockfile-only, ~20s,
verified on node:20 in docker) and enable the npm cache.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The upgraded lockfile was generated with a user-level npmrc pointing at
npm.registries.huggingface.tech, so every "resolved" URL referenced the
internal mirror. GitHub runners can't reach it — npm hung for its 5-min
fetch timeout and crashed ("Exit handler never called!"), breaking both
the lint and integration workflows. Same dependency versions, all
resolved URLs now registry.npmjs.org.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@mishig25
mishig25 merged commit c669bea into main Jul 3, 2026
5 checks passed
@mishig25
mishig25 deleted the kit-svelte5-tailwind4-upgrade branch July 3, 2026 20:47
mishig25 added a commit that referenced this pull request Jul 3, 2026
Svelte 5 raises a hard compile error (node_invalid_placement) when <tr>
is a direct child of <table>, which is a common raw-HTML idiom in doc
markdown (e.g. hub-docs transformers-js.md) and broke downstream doc
builds after #792. Wrap direct-child rows in an explicit <tbody> after
mdsvex processing — the resulting DOM is identical to what browsers
auto-inserted for the old output.

Also silence the new element_invalid_self_closing_tag warning, which
md-generated content triggers pervasively (<video ... />, <div ... />).

Verified with a full local hub-docs build (268 pages, previously failing).

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
mishig25 added a commit that referenced this pull request Jul 3, 2026
…av (#794)

After #792, clicking a shorthand doc link (/docs/lib/page) canonicalized
the address bar to the full /docs/lib/version/lang/page URL. Restore the
old svelteKitCustomClient behavior: SvelteKit still resolves the expanded
path internally (partial loading), but once the navigation completes the
history entry is rewritten back to the shorthand the user clicked. The
anchor's href is also restored right after SvelteKit reads it, and
modified clicks (cmd/ctrl/middle) are left untouched so new tabs open the
shorthand URL.

Caveat: back/forward onto a shorthand history entry falls back to a full
page load (the server serves the same page there).

Verified with a browser test on the built accelerate docs: shorthand
click SPA-navigates AND the address bar shows /docs/accelerate/quicktour.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
mishig25 added a commit that referenced this pull request Jul 3, 2026
Migrated all 110 src/ components with `migrate()` from svelte/compiler
($props/$state/$derived, event attributes, snippets), then hand-finished:

- tooltip action rewritten from the removed class API (new Component/$set/
  $destroy) to mount/unmount with reactive $state props, in a .svelte.ts
  module. This FIXES docstring parameter tooltips, which have been silently
  broken since #792 (`new Tooltip()` throws on Svelte 5 components; hover
  handlers swallowed the error). Verified against the Svelte 4 baseline.
- FrameworkContent, InferenceApi, TokenizersLanguageContent intentionally
  stay in legacy syntax: their named slots collide with same-named props,
  which snippets cannot express; mixing legacy and runes is supported.
- svelte/legacy shims (preventDefault/stopPropagation/handlers) replaced
  with plain event handlers; component prop types moved from constructor
  signatures to `Component<...>`.
- `state_referenced_locally` warnings silenced in onwarn: initial-value
  capture matches the previous Svelte 4 semantics (doc pages pass static
  props), and they'd flood every downstream doc build log.

Verified: svelte-check 0 errors; accelerate e2e output equivalent to the
Svelte 4 baseline (identical metadata/links/ids, known whitespace-only
diffs); hub-docs build (268 pages) byte-identical on all compared
dimensions vs pre-migration; browser tests pass (hydration, SPA nav,
shorthand URLs, HfOptions tabs, docstring tooltips mount/unmount).

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
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