All-in-one JavaScript/TypeScript toolkit: fast runtime, package manager, test runner, and bundler. Version-aware skill backed by the ask CLI.
75
94%
Does it follow best practices?
Impact
—
No eval scenarios have been run
Advisory
Suggest reviewing before use
Verify the ask CLI is available (which ask). It is the primary tool for reading the exact Bun version installed in the project — it fetches the version-tagged source from GitHub once and caches it at ~/.ask/. If ask is not installed, fall back to the local bun binary's built-in help and the official docs at https://bun.com/docs (which always tracks the latest release).
Before writing Bun-specific code, detect the project's Bun version. The skill bundles a helper that resolves it in the correct priority order (.bun-version → package.json.packageManager → engines.bun → global bun):
# Resolve project pin; GitHub release tags use the `bun-vX.Y.Z` form
BUN_REF="bun-v$(${CLAUDE_SKILL_DIR}/scripts/resolve-bun-version.sh)" || exit 1
echo "$BUN_REF" # e.g. bun-v1.3.14
# Lockfile format — Bun migrated from binary bun.lockb to text bun.lock at 1.2.0
ls bun.lock bun.lockb 2>/dev/nullSee references/versions.md for the resolution rules and the underlying script (scripts/resolve-bun-version.sh).
If Bun is not installed, install it once:
# Recommended — official installer
curl -fsSL https://bun.sh/install | bash
# Or via npm / brew / proto / asdf — see https://bun.com/docs/installationBun ships fast — APIs land, change shape, or move modules between minor releases. Common pitfalls from outdated training data:
Bun.serve routes (routes: { "/users/:id": handler }) — requires Bun 1.2.3+. Before that you wrote fetch(req) with manual URL parsing. Do not suggest routes on older versions.bun.lock (text JSONC) vs bun.lockb (binary) — Bun 1.2.0+ writes bun.lock by default (the text format was introduced as opt-in earlier and became the default at 1.2). Existing bun.lockb files migrate via bun install --save-text-lockfile --frozen-lockfile --lockfile-only. If you see both, the text one wins.catalog: / catalogs: in package.json / bunfig.toml) — added in Bun 1.2+. Not available earlier.linker = "isolated") — added in Bun 1.2.x. Earlier versions only support hoisted.bun:sql / Bun.SQL — Postgres client landed in Bun 1.2+; native MySQL/SQLite are different surfaces (bun:sqlite has always existed).Bun.RedisClient / Bun.redis — Valkey/Redis client is recent (Bun 1.2.x). Older code uses third-party libs.bun build --compile — single-file executables stabilised in 1.1+; flags like --bytecode, --target=bun-linux-x64-baseline, and Windows cross-compile are newer.mock.module() — module mocking in bun:test. Stable across all current Bun releases; very old (early 1.0.x) versions only had mock() for function-level mocks. If you need to support a specific pre-1.1 version, verify the API against that release's docs.Bun.$ (shell) — promoted from experimental in Bun 1.0.24+. API stabilised since.trustedDependencies in package.json — Bun does not run installed dependencies' lifecycle scripts by default for security; you must allowlist via this field. Different default than npm/yarn.When working with Bun:
${CLAUDE_SKILL_DIR}/scripts/resolve-bun-version.sh (which checks .bun-version, package.json.packageManager, engines.bun, then global bun --version in priority order).ask before generating code. Do not invent flag names — Bun's CLI has many short forms and aliases, but only the documented ones are stable.references/versions.md for the ask pin recipe) — not main, which tracks unreleased changes.bun --print '<expr>' or a quick REPL (bun repl) to confirm behaviour before committing complex API uses.Bun.serve static routes vs fetch handler; bun:sqlite vs Bun.SQL; bun test vs vitest for projects that already use Vitest).If documentation cannot be found locally or remotely to back an answer, say so explicitly.
Bun's source and docs live in one repo: github:oven-sh/bun. Use ask with the matching tag:
# Resolve project pin (see Prerequisites above) — GitHub tags use `bun-v` prefix
BUN_REF="bun-v$(${CLAUDE_SKILL_DIR}/scripts/resolve-bun-version.sh)"
# Source tree (single line — pass to rg/fd/cat)
ask src "github:oven-sh/bun@${BUN_REF}"
# Doc candidates (one per line; the docs/ folder will be first)
ask docs "github:oven-sh/bun@${BUN_REF}"
# Convenience
BUN_SRC=$(ask src "github:oven-sh/bun@${BUN_REF}")
ls "${BUN_SRC}/docs" # MDX docs by topic
rg "Bun\.serve" "${BUN_SRC}/docs/runtime/http/server.mdx"
rg "fn serve" "${BUN_SRC}/src/bun.js" # implementationWhen the version is unknown or the user is reading reference material:
ask docs github:oven-sh/bun@main # latest unreleased
ask src github:oven-sh/bun@mainSee references/versions.md for the version pinning recipe and known-stable tag list.
Load the focused reference for the area you're touching — do not read all of them upfront.
| Topic | Reference | When |
|---|---|---|
Runtime APIs (Bun.*, bun:* modules) | references/runtime-apis.md | Writing server code, file I/O, child processes, SQL/SQLite/Redis, FFI, shell |
Package manager (bun install, workspaces, catalogs) | references/package-manager.md | Setting up deps, monorepos, bunfig.toml install settings, lockfile, registries |
Test runner (bun:test) | references/test-runner.md | Writing tests, mocks, snapshots, coverage, migrating from Jest/Vitest |
Bundler (Bun.build, bun build) | references/bundler.md | Bundling, executables (--compile), plugins, macros, fullstack dev server |
| Node.js compatibility | references/node-compat.md | Migrating Node apps, checking node:* module support, JSC vs V8 differences |
| Version pinning recipe | references/versions.md | ask spec to use, known-stable Bun versions, lockfile format history |
Bun.serve over node:http — built-in routing (routes: on 1.2.3+), WebSockets, TLS, hot reload via --hot.Bun.file() / Bun.write() over node:fs/promises — lazy reads, faster, returns Blob-compatible objects.Bun.spawn() / Bun.$ over node:child_process — better defaults, streaming stdio, async iterators.bun:sqlite — synchronous, built-in, no compile step. For Postgres use Bun.SQL.Bun.$\cmd`overchild_process.exec` — safe interpolation, async iteration, JS strings as commands.bun install is the default; falls back gracefully on npm/yarn lockfiles but writes bun.lock after the first run. Warn the user if they share a repo with other PMs.bun test is Jest-compatible and runs *.test.{ts,tsx,js,jsx,mjs,cjs} by default — no config required. Migrate from vitest only if speed is a real bottleneck; APIs are close but not identical.Bun.build({ target: "browser" }) is fast and adequate; for production web bundles with code splitting and asset pipelines, dedicated tools (Vite/Webpack) may still be more featureful — check the user's actual needs before recommending.bun build --compile produces a single-file native binary including the Bun runtime. Excellent for CLIs; not suitable for plugin systems that need dynamic imports.| From | To | Notes |
|---|---|---|
npm install / yarn install / pnpm install | bun install | First run writes bun.lock; coexists with other lockfiles but they drift |
npx <cmd> | bunx <cmd> | Equivalent; faster cold start |
node script.ts (with ts-node/tsx) | bun script.ts | Native TS; no config |
node --watch script.ts | bun --watch run script.ts | Or bun --hot run for in-process hot reload |
jest / vitest | bun test | API mostly compatible; verify matchers — Bun does not implement every Jest matcher |
dotenv | built-in | Bun auto-loads .env, .env.local, .env.{NODE_ENV} |
tsx watch src/index.ts | bun --watch run src/index.ts | |
child_process.exec | Bun.$`...` | Async iterable output, safe interpolation |
fs.readFile | await Bun.file(path).text() | Or .json(), .arrayBuffer(), .bytes(), .stream() |
crypto.createHash | Bun.hash / Bun.CryptoHasher | Faster; check algorithm support |
.ts / .tsx natively. Add @types/bun if your editor needs types: bun add -d @types/bun. In tsconfig.json use "types": ["bun"] (replaces @types/node in pure-Bun projects)."type": "module" in package.json is optional but recommended for clarity.dist/ for libraries that ship as-is — Bun can publish TS directly, but most ecosystems still expect compiled output. Use bun build or a dedicated bundler for npm releases.bunfig.toml lives at the project root and configures install, runtime, and test behaviour. Keep it minimal — defaults are good. See references/runtime-apis.md and references/package-manager.md for the keys that matter most.