Bun runtime expert
Koleksi 20 Claude Skills siap pakai untuk pengembangan SaaS, web modern, dan praktik rekayasa perangkat lunak tingkat lanjut.
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.
What its author says it does
Copied from the file, not written here
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.
SKILL.md
9.2 KB, 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