CtrlK
BlogDocsLog inGet started
Tessl Logo

pleaseai/bun

All-in-one JavaScript/TypeScript toolkit: fast runtime, package manager, test runner, and bundler. Version-aware skill backed by the ask CLI.

75

Quality

94%

Does it follow best practices?

Impact

No eval scenarios have been run

SecuritybySnyk

Advisory

Suggest reviewing before use

Overview
Quality
Evals
Security
Files

SKILL.mdskills/use-bun/

name:
use-bun
description:
Answer questions about Bun — the all-in-one JavaScript/TypeScript toolkit — and write code using its runtime, package manager, test runner, and bundler. Use when developers call Bun-native APIs (`Bun.serve`, `Bun.file`, `Bun.write`, `Bun.spawn`, `Bun.$` shell, `Bun.SQL`, `Bun.RedisClient`, `Bun.build`, `HTMLRewriter`); import `bun:*` modules (`bun:test`, `bun:sqlite`, `bun:ffi`, `bun:jsc`); run CLI commands (`bun install`/`add`/`run`/`test`/`build`, `bunx`, `bun create`, `bun --compile`); configure `bunfig.toml`, `bun.lock`, workspaces, catalogs, overrides, isolated installs, trustedDependencies, or lifecycle scripts; bundle with loaders, plugins, or macros; write `bun:test` tests (`mock`, `spyOn`, `mock.module`, snapshots, coverage); or need Node.js compatibility, JSC vs V8 differences, or migration from npm/yarn/pnpm/jest/vitest.

Prerequisites

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-versionpackage.json.packageManagerengines.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/null

See 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/installation

Critical: Do Not Trust Internal Knowledge

Bun 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.
  • Catalogs (catalog: / catalogs: in package.json / bunfig.toml) — added in Bun 1.2+. Not available earlier.
  • Isolated installs (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:

  1. Resolve the installed version against the project via ${CLAUDE_SKILL_DIR}/scripts/resolve-bun-version.sh (which checks .bun-version, package.json.packageManager, engines.bun, then global bun --version in priority order).
  2. Verify every API name, method signature, and CLI flag against the version-tagged source via 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.
  3. Cross-reference the upstream docs at the matching version tag (references/versions.md for the ask pin recipe) — not main, which tracks unreleased changes.
  4. Use bun --print '<expr>' or a quick REPL (bun repl) to confirm behaviour before committing complex API uses.
  5. Surface meaningful trade-offs to the user instead of silently picking a side (e.g. 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.

Finding Documentation

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"                  # implementation

When 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@main

See references/versions.md for the version pinning recipe and known-stable tag list.

Topic Map

Load the focused reference for the area you're touching — do not read all of them upfront.

TopicReferenceWhen
Runtime APIs (Bun.*, bun:* modules)references/runtime-apis.mdWriting server code, file I/O, child processes, SQL/SQLite/Redis, FFI, shell
Package manager (bun install, workspaces, catalogs)references/package-manager.mdSetting up deps, monorepos, bunfig.toml install settings, lockfile, registries
Test runner (bun:test)references/test-runner.mdWriting tests, mocks, snapshots, coverage, migrating from Jest/Vitest
Bundler (Bun.build, bun build)references/bundler.mdBundling, executables (--compile), plugins, macros, fullstack dev server
Node.js compatibilityreferences/node-compat.mdMigrating Node apps, checking node:* module support, JSC vs V8 differences
Version pinning recipereferences/versions.mdask spec to use, known-stable Bun versions, lockfile format history

Common Decision Points

  • Server: prefer Bun.serve over node:http — built-in routing (routes: on 1.2.3+), WebSockets, TLS, hot reload via --hot.
  • File I/O: prefer Bun.file() / Bun.write() over node:fs/promises — lazy reads, faster, returns Blob-compatible objects.
  • Spawning processes: prefer Bun.spawn() / Bun.$ over node:child_process — better defaults, streaming stdio, async iterators.
  • SQLite: use bun:sqlite — synchronous, built-in, no compile step. For Postgres use Bun.SQL.
  • Shell scripts: prefer Bun.$\cmd`overchild_process.exec` — safe interpolation, async iteration, JS strings as commands.
  • Package install: 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.
  • Tests: 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.
  • Bundling for browser: 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.
  • Bundling for CLI distribution: 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.

Migration Quick Reference

FromToNotes
npm install / yarn install / pnpm installbun installFirst 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.tsNative TS; no config
node --watch script.tsbun --watch run script.tsOr bun --hot run for in-process hot reload
jest / vitestbun testAPI mostly compatible; verify matchers — Bun does not implement every Jest matcher
dotenvbuilt-inBun auto-loads .env, .env.local, .env.{NODE_ENV}
tsx watch src/index.tsbun --watch run src/index.ts
child_process.execBun.$`...`Async iterable output, safe interpolation
fs.readFileawait Bun.file(path).text()Or .json(), .arrayBuffer(), .bytes(), .stream()
crypto.createHashBun.hash / Bun.CryptoHasherFaster; check algorithm support

Conventions

  • TypeScript by default — Bun runs .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).
  • ESM by default — Bun supports CJS interop but new code should be ESM. "type": "module" in package.json is optional but recommended for clarity.
  • No 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.

README.md

tile.json