skills/bun-runtime/SKILL.md
Bun runtime for fast JavaScript/TypeScript execution, package management, bundling, and testing. Use when user mentions "bun", "bun run", "bun install", "bunx", "bun test", "bun build", "fast node alternative", "bun shell", or migrating from Node to Bun.
npx skillsauth add 1mangesh1/dev-skills-collection bun-runtimeInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Bun is an all-in-one JavaScript/TypeScript runtime, package manager, bundler, and test runner.
Bun runs .ts, .tsx, .js, and .jsx files directly. No compilation step or tsconfig required.
bun run index.ts # Run a file
bun --watch run server.ts # Restart on file changes
bun --hot run server.ts # Hot reload (preserves state)
Uses a binary lockfile (bun.lockb). Commit it to version control.
bun install # Install all deps
bun add express # Add dependency
bun add -d typescript @types/node # Add dev dependency
bun add -g serve # Global install
bun remove express # Remove dependency
bun update # Update deps
By default, postinstall scripts do not run. Allow specific packages in package.json:
{ "trustedDependencies": ["sharp", "esbuild"] }
Or run bun install --trust to allow all.
bun run dev # Run package.json script
bun dev # Shorthand (same thing)
bunx cowsay hello # One-off binary (like npx)
bun --env-file=.env.local run app.ts # Custom env file
Cross-platform shell via $ tagged template. Works on macOS, Linux, and Windows.
import { $ } from "bun";
const result = await $`ls -la`.text();
const count = await $`cat file.txt | wc -l`.text();
const dir = "/tmp";
await $`ls ${dir}`; // Safe interpolation
await $`echo "hello" > output.txt`; // Redirect
await $`noisy-command`.quiet(); // Suppress stdout
const { exitCode } = await $`cmd`.nothrow(); // No throw on failure
for await (const line of $`tail -f log.txt`.lines()) {
console.log(line); // Stream lines
}
Jest-compatible syntax with bun:test.
bun test # Run all tests
bun test auth.test.ts # Specific file
bun test --grep "login" # Filter by pattern
bun test --watch # Watch mode
bun test --coverage # Coverage report
bun test --update-snapshots # Update snapshots
import { test, expect, describe, mock, spyOn } from "bun:test";
describe("math", () => {
test("addition", () => {
expect(1 + 1).toBe(2);
});
test("async", async () => {
const result = await fetchData();
expect(result).toEqual({ id: 1 });
});
});
// Mocking
const fn = mock(() => 42);
fn();
expect(fn).toHaveBeenCalled();
mock.module("./db", () => ({
query: mock(() => [{ id: 1 }]),
}));
// Snapshots
test("snapshot", () => {
expect({ users: [{ name: "Alice" }] }).toMatchSnapshot();
});
bun build ./src/index.ts --outdir ./dist --target browser
bun build ./src/index.ts --outdir ./dist --target node
bun build ./src/index.ts --outdir ./dist --target bun
bun build ./src/cli.ts --compile --outfile mycli # Standalone binary
bun build ./src/index.ts --outdir ./dist --minify
Programmatic API:
const result = await Bun.build({
entrypoints: ["./src/index.ts"],
outdir: "./dist",
target: "browser",
minify: true,
splitting: true,
sourcemap: "external",
});
if (!result.success) {
for (const log of result.logs) console.error(log);
}
Bun.serve({
port: 3000,
async fetch(req) {
const url = new URL(req.url);
if (url.pathname === "/api/health") return Response.json({ status: "ok" });
if (req.method === "POST" && url.pathname === "/api/data") {
return Response.json({ received: await req.json() });
}
return new Response("Not Found", { status: 404 });
},
error(error) {
return new Response(`Error: ${error.message}`, { status: 500 });
},
});
Bun.serve({
fetch(req, server) {
if (server.upgrade(req)) return;
return new Response("Not a WebSocket request", { status: 400 });
},
websocket: {
open(ws) { console.log("connected"); },
message(ws, message) { ws.send(`echo: ${message}`); },
close(ws) { console.log("disconnected"); },
},
});
Bun.file and Bun.write are optimized alternatives to node:fs.
const file = Bun.file("data.json");
const text = await file.text();
const json = await file.json();
const exists = await file.exists();
console.log(file.size, file.type);
await Bun.write("output.txt", "hello world");
await Bun.write("data.json", JSON.stringify({ key: "value" }));
await Bun.write("copy.txt", Bun.file("original.txt"));
// Write a fetch response directly to disk
await Bun.write("image.png", await fetch("https://example.com/image.png"));
import { Database } from "bun:sqlite";
const db = new Database("app.db");
db.run(`CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL, email TEXT UNIQUE
)`);
const insert = db.prepare("INSERT INTO users (name, email) VALUES (?, ?)");
insert.run("Alice", "[email protected]");
const users = db.prepare("SELECT * FROM users WHERE name = ?").all("Alice");
const insertMany = db.transaction((entries) => {
for (const u of entries) insert.run(u.name, u.email);
});
insertMany([
{ name: "Bob", email: "[email protected]" },
{ name: "Carol", email: "[email protected]" },
]);
db.close();
Bun auto-loads .env files. No dotenv package needed.
const port = Bun.env.PORT ?? "3000";
const secret = process.env.SECRET_KEY; // process.env also works
Load order (later overrides earlier):
.env < .env.local < .env.${NODE_ENV} < .env.${NODE_ENV}.local < actual environment.
Custom env file: bun --env-file=.env.staging run server.ts
Works: node:fs, node:path, node:os, node:crypto, node:buffer, node:http, node:https,
node:stream, node:events, node:util, node:child_process, node:worker_threads.
CJS/ESM interop works. __dirname and __filename available in ESM. NAPI native addons supported.
Known gaps: node:vm (limited), node:dgram (partial), node:inspector (no), node:http2 (partial),
node:cluster (no). Some native addons may not work. See https://bun.sh/docs/runtime/nodejs-apis.
rm package-lock.json yarn.lock pnpm-lock.yamlbun install to generate bun.lockbnpx with bunx, node with bun in scripts# GitHub Actions
- uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- run: bun install
- run: bun test
- run: bun run build
bun test and fix any failures from unsupported Node.js APIs. You can still use node for specific scripts.{ "workspaces": ["packages/*", "apps/*"] }
bun install # Install all workspace deps
bun run --filter '@myorg/api' dev # Run script in workspace
bun add zod --filter '@myorg/api' # Add dep to workspace
Bun.serve({
port: Bun.env.PORT ?? 3000,
async fetch(req) {
const url = new URL(req.url);
if (url.pathname === "/api/users" && req.method === "GET") {
const db = new (await import("bun:sqlite")).Database("app.db");
return Response.json(db.prepare("SELECT * FROM users").all());
}
return new Response("Not Found", { status: 404 });
},
});
#!/usr/bin/env bun
const command = Bun.argv[2];
switch (command) {
case "init":
await Bun.write("config.json", JSON.stringify({ version: 1 }, null, 2));
break;
case "build":
const result = await Bun.build({ entrypoints: ["./src/index.ts"], outdir: "./dist" });
console.log(result.success ? "Build succeeded" : "Build failed");
break;
default:
console.log("Usage: mycli <init|build>");
}
Compile to standalone: bun build ./cli.ts --compile --outfile mycli
import { $ } from "bun";
await $`bun test`;
await $`bun run build`;
await $`docker build -t myapp .`;
await $`docker push myapp:latest`;
Run with bun run scripts/deploy.ts.
tools
Parallel execution with xargs, GNU parallel, and batch processing patterns. Use when user mentions "xargs", "parallel", "batch processing", "run in parallel", "parallel execution", "process list of files", "bulk operations", "concurrent commands", "map over files", or running commands on multiple inputs.
development
WebSocket implementation for real-time bidirectional communication. Use when user mentions "websocket", "ws://", "wss://", "real-time", "live updates", "chat application", "socket.io", "Server-Sent Events", "SSE", "push notifications", "live data", "streaming data", "bidirectional communication", "websocket server", "reconnection", or building real-time features.
tools
Frontend bundler configuration for Webpack and Vite. Use when user mentions "webpack", "vite", "bundler", "vite config", "webpack config", "code splitting", "tree shaking", "hot module replacement", "HMR", "build optimization", "bundle size", "chunk splitting", "loader", "plugin", "esbuild", "rollup", "dev server", or configuring JavaScript build tools.
tools
VS Code configuration, extensions, keybindings, and workspace optimization. Use when user mentions "vscode", "vs code", "vscode settings", "vscode extensions", "keybindings", "code editor", "workspace settings", "settings.json", "launch.json", "tasks.json", "vscode snippets", "devcontainer", "remote development", or customizing their VS Code setup.