Bun
Bun runtime and package management conventions
Bun is the only runtime + package manager.
MUST
- Use only
bun. Why: one toolchain, no manager drift. bun fixpasses before done. Why: lint/format gate.- Update deps via
bun clean && bun i. Why: refreshes"latest"cleanly. - All deps
"latest"; WHEN a pin is unavoidable, pin major only ("eslint": "9"). Why: no legacy lock-in. - Every direct dep shows an upstream release within ~6 months; replace an abandoned or archived dep, never keep it. Why: stale-but-stable rots — force the migration early.
- A newly required CLI or dep lands in
package.json(or the documented setup script) the same turn it is first used. Why: never re-litigate the install next session. import { X } from 'bun'($,file,write,Glob,spawn, …) in bun-runtime apps (CLI, standalone server). Why: explicit + tree-shakeable;Bunis a registered biome global so either form lints clean.- Use the
Bunglobal (Bun.S3Client,Bun.s3, …) in Next/Turbopack apps. Why:import { X } from 'bun'is unresolvable innext build's Node page-data-collection workers; the global needs no module resolution, so it survives the build and resolves under the bun runtime. - Run
bun iimmediately after renaming a workspacename:. Why: dependents resolve old name via stalenode_modules/<scope>/symlink. - Read an opaque eslint
ResolveMessage {}as a stale workspace symlink → reinstall first. Why: it masks every other violation; not a lint-internals bug. - Scripts silent on success, verbose on failure. Why: agent context budget.
NEVER
- yarn / npm / npx / pnpm. Cost: toolchain drift.
bun update. Cost: rewrites"latest"to resolved versions.- Commit
bun.lock(keep in.gitignore). Cost: lockfile drift across machines. git clean. Cost: deletes.env+ uncommitted files — use explicitrm -rf.
Scripts
sh clean.sh— nuke artifacts (node_modules, lockfile, caches, dist, .next).sh up.sh— clean + install + fix + check (universal maintenance cycle).