bun
Bun runtime conventions, APIs, and toolchain. Invoke whenever task involves any interaction with Bun — serving HTTP, file I/O, shell scripting, testing, bundling, or package management with Bun.
What this skill does
# Bun
**Use Bun APIs, not Node.js polyfills. If Bun provides a native API for it, use it.**
Bun is a batteries-included JavaScript runtime. It replaces Node.js, npm, Jest, and webpack with a single tool. Prefer
Bun-native APIs (`Bun.serve`, `Bun.file`, `Bun.$`, `bun:sqlite`, `bun:test`) over Node.js equivalents unless portability
is an explicit requirement.
## References
- **HTTP server** — [`${CLAUDE_SKILL_DIR}/references/server.md`]: Route types, file response patterns, WebSocket
pub/sub, server config
- **File I/O and processes** — [`${CLAUDE_SKILL_DIR}/references/io-and-processes.md`]: File I/O details, shell API,
child processes, workers
- **Testing** — [`${CLAUDE_SKILL_DIR}/references/testing.md`]: Test modifiers, parametrized tests, mocking, snapshots,
CLI flags
- **SQLite, bundler, plugins** — [`${CLAUDE_SKILL_DIR}/references/ecosystem.md`]: SQLite API, bundler options, plugins,
macros
- **Configuration** — [`${CLAUDE_SKILL_DIR}/references/config-and-compat.md`]: bunfig.toml sections, Node.js
compatibility, env vars
## Prefer Bun-Native APIs
Rule: if `Bun.*` or `bun:*` has it, use it. Fall back to `node:*` only when there's no Bun-native alternative or when
portability to Node.js is required.
Core mappings: `Bun.serve()` over `http.createServer()`, `Bun.file()`/`Bun.write()` over `node:fs`, `Bun.$` over
`child_process.exec`, `bun:sqlite` over `better-sqlite3`, `bun:test` over Jest/Vitest, `Bun.password` over `bcrypt`,
`Bun.sleep()` over `setTimeout` wrappers, `Bun.spawn()` over `child_process.spawn`. Use `node:fs` for directory ops — no
Bun API yet. Use Web Streams API over `node:stream`.
Full API preference table: see `${CLAUDE_SKILL_DIR}/references/io-and-processes.md`.
## HTTP Server
### Routing
- **Use `routes` object** (v1.2.3+) for declarative path matching. Preferred over `fetch`-based routing.
- **Route types:** exact (`"/users/all"`, highest priority), parameterized (`"/users/:id"`, `req.params.id`), wildcard
(`"/api/*"`), per-method (`{ GET: handler, POST: handler }`).
- **Precedence:** exact > parameterized > wildcard > global catch-all.
- **`fetch` handler** as fallback for unmatched routes, not primary routing.
- **Always implement `error` handler** in `Bun.serve()`.
- **`development: true`** in dev for built-in error pages.
### Static Responses
- **Use static `Response` objects** for health checks, redirects, fixed JSON — they are zero-allocation after init,
cached for server lifetime.
- **Call `server.reload()`** to update static responses at runtime.
### Request Object
- **Route handlers receive `BunRequest`** (extends `Request`) with `params` (auto URL-decoded) and `cookies`
(auto-tracked `CookieMap`).
- **TypeScript infers param shape** when route is a string literal.
- **Cookie changes are auto-tracked** — `Set-Cookie` headers added automatically when using `req.cookies.set()` /
`.delete()`.
### WebSocket
- **Upgrade via `server.upgrade(req, { data })`** in the `fetch` handler.
- **Use native pub/sub** for topic-based broadcasting: `ws.subscribe("topic")`, `ws.publish("topic", data)`.
- **Type `ws.data`** via the `data` property on the `websocket` handler object.
WebSocket limits, server configuration, file response patterns, HTML imports, and server lifecycle details: see
`${CLAUDE_SKILL_DIR}/references/server.md`.
## File I/O
- **`Bun.file()` is lazy.** Creating a `BunFile` does not read from disk. It conforms to `Blob`.
- **Read with `.text()`, `.json()`, `.bytes()`, `.stream()`, `.arrayBuffer()`** on `BunFile`.
- **Check existence:** `await file.exists()`. Access `file.size` and `file.type`.
- **`Bun.write()` handles all types** — string, Blob, Response, ArrayBuffer, BunFile. Uses fastest syscall per platform
(`copy_file_range`, `sendfile`, `clonefile`).
- **Incremental writing:** use `file.writer()` (`FileSink`). Call `.flush()` to flush buffer, `.end()` to flush + close
(required to let process exit).
- **Built-in stdio references:** `Bun.stdin` (readonly), `Bun.stdout`, `Bun.stderr`.
- **Use `node:fs` for directory ops** — `mkdir`, `readdir`. No Bun-specific API yet.
- **`import.meta.dir`** gives the directory of the current file.
## Shell API — `Bun.$`
Cross-platform bash-like shell with JavaScript interop. Runs in-process (not `/bin/sh`).
- **`$` tagged template** for shell commands. Interpolated values are auto-escaped — injection-safe by default.
- **Read output:** `.text()` (string, auto-quiets), `.json()` (parsed), `.lines()` (async iterator), `.blob()`, or
`await $\`...\``for`{ stdout, stderr }` Buffers.
- **`.quiet()`** to suppress stdout/stderr output.
- **Non-zero exit codes throw `ShellError`** by default. Use `.nothrow()` to handle exit codes manually. Configure
globally: `$.nothrow()` or `$.throws(false)`.
- **Piping and redirection** work: `|`, `>`, `2>&1`, `< ${Bun.file("input.txt")}`, `< ${response}`.
- **Set environment/cwd:** `.env({ FOO: "bar" })`, `.cwd("/tmp")`. Global defaults: `$.env(...)`, `$.cwd(...)`.
- **Security:** interpolated variables are escaped (no command injection), but argument injection is still possible
(external commands interpret their own flags). Spawning `bash -c` bypasses Bun's protections.
## Child Processes
- **`Bun.spawn()`** for fine-grained async process control. Access `proc.pid`, `proc.stdout`, `proc.exited`,
`proc.exitCode`. Kill with `proc.kill()`.
- **`Bun.spawnSync()`** for blocking execution. Rule: `spawnSync` for CLI tools, `spawn` for servers.
- **Timeout and abort:** `{ timeout: 5000, killSignal: "SIGKILL" }` or pass `AbortController.signal`.
- **IPC between Bun processes:** `Bun.spawn(["bun", "child.ts"], { ipc(message) {} })`.
Stdin/stdout options, workers, and process details: see `${CLAUDE_SKILL_DIR}/references/io-and-processes.md`.
## Testing — `bun:test`
- **Import from `bun:test`**, not `jest` or `vitest`.
- **Jest-compatible API:** `test`, `describe`, `expect`, `mock`, `spyOn`, `beforeAll`, `beforeEach`, `afterEach`,
`afterAll`.
- **Run with `bun test`** — auto-discovers `*.test.*` and `*.spec.*` files.
- **Cleanup:** `mock.restore()` restores all spied functions, `mock.clearAllMocks()` clears history. Add to `afterEach`.
- **`mock.module("./path", () => ({ ... }))`** for module mocking. Works for ESM and CJS.
Test modifiers, parametrized tests, mocking details, snapshots, CLI flags, and bunfig.toml test config: see
`${CLAUDE_SKILL_DIR}/references/testing.md`.
## SQLite, Bundler, Plugins, Macros
- **SQLite:** use `bun:sqlite` — native, synchronous, 3-6x faster than `better-sqlite3`. Enable WAL mode. Use prepared
statements and transactions.
- **Bundler:** `Bun.build()` with targets `"bun"`, `"browser"`, `"node"`. Check `result.success` and iterate
`result.logs` on failure.
- **Plugins:** `Bun.plugin()` with `setup(build)` — extend module resolver and loader. Register via bunfig.toml
`preload`.
- **Macros:** compile-time code execution via `{ type: "macro" }` import. Return value inlined; must be
JSON-serializable.
Full SQLite API, bundler options, plugin patterns, and macro constraints: see
`${CLAUDE_SKILL_DIR}/references/ecosystem.md`.
## Utilities
### Hashing & Passwords
- `Bun.password.hash(pw)` — argon2id default. Also supports `"bcrypt"`.
- `Bun.password.verify(pw, hash)` — auto-detects algorithm.
- `Bun.hash("data")` — fast non-crypto (Wyhash).
- `new Bun.CryptoHasher("sha256")` — crypto hashing.
### Sleep & Timing
- `await Bun.sleep(ms)` — async. `Bun.sleepSync(ms)` — blocking.
- `Bun.nanoseconds()` — high-resolution timer.
### Comparison & Inspection
- `Bun.deepEquals(a, b)` — deep equality. `Bun.deepMatch(subset, obj)` — partial match.
- `Bun.inspect(obj)` — `console.log` format as string. `Bun.peek(promise)` — read without awaiting.
### Compression
- Gzip: `Bun.gzipSync(data)` / `Bun.gunzipSync(data)`.
- Deflate: `Bun.deflateSync(data)` / `Bun.inflateSync(data)`.
- Zstd: `Bun.zstdCompressSync(data)` / `Bun.zstdDecompressSync(data)`.
### Paths, UUIDs, Streams
Related in Productivity
gitea-workflow
IncludedOrchestrate agile development workflows for Gitea repositories using the tea CLI. Use when working with Gitea-hosted repos and asking to 'run the workflow', 'continue working', 'what's next', 'complete the task cycle', 'start my day', 'end the sprint', 'implement the next task', or wanting guided step-by-step development assistance. Keywords: workflow, orchestrate, agile, task cycle, sprint, daily, implement, review, PR, standup, retrospective, gitea, tea.
microsoft-graph-gateway
IncludedRoute Microsoft Graph work in this workspace. Use when users want to read or write Outlook mail, calendar events, contacts, OneDrive or SharePoint files, Teams, Planner, To Do, users, groups, directory data, or arbitrary Microsoft Graph endpoints from VS Code. Prefer WorkIQ for common read scenarios. Use Microsoft Graph for write actions and gap-read scenarios that need exact Graph properties, filters, permissions, or endpoints.
copilotkit
IncludedUse when building with CopilotKit — setup, development, integrations, debugging, upgrading, or contributing. Routes to the appropriate specialized skill based on the task.
wordly-wisdom
IncludedProvides calibrated decision analysis using Charlie Munger-style multiple mental models, inversion, incentive mapping, circle-of-competence checks, misjudgment audits, second-order effects, and forecast updates. Use when the user asks for an oracle take, a hard call, a decision memo, a premortem, an outside view, a red-team, a sanity-check, what am I missing, think this through, or wants a strategy, hire, investment, plan, product, partnership, or major life choice analysed. Avoid for simple factual lookups or time-sensitive legal, medical, or market questions without fresh evidence.
swain-session
IncludedSession management and project status dashboard. Owns the full session lifecycle (start/work/close/resume), focus lane, bookmarks, worktree detection, and tab naming. Also serves as the project status dashboard — shows active epics, progress, actionable next steps, blocked items, tasks, GitHub issues, and recommendations. Worktree creation is deferred to swain-do task dispatch (SPEC-195). Triggers on: 'session', 'status', 'what's next', 'dashboard', 'overview', 'where are we', 'what should I work on', 'show me priorities', 'bookmark', 'focus on', 'session info'.
gandi
IncludedComprehensive Gandi domain registrar integration for domain and DNS management. Register and manage domains, create/update/delete DNS records (A, AAAA, CNAME, MX, TXT, SRV, and more), configure email forwarding and aliases, check SSL certificate status, create DNS snapshots for safe rollback, bulk update zone files, and monitor domain expiration. Supports multi-domain management, zone file import/export, and automated DNS backups. Includes both read-only and destructive operations with safety controls.