Bun runtime expert
Expert skill for the Bun JavaScript/TypeScript runtime. Use whenever the user is building, running, or debugging code with Bun — covering Bun.serve (HTTP server), Bun.sql (PostgreSQL), Bun.s3 (object storage), bun:test (testing), the Bun bundler, and package manager. Trigger on any mention of Bun, bun install, bun run, Bun.serve, Bun.file, Bun.sql, bun:test, or when the user wants a fast Node.js alternative. Also trigger for Bun shell scripting or Bun-specific APIs.From its SKILL.md
npx -y skills add roedyrustam/claudevibeskills --skill bun-runtime-expertAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
9.2 KB, ~2.4k tokens by cl100k_base, as published. Nobody here has run it
Bun Runtime Expert
Fast, all-in-one JavaScript/TypeScript runtime — server, bundler, package manager, test runner.
Why Bun
| Feature | Bun | Node.js |
|---|---|---|
| Startup time | ~5ms | ~50ms |
bun install | ~100ms | npm: ~3s |
| Built-in SQLite | ✅ | ❌ |
| Built-in test runner | ✅ | ❌ (need Jest) |
| Built-in bundler | ✅ | ❌ (need webpack) |
| TypeScript natively | ✅ | ❌ (need ts-node) |
| Web APIs (fetch, Request) | ✅ native | Partial |
HTTP Server — Bun.serve
Basic Server
const server = Bun.serve({
port: 3000,
hostname: "0.0.0.0",
async fetch(req: Request): Promise<Response> {
const url = new URL(req.url)
if (url.pathname === "/health") {
return Response.json({ status: "ok" })
}
if (url.pathname === "/api/users" && req.method === "GET") {
const users = await getUsers()
return Response.json(users)
}
if (url.pathname === "/api/users" && req.method === "POST") {
const body = await req.json()
const user = await createUser(body)
return Response.json(user, { status: 201 })
}
return new Response("Not Found", { status: 404 })
},
error(err: Error): Response {
console.error(err)
return Response.json({ error: "Internal Server Error" }, { status: 500 })
},
})
console.log(`Server running at http://localhost:${server.port}`)
Router Pattern
type Handler = (req: Request, params: Record<string, string>) => Promise<Response>
class Router {
private routes = new Map<string, Handler>()
add(method: string, path: string, handler: Handler) {
this.routes.set(`${method}:${path}`, handler)
return this
}
get(path: string, handler: Handler) { return this.add("GET", path, handler) }
post(path: string, handler: Handler) { return this.add("POST", path, handler) }
put(path: string, handler: Handler) { return this.add("PUT", path, handler) }
delete(path: string, handler: Handler) { return this.add("DELETE", path, handler) }
async handle(req: Request): Promise<Response> {
const url = new URL(req.url)
const key = `${req.method}:${url.pathname}`
const handler = this.routes.get(key)
if (!handler) return new Response("Not Found", { status: 404 })
return handler(req, {})
}
}
const router = new Router()
.get("/api/posts", listPosts)
.post("/api/posts", createPost)
.get("/api/posts/:id", getPost)
Bun.serve({ fetch: req => router.handle(req) })
WebSocket Support
Bun.serve({
fetch(req, server) {
if (server.upgrade(req)) return // Upgraded to WS
return new Response("HTTP response")
},
websocket: {
open(ws) {
ws.subscribe("chat")
ws.send(JSON.stringify({ type: "connected" }))
},
message(ws, message) {
// Broadcast to all subscribers
ws.publish("chat", message)
},
close(ws) {
ws.unsubscribe("chat")
},
},
})
Database — Bun.sql
PostgreSQL (Built-in, no driver needed)
import { sql } from "bun"
// Bun.sql uses tagged template literals — SQL injection safe
const users = await sql`SELECT * FROM users WHERE active = ${true}`
// With types
type User = { id: string; email: string; name: string }
const user = await sql<User[]>`
SELECT id, email, name
FROM users
WHERE email = ${email}
LIMIT 1
`
// Transactions
await sql.begin(async (tx) => {
const [newUser] = await tx<User[]>`
INSERT INTO users (email, name) VALUES (${email}, ${name})
RETURNING *
`
await tx`
INSERT INTO audit_log (user_id, action) VALUES (${newUser.id}, 'signup')
`
return newUser
})
// Configure connection
const db = new Bun.SQL({
url: process.env.DATABASE_URL,
max: 20, // pool size
idleTimeout: 30, // seconds
})
SQLite (Zero-config, built-in)
import { Database } from "bun:sqlite"
const db = new Database("mydb.sqlite")
// Prepare statements (reuse for performance)
const getUser = db.prepare<{ id: number; name: string }, [string]>(
"SELECT id, name FROM users WHERE email = ?"
)
const user = getUser.get("[email protected]")
// Transactions
const insertUser = db.prepare("INSERT INTO users (email, name) VALUES (?, ?)")
const insertLog = db.prepare("INSERT INTO logs (user_id) VALUES (?)")
const signup = db.transaction((email: string, name: string) => {
const info = insertUser.run(email, name)
insertLog.run(info.lastInsertRowid)
return info.lastInsertRowid
})
const id = signup("[email protected]", "Bob")
Object Storage — Bun.s3
// Configure (auto-reads AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY)
const s3 = new Bun.S3Client({
bucket: "my-bucket",
region: "us-east-1",
// Or use custom endpoint for R2/MinIO:
endpoint: "https://xxx.r2.cloudflarestorage.com",
})
// Upload
await s3.write("uploads/avatar.png", imageBuffer, {
type: "image/png",
acl: "public-read",
})
// Download
const file = s3.file("uploads/avatar.png")
const buffer = await file.arrayBuffer()
// Presigned URL
const url = await s3.presign("uploads/avatar.png", {
expiresIn: 3600, // 1 hour
method: "GET",
})
// Delete
await s3.delete("uploads/old-avatar.png")
// List
const objects = await s3.list({ prefix: "uploads/" })
Testing — bun:test
// math.test.ts
import { describe, it, expect, beforeEach, afterEach, mock, spyOn } from "bun:test"
describe("Calculator", () => {
it("adds two numbers", () => {
expect(1 + 2).toBe(3)
})
it("handles async operations", async () => {
const result = await fetchData("https://api.example.com")
expect(result).toMatchObject({ status: "ok" })
})
it("mocks functions", () => {
const mockFetch = mock(() => Promise.resolve({ ok: true }))
globalThis.fetch = mockFetch as any
// test code that calls fetch...
expect(mockFetch).toHaveBeenCalledTimes(1)
})
})
// Snapshot testing
it("renders correctly", () => {
const output = renderComponent()
expect(output).toMatchSnapshot()
})
# Run tests
bun test
# Watch mode
bun test --watch
# Coverage
bun test --coverage
# Filter by name
bun test --test-name-pattern "Calculator"
# Specific file
bun test math.test.ts
Bundler
// build.ts
await Bun.build({
entrypoints: ["./src/index.ts"],
outdir: "./dist",
target: "browser", // or "node" or "bun"
format: "esm", // or "cjs" or "iife"
splitting: true, // code splitting
minify: true,
sourcemap: "external",
define: {
"process.env.NODE_ENV": JSON.stringify("production"),
},
plugins: [
// Custom plugins (compatible with esbuild API)
],
})
# Build from CLI
bun build ./src/index.ts --outdir ./dist --minify
# Bundle to single file
bun build ./src/index.ts --outfile ./dist/bundle.js
Package Manager
# Install (fastest package manager)
bun install # install from package.json
bun add express # add dependency
bun add -d @types/bun # add devDependency
bun remove express # remove
bun update # update all
# Run scripts
bun run dev
bun run build
# Execute files
bun index.ts # run TypeScript directly
bun --watch index.ts # hot reload
# Workspaces
bun install # installs all workspace packages
bunfig.toml Configuration
[install]
registry = "https://registry.npmjs.org"
frozen = true # like --frozen-lockfile
[run]
bun = true # prefer bun over node for scripts
Bun Shell ($)
import { $ } from "bun"
// Run shell commands
const result = await $`ls -la`.text()
// Pipe
const count = await $`cat package.json | grep name`.text()
// Template with variables (auto-escaped)
const filename = "my file.txt"
await $`rm ${filename}` // safe: rm "my file.txt"
// Capture output
const { stdout, stderr, exitCode } = await $`git status`.quiet()
// Write file
await $`echo "hello" > output.txt`
// Script mode
await $`
mkdir -p dist
bun build ./src/index.ts --outdir dist
echo "Build complete"
`
Key Rules
- Use tagged template literals for SQL — never string concatenation (injection safe)
bun:testnot Jest — same API, 10x fasterBun.file()for file reads — lazy, streaming, faster thanfs.readFileResponse.json()notnew Response(JSON.stringify())— cleaner APIBun.serveerror handler — always defineerror()for uncaught handler errors- Pool connections — set
maxonBun.SQLfor production bun --watchfor development — built-in hot reload- TypeScript natively — no build step needed in development
bun buildfor production — minify + tree-shake before deployingbunxinstead ofnpx— runs package CLIs faster
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.