Vite 8 + React with Bun install, Oxlint, and Oxfmt
Bun installs, Vite bundles, tsc checks, Oxc lints and formats.
Four tools, four jobs. Bun installs, Vite serves and bundles, TypeScript checks types, Oxc lints and formats. Know which one failed before you fix anything.
§I. Frame
This is the first ABC Frontend fire. Everything later on this clock (TanStack Start, Hono, Tailwind, WASM islands) sits inside a Vite app, so the first job is a clean scaffold you can rebuild from a lockfile and check in under a second.
Done bar: a React + TypeScript app that installs from bun.lock, builds with tsc -b && vite build, lints clean with Oxlint, and passes oxfmt --check.
§II. Three techniques
One Tool, One Job (named technique). Name the tool behind every command.
| Command | Tool | Job |
|---|---|---|
bun create vite, bun install | Bun | scaffold, resolve, write bun.lock |
vite, vite build | Vite 8 | dev server with HMR, production bundle |
tsc -b | TypeScript | type check only (the build script runs it first) |
oxlint | Oxc | lint |
oxfmt | Oxc | format |
Bun stays install and CLI here. The anchor puts the Deno runtime shell on a C-day; Bun is not the server.
Read the Lockfile, Not the Range (named technique). package.json says "vite": "^8.3.0". The install resolved [email protected]. The range is a wish; bun.lock is the fact, and it is what a teammate or a Nix build reproduces. Check versions from the tools themselves:
vite/8.3.4 darwin-arm64 node-v26.8.2
oxlint Version: 1.88.0
oxfmt Version: 0.73.0
node_modules/vite/package.json lists "rolldown": "~1.2.12" as a dependency, so this Vite bundles with Rolldown. That line is from the installed package, not from release notes.
Check Mode in CI, Write Mode Locally (named technique). oxfmt rewrites files; oxfmt --check only reports. Run write mode once after scaffolding, commit, then gate on check mode.
§III. Run it
bun create vite@latest asr-web --template react-ts --no-interactive
cd asr-web && bun install
bun add -d oxfmt
bun run build # tsc -b && vite build
bun run lint # oxlint
bunx oxfmt --check
Real output on the lab Mac, trimmed to the lines that matter:
28 packages installed [787.00ms]
✓ 20 modules transformed.
dist/index.html 0.45 kB │ gzip: 0.29 kB
dist/assets/index-D64VDMd1.css 4.10 kB │ gzip: 1.47 kB
dist/assets/index-CVtPK4EU.js 222.44 kB │ gzip: 69.28 kB
✓ built in 215ms
oxlint printed nothing and exited 0. The template already wires it as the lint script, so no ESLint config ships in this scaffold.
The first oxfmt --check failed on the fresh template:
Format issues found in above 7 files. Run without `--check` to fix.
Finished in 78ms on 12 files using 10 threads.
No config found, using defaults. Please add a config file or try `oxfmt --init` if needed.
After one bunx oxfmt write pass:
All matched files use the correct format.
Finished in 65ms on 12 files using 10 threads.
So the template's own style and Oxfmt's defaults disagree. Format once, commit, and the check stays green. Add an .oxfmtrc only when you need a non-default rule.
§IV. Where the Duha API plugs in
The Duha health binary from today answers {"status":"ok"} on 127.0.0.1:8787 and sends access-control-allow-origin: *. The fetch stub to it is the last row of this A bucket, so it waits; do not add it today. The build output in dist/ is static files, which is why Ops can package it with Nix on 2026-10-12.
§V. Drills
bun run buildfails before Vite prints anything. Which tool failed? (tsc -b: the type check runs first.)- A teammate gets
[email protected]and you have8.3.4. Which file decides? (bun.lock, if it is committed and used.) - CI should fail on badly formatted code but never rewrite it. Which command? (
oxfmt --check.) - Lint is clean but the app shows a type error in the editor. Why did
oxlintnot catch it? (Oxlint lints;tsctype checks.)
Close
One Tool, One Job; Read the Lockfile, Not the Range; Check Mode in CI. Scaffold, install from the lock, build, lint, format once, then gate on check. Next A-day adds a router.
Related
- Tome: Cherny ch2, tsconfig.json (grounded-in)
- Web: Vite guide · bun install · Oxlint · Oxfmt · React build-from-scratch
- Paired Duha 2026-10-11: Tokio runtime and the health binary