Skip to content

Use bun as the kit package manager and script runner - #799

Closed
mishig25 wants to merge 3 commits into
mainfrom
migrate-to-bun
Closed

Use bun as the kit package manager and script runner#799
mishig25 wants to merge 3 commits into
mainfrom
migrate-to-bun

Conversation

@mishig25

@mishig25 mishig25 commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

What

Switches the kit toolchain from npm to bun for installing dependencies and running package scripts, across local commands (doc-builder build --html, doc-builder preview) and all CI workflows.

What bun is (and isn't) here: bun replaces npm (installs, ~20s → <1s warm / ~5s cold) and the script runner. It does not replace ESLint/Prettier — bun ships no linter/formatter (that would be Biome, which still has partial Svelte support and no tailwind class sorting, so it's not a good trade here). And Vite itself still runs on Node.js (≥ 20): bun is the installer/runner, node stays the battle-tested runtime for the build — the python toolchain check now verifies both.

Changes

  • kit/bun.lock replaces package-lock.json — generated against the public registry, resolving the same dependency versions (verified, incl. the @huggingface/inference@4.13.15 pin). Bonus: bun.lock stores no registry URLs, so it's structurally immune to the internal-mirror-baked-URL trap that once broke CI with package-lock.json.
  • build.py/preview.py: bun install --frozen-lockfile + bun run build|dev; check_toolchain_is_available() checks bun ≥ 1.2 and node ≥ 20 up front.
  • CI: setup-bun added to the SvelteKit lint workflow, the shared build_main_documentation/build_pr_documentation workflows, and the accelerate integration workflow. setup-node is kept in the build workflows on purpose: they can run in custom containers where node isn't preinstalled.
  • bump-huggingface-js-packages workflow and README dev instructions updated (bun install, bun run dev, bun run update-inference-providers).

Verification

  • Accelerate e2e: output identical to the npm-built output on all 48 pages. One finding along the way: the hydration node_ids pointers differ across any two builds (npm↔npm or bun↔bun alike) because SvelteKit enumerates route nodes with unsorted readdirSync — each build is internally consistent, and everything else is byte-identical once that's normalized.
  • Browser tests on the bun-built output: hydration, SPA navigation, shorthand-URL preservation, HfOptions tabs, docstring tooltips — all pass.
  • doc-builder preview smoke-tested: bun install + vite dev server + page serving work end-to-end.
  • ruff and pytest clean.

🤖 Generated with Claude Code

mishig25 and others added 3 commits July 5, 2026 14:09
- kit: bun.lock replaces package-lock.json (generated against the public
  registry, resolving the same dependency versions incl. the
  @huggingface/inference pin). bun.lock stores no registry URLs, making
  it immune to the internal-mirror-baked-URL trap package-lock had.
- doc-builder build/preview invoke `bun install --frozen-lockfile` and
  `bun run build|dev` instead of `npm ci`/`npm run`. Vite itself still
  runs on Node.js (>= 20): bun is the installer/script runner, node stays
  the battle-tested runtime. The toolchain check verifies both.
- CI: setup-bun added to the lint workflow (bun-only there) and to the
  shared build workflows + accelerate integration workflow alongside
  setup-node (kept for custom-container jobs where node may be absent).
- bump-huggingface-js-packages workflow and README instructions updated.

Install time for kit deps drops from ~20s (npm ci, warm) to <1s locally
and ~5s cold.

Verified: accelerate e2e output identical to the npm-built output on all
48 pages — the only normalized difference is the hydration node_ids
ordering, which is fs-readdir-order-dependent in svelte-kit (unsorted
readdirSync) and nondeterministic across ANY two builds, npm or bun; each
build is internally consistent, confirmed by browser tests (hydration,
SPA nav, shorthand URLs, tooltips). preview smoke-tested (install + dev
server + serving). ruff/pytest clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
It runs on ubuntu-latest, where node is preinstalled (22.x satisfies the
>= 20 toolchain check) — same treatment as the lint workflow. setup-node
stays only in the shared build workflows, which can run in custom
containers without node.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Hosted runners ship node; custom-container jobs are expected to provide
node >= 20 in their image (the doc-builder toolchain check fails fast
with a clear message if it's missing).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@mishig25

mishig25 commented Jul 5, 2026

Copy link
Copy Markdown
Contributor Author

Closing for now: checking the transformers workflow surfaced two blockers for a safe rollout —

  1. custom_container images (e.g. huggingface/transformers-doc-builder, FROM python:3.10) have no Node; it was provided by the setup-node step this PR removes, so container-based doc builds would lose Vite's runtime.
  2. Most consumer repos (transformers, accelerate, diffusers, datasets, peft, trl) pin the shared build workflows to old commit SHAs while those workflows checkout doc-builder code at main — merging this would immediately break their doc builds ("bun was not found") until every repo bumps its pin.

The branch is kept. A safe re-roll would need: setup-node restored in the shared workflows, an npm fallback in the python commands with package-lock.json kept alongside bun.lock during the transition, and ideally the shared workflows checking out doc-builder at their own ref so future toolchain changes are atomic for pinned consumers.

@mishig25 mishig25 closed this Jul 5, 2026
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