From javascript
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.
How this skill is triggered — by the user, by Claude, or both
Slash command
/javascript:bunThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
**Use Bun APIs, not Node.js polyfills. If Bun provides a native API for it, use it.**
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.
${CLAUDE_SKILL_DIR}/references/server.md]: Route types, file response patterns, WebSocket
pub/sub, server config${CLAUDE_SKILL_DIR}/references/io-and-processes.md]: File I/O details, shell API,
child processes, workers${CLAUDE_SKILL_DIR}/references/testing.md]: Test modifiers, parametrized tests, mocking, snapshots,
CLI flags${CLAUDE_SKILL_DIR}/references/ecosystem.md]: SQLite API, bundler options, plugins,
macros${CLAUDE_SKILL_DIR}/references/config-and-compat.md]: bunfig.toml sections, Node.js
compatibility, env varsRule: 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.
routes object (v1.2.3+) for declarative path matching. Preferred over fetch-based routing."/users/all", highest priority), parameterized ("/users/:id", req.params.id), wildcard
("/api/*"), per-method ({ GET: handler, POST: handler }).fetch handler as fallback for unmatched routes, not primary routing.error handler in Bun.serve().development: true in dev for built-in error pages.Response objects for health checks, redirects, fixed JSON — they are zero-allocation after init,
cached for server lifetime.server.reload() to update static responses at runtime.BunRequest (extends Request) with params (auto URL-decoded) and cookies
(auto-tracked CookieMap).Set-Cookie headers added automatically when using req.cookies.set() /
.delete().server.upgrade(req, { data }) in the fetch handler.ws.subscribe("topic"), ws.publish("topic", data).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.
Bun.file() is lazy. Creating a BunFile does not read from disk. It conforms to Blob..text(), .json(), .bytes(), .stream(), .arrayBuffer() on BunFile.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).file.writer() (FileSink). Call .flush() to flush buffer, .end() to flush + close
(required to let process exit).Bun.stdin (readonly), Bun.stdout, Bun.stderr.node:fs for directory ops — mkdir, readdir. No Bun-specific API yet.import.meta.dir gives the directory of the current file.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..text() (string, auto-quiets), .json() (parsed), .lines() (async iterator), .blob(), or
await $\...`for{ stdout, stderr }` Buffers..quiet() to suppress stdout/stderr output.ShellError by default. Use .nothrow() to handle exit codes manually. Configure
globally: $.nothrow() or $.throws(false).|, >, 2>&1, < ${Bun.file("input.txt")}, < ${response}..env({ FOO: "bar" }), .cwd("/tmp"). Global defaults: $.env(...), $.cwd(...).bash -c bypasses Bun's protections.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: 5000, killSignal: "SIGKILL" } or pass AbortController.signal.Bun.spawn(["bun", "child.ts"], { ipc(message) {} }).Stdin/stdout options, workers, and process details: see ${CLAUDE_SKILL_DIR}/references/io-and-processes.md.
bun:testbun:test, not jest or vitest.test, describe, expect, mock, spyOn, beforeAll, beforeEach, afterEach,
afterAll.bun test — auto-discovers *.test.* and *.spec.* files.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.
bun:sqlite — native, synchronous, 3-6x faster than better-sqlite3. Enable WAL mode. Use prepared
statements and transactions.Bun.build() with targets "bun", "browser", "node". Check result.success and iterate
result.logs on failure.Bun.plugin() with setup(build) — extend module resolver and loader. Register via bunfig.toml
preload.{ 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.
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.await Bun.sleep(ms) — async. Bun.sleepSync(ms) — blocking.Bun.nanoseconds() — high-resolution timer.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.Bun.gzipSync(data) / Bun.gunzipSync(data).Bun.deflateSync(data) / Bun.inflateSync(data).Bun.zstdCompressSync(data) / Bun.zstdDecompressSync(data).Bun.randomUUIDv7() — time-ordered. crypto.randomUUID() — standard v4.Bun.readableStreamToText/JSON/Bytes/Blob/Array/ArrayBuffer(stream).Bun.escapeHTML("<script>"), Bun.stringWidth("hello").Bun.version, Bun.revision (git hash), Bun.env (alias for process.env), Bun.main (entrypoint path).import.meta.dir, import.meta.file, import.meta.path — current file info.Response objects and strings.bun installDrop-in replacement for npm/yarn/pnpm. ~25x faster.
bun.lock (text, default since v1.2) or bun.lockb (binary).postinstall of dependencies by default (security). Add to trustedDependencies in package.json
to allow.package.json workspaces field.node_modules found, Bun resolves packages on the fly.bunx: execute package binaries without installing (like npx).bun install --production skips devDependencies.bunfig.toml sections, environment variable loading, and Node.js API compatibility details: see
${CLAUDE_SKILL_DIR}/references/config-and-compat.md.
When writing Bun code:
When reviewing Bun code:
The javascript skill governs language choices; this skill governs Bun runtime and toolchain decisions. Activate typescript alongside both when working with TypeScript.
Use Bun APIs, not Node.js polyfills. When in doubt, check if Bun has a native API.
npx claudepluginhub xobotyi/cc-foundry --plugin javascriptGuides fast JavaScript/TypeScript development with Bun runtime: project init, package management, built-in bundler/test runner, Node.js migration, and troubleshooting.
Provides guidance and examples for Bun runtime APIs including Bun.file(), Bun.serve(), WebSockets, environment variables, and shell execution in JS/TS projects.
Provides guidance on using Bun as a runtime, package manager, bundler, and test runner, including migration from Node and Vercel deployment.