bun-runtime-expert ยท diff
git:20260612.8b09a53 to git:20260614.78a2809
105 added, 439 removed. Audit C to B.
---
name: bun-runtime-expert
- description: "Expert skill for the Bun JavaScript/TypeScript runtime. Use when building, testing, or deploying applications with Bun, migrating from Node.js, or leveraging Bun's built-in APIs (Bun.serve, Bun.sql, Bun.s3, bun:test)."
+ description: "Panduan ahli untuk runtime JavaScript/TypeScript Bun. Digunakan saat membuat, menguji, atau meluncurkan aplikasi dengan Bun / Expert guide for Bun JavaScript/TypeScript runtime. Use when building, testing, or deploying applications with Bun."
author: "Roedy Rustam"
---
# Bun Runtime Expert
- Expert-level guidance for building high-performance applications with the Bun JavaScript/TypeScript runtime (v1.3+). Covers Bun's built-in HTTP server, database clients, bundler, test runner, package manager, and Node.js migration strategies.
+ [Bahasa Indonesia](#bahasa-indonesia) | [English](#english)
- ## Kondisi Pemicu
+ ---
- - Use when scaffolding a new project with Bun as the runtime.
- - Use when building HTTP servers or APIs with `Bun.serve()`.
- - Use when querying databases with `Bun.sql` (PostgreSQL, MySQL, SQLite).
- - Use when interacting with S3-compatible object storage via `Bun.s3`.
- - Use when bundling frontend or backend code with `bun build`.
- - Use when writing tests with `bun:test`.
- - Use when migrating an existing Node.js project to Bun.
- - Use when optimizing package installation speed or lockfile management.
+ <a name="bahasa-indonesia"></a>
+ ## Bahasa Indonesia
- ---
+ Panduan tingkat ahli untuk membangun aplikasi berkinerja tinggi menggunakan runtime JavaScript/TypeScript Bun (v1.1+). Mencakup server HTTP bawaan, klien database, bundler, test runner, package manager, dan strategi migrasi dari Node.js.
- ## Core Architecture
+ ### Kondisi Pemicu
+ - Gunakan saat merancang proyek baru menggunakan Bun sebagai runtime.
+ - Gunakan saat membangun server HTTP atau API dengan `Bun.serve()`.
+ - Gunakan saat melakukan query database dengan `Bun.sql` (PostgreSQL, MySQL, SQLite).
+ - Gunakan saat berinteraksi dengan object storage yang kompatibel dengan S3 via `Bun.s3`.
+ - Gunakan saat membundel kode frontend atau backend dengan `bun build`.
+ - Gunakan saat menulis pengujian (testing) menggunakan `bun:test`.
+ - Gunakan saat memigrasikan proyek Node.js ke Bun.
+ - Gunakan saat mengoptimalkan kecepatan instalasi paket atau manajemen lockfile.
- ### Why Bun?
+ ### Arsitektur Inti
- Bun is a batteries-included JavaScript/TypeScript runtime that replaces Node.js, npm, Webpack/Vite, and Jest in a single binary:
+ #### Mengapa Bun?
+ Bun adalah runtime JavaScript/TypeScript serba ada yang menggantikan Node.js, npm, Webpack/Vite, dan Jest dalam satu berkas biner tunggal:
- | Capability | Bun Built-in | Node.js Equivalent |
+ | Kemampuan | Bawaan Bun | Setara di Node.js |
|---|---|---|
| Runtime | `bun run` | `node` |
| Package Manager | `bun install` | `npm` / `pnpm` / `yarn` |
| Bundler | `bun build` | Webpack / Vite / esbuild |
| Test Runner | `bun test` | Jest / Vitest |
| HTTP Server | `Bun.serve()` | Express / Fastify |
| SQL Client | `Bun.sql` | `pg` / `mysql2` / `better-sqlite3` |
| S3 Client | `Bun.s3` | `@aws-sdk/client-s3` |
| Redis Client | Built-in | `ioredis` |
- | TypeScript | Native (zero config) | `ts-node` / `tsx` |
+ | TypeScript | Native (tanpa config) | `ts-node` / `tsx` |
| `.env` loading | Native | `dotenv` |
- ---
-
- ## Quick Start
-
- ### 1. Install Bun
+ ### Memulai Cepat
+ #### 1. Instal Bun
```bash
- # macOS / Linux
- curl -fsSL https://bun.sh/install | bash
-
# Windows (PowerShell)
powershell -c "irm bun.sh/install.ps1 | iex"
- # Verify installation
+ # macOS / Linux
+ curl -fsSL https://bun.sh/install | bash
+
+ # Verifikasi instalasi
bun --version
```
- ### 2. Initialize a New Project
-
+ #### 2. Inisialisasi Proyek Baru
```bash
bun init
```
-
- This generates `package.json`, `tsconfig.json`, and an `index.ts` entry point. TypeScript works out of the box with zero configuration.
-
- ### 3. Install Dependencies
+ Ini menghasilkan `package.json`, `tsconfig.json`, dan file entry point `index.ts`. TypeScript langsung berfungsi tanpa konfigurasi tambahan.
+ #### 3. Instal Dependensi
```bash
- # Install all dependencies (10-100x faster than npm)
+ # Menginstal semua dependensi (10-100x lebih cepat dari npm)
bun install
- # Add a package
+ # Menambahkan paket
bun add hono zod drizzle-orm
- # Add dev dependency
+ # Menambahkan dev dependency
bun add -d @types/bun vitest
```
- ---
-
- ## Bun.serve() โ High-Performance HTTP Server
-
- `Bun.serve()` is a zero-dependency HTTP server with built-in TLS, WebSocket support, and hot module reloading.
-
- ### Basic HTTP Server
+ ### Bun.serve() โ HTTP Server Berkinerja Tinggi
+ `Bun.serve()` adalah server HTTP tanpa dependensi eksternal dengan dukungan TLS bawaan, WebSocket, dan hot module reloading.
+ #### Server HTTP Dasar
```typescript
- // server.ts
Bun.serve({
port: 3000,
fetch(req) {
const url = new URL(req.url);
-
if (url.pathname === '/api/health') {
return Response.json({ status: 'ok', runtime: 'bun' });
}
-
- if (url.pathname === '/api/users' && req.method === 'POST') {
- return handleCreateUser(req);
- }
-
return new Response('Not Found', { status: 404 });
},
});
-
- console.log('๐ Server running at http://localhost:3000');
-
- async function handleCreateUser(req: Request): Promise<Response> {
- const body = await req.json();
- // validate & persist...
- return Response.json({ id: crypto.randomUUID(), ...body }, { status: 201 });
- }
```
- ### WebSocket Server
-
- ```typescript
- Bun.serve({
- port: 3000,
- fetch(req, server) {
- // Upgrade HTTP to WebSocket
- if (server.upgrade(req)) {
- return; // Upgrade succeeded
- }
- return new Response('Upgrade failed', { status: 500 });
- },
- websocket: {
- open(ws) {
- console.log('Client connected');
- ws.subscribe('chat');
- },
- message(ws, message) {
- // Broadcast to all subscribers
- ws.publish('chat', `User: ${message}`);
- },
- close(ws) {
- console.log('Client disconnected');
- },
- },
- });
- ```
-
- ### Using Hono Framework (Recommended for APIs)
-
- ```typescript
- // server.ts
- import { Hono } from 'hono';
- import { cors } from 'hono/cors';
- import { zValidator } from '@hono/zod-validator';
- import { z } from 'zod';
-
- const app = new Hono();
-
- app.use('/*', cors());
-
- const createUserSchema = z.object({
- email: z.string().email(),
- name: z.string().min(2),
- });
-
- app.get('/api/health', (c) => c.json({ status: 'ok' }));
-
- app.post('/api/users', zValidator('json', createUserSchema), async (c) => {
- const data = c.req.valid('json');
- // persist user...
- return c.json({ id: crypto.randomUUID(), ...data }, 201);
- });
-
- export default app; // Bun auto-detects default export as Bun.serve handler
- ```
-
- ---
-
- ## Bun.sql โ Unified Database Client
-
- Zero-dependency SQL client supporting PostgreSQL, MySQL/MariaDB, and SQLite via tagged template literals.
-
- ### PostgreSQL
+ ### Bun.sql โ Klien Database Terpadu
+ Klien SQL tanpa dependensi eksternal yang mendukung PostgreSQL, MySQL/MariaDB, dan SQLite melalui tagged template literals.
+ #### PostgreSQL
```typescript
import { sql } from 'bun';
-
- // Connection is automatically configured from DATABASE_URL env var
- // or you can pass options explicitly:
- // const sql = new Bun.SQL({ url: 'postgres://user:pass@localhost:5432/mydb' });
-
- // Simple query
const users = await sql`SELECT * FROM users WHERE active = ${true}`;
-
- // Insert with returning
- const [newUser] = await sql`
- INSERT INTO users (email, name)
- VALUES (${email}, ${name})
- RETURNING *
- `;
-
- // Transaction
- await sql.begin(async (tx) => {
- const [workspace] = await tx`
- INSERT INTO workspaces (name, slug) VALUES (${name}, ${slug}) RETURNING *
- `;
- await tx`
- INSERT INTO workspace_members (workspace_id, user_id, role)
- VALUES (${workspace.id}, ${userId}, 'admin')
- `;
- });
```
- ### SQLite (Embedded)
-
- ```typescript
- import { Database } from 'bun:sqlite';
-
- const db = new Database('app.db');
-
- // WAL mode for better concurrent read performance
- db.run('PRAGMA journal_mode = WAL');
-
- // Prepared statements (fast & safe)
- const getUser = db.prepare('SELECT * FROM users WHERE id = ?');
- const user = getUser.get(userId);
-
- // Batch insert with transaction
- const insertUser = db.prepare('INSERT INTO users (email, name) VALUES (?, ?)');
- const insertMany = db.transaction((users: { email: string; name: string }[]) => {
- for (const u of users) insertUser.run(u.email, u.name);
- });
-
- insertMany([
- { email: 'a@test.com', name: 'Alice' },
- { email: 'b@test.com', name: 'Bob' },
- ]);
- ```
+ ### Praktik Terbaik
+ - **Performa:** Gunakan `Bun.serve()` secara langsung atau bersama Hono โ hindari Express (karena lapisan kompatibilitasnya lebih lambat). Gunakan `Bun.file()` untuk I/O file yang efisien.
+ - **Keamanan:** Selalu gunakan parameterisasi query melalui template literals di `Bun.sql` untuk mencegah SQL Injection secara otomatis.
+ - **Pengujian:** Gunakan `bun:test` yang kompatibel dengan Jest namun jauh lebih cepat.
---
- ## Bun.s3 โ Object Storage Client
-
- Built-in S3-compatible client for AWS S3, Cloudflare R2, MinIO, and other providers.
-
- ```typescript
- import { s3 } from 'bun';
-
- // Configure via env: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION, S3_BUCKET
-
- // Upload a file
- const file = Bun.file('./report.pdf');
- await s3.write('reports/2026/q1.pdf', file);
-
- // Download a file
- const data = await s3.file('reports/2026/q1.pdf').text();
-
- // Generate presigned URL
- const url = s3.presign('reports/2026/q1.pdf', {
- expiresIn: 3600, // 1 hour
- });
+ <a name="english"></a>
+ ## English
- // List objects
- const objects = await s3.list({ prefix: 'reports/' });
+ Expert-level guidance for building high-performance applications with the Bun JavaScript/TypeScript runtime (v1.1+). Covers Bun's built-in HTTP server, database clients, bundler, test runner, package manager, and Node.js migration strategies.
- // Delete
- await s3.delete('reports/old.pdf');
- ```
+ ### Trigger Conditions
+ - Use when scaffolding a new project with Bun as the runtime.
+ - Use when building HTTP servers or APIs with `Bun.serve()`.
+ - Use when querying databases with `Bun.sql` (PostgreSQL, MySQL, SQLite).
+ - Use when interacting with S3-compatible object storage via `Bun.s3`.
+ - Use when bundling frontend or backend code with `bun build`.
+ - Use when writing tests with `bun:test`.
+ - Use when migrating an existing Node.js project to Bun.
+ - Use when optimizing package installation speed or lockfile management.
- ---
+ ### Core Architecture
- ## bun build โ Bundler
+ #### Why Bun?
+ Bun is a batteries-included JavaScript/TypeScript runtime that replaces Node.js, npm, Webpack/Vite, and Jest in a single binary:
- Bun's built-in bundler replaces Webpack, Vite, and esbuild for most use cases.
+ | Capability | Bun Built-in | Node.js Equivalent |
+ |---|---|---|
+ | Runtime | `bun run` | `node` |
+ | Package Manager | `bun install` | `npm` / `pnpm` / `yarn` |
+ | Bundler | `bun build` | Webpack / Vite / esbuild |
+ | Test Runner | `bun test` | Jest / Vitest |
+ | HTTP Server | `Bun.serve()` | Express / Fastify |
+ | SQL Client | `Bun.sql` | `pg` / `mysql2` / `better-sqlite3` |
+ | S3 Client | `Bun.s3` | `@aws-sdk/client-s3` |
+ | Redis Client | Built-in | `ioredis` |
+ | TypeScript | Native (zero config) | `ts-node` / `tsx` |
+ | `.env` loading | Native | `dotenv` |
- ### Bundle for Production
+ ### Quick Start
+ #### 1. Install Bun
```bash
- # Bundle a single entry point
- bun build ./src/index.ts --outdir ./dist --minify
-
- # Bundle with multiple entry points
- bun build ./src/index.ts ./src/worker.ts --outdir ./dist --splitting --minify
-
- # Target browser
- bun build ./src/app.tsx --outdir ./public/js --target browser --minify
- ```
-
- ### Programmatic Build API
+ # macOS / Linux
+ curl -fsSL https://bun.sh/install | bash
- ```typescript
- const result = await Bun.build({
- entrypoints: ['./src/index.ts'],
- outdir: './dist',
- target: 'bun', // 'bun' | 'browser' | 'node'
- minify: true,
- splitting: true,
- sourcemap: 'external',
- external: ['postgres'], // Don't bundle native modules
- });
+ # Windows (PowerShell)
+ powershell -c "irm bun.sh/install.ps1 | iex"
- if (!result.success) {
- console.error('Build failed:');
- for (const log of result.logs) {
- console.error(log);
- }
- }
+ # Verify installation
+ bun --version
```
- ### HTML Imports (Zero-Config Frontend)
-
+ #### 2. Initialize a New Project
```bash
- # Serve an HTML file with auto-bundled JS/CSS
- bun ./index.html
- ```
-
- Bun automatically transpiles, bundles, and serves all referenced `<script>` and `<link>` tags, including React/JSX support.
-
- ---
-
- ## bun:test โ Test Runner
-
- Jest-compatible test runner with native TypeScript support, lifecycle hooks, and snapshot testing.
-
- ### Writing Tests
-
- ```typescript
- // __tests__/math.test.ts
- import { describe, it, expect, beforeAll, afterAll } from 'bun:test';
-
- describe('Math utilities', () => {
- it('should add numbers correctly', () => {
- expect(1 + 2).toBe(3);
- });
-
- it('should handle floating point', () => {
- expect(0.1 + 0.2).toBeCloseTo(0.3);
- });
- });
- ```
-
- ### HTTP API Integration Tests
-
- ```typescript
- // __tests__/api.test.ts
- import { describe, it, expect, beforeAll, afterAll } from 'bun:test';
- import app from '../src/server';
-
- describe('Users API', () => {
- let server: ReturnType<typeof Bun.serve>;
-
- beforeAll(() => {
- server = Bun.serve({ port: 0, fetch: app.fetch }); // Random port
- });
-
- afterAll(() => {
- server.stop();
- });
-
- it('POST /api/users should create a user', async () => {
- const res = await fetch(`http://localhost:${server.port}/api/users`, {
- method: 'POST',
- headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify({ email: 'test@example.com', name: 'Test User' }),
- });
-
- expect(res.status).toBe(201);
- const body = await res.json();
- expect(body).toHaveProperty('id');
- expect(body.email).toBe('test@example.com');
- });
-
- it('GET /api/health should return ok', async () => {
- const res = await fetch(`http://localhost:${server.port}/api/health`);
- expect(res.status).toBe(200);
- const body = await res.json();
- expect(body.status).toBe('ok');
- });
- });
+ bun init
```
-
- ### Running Tests
+ This generates `package.json`, `tsconfig.json`, and an `index.ts` entry point. TypeScript works out of the box with zero configuration.
+ #### 3. Install Dependencies
```bash
- # Run all tests
- bun test
-
- # Run specific file
- bun test __tests__/api.test.ts
-
- # Watch mode
- bun test --watch
-
- # With coverage
- bun test --coverage
-
- # Concurrent tests
- bun test --concurrency 4
- ```
-
- ---
-
- ## Node.js Migration Guide
-
- ### Step-by-Step Migration
-
- 1. **Replace runtime:** Change `node` โ `bun` in your scripts.
- 2. **Replace package manager:** Change `npm install` โ `bun install`.
- 3. **Remove unnecessary devDependencies:**
- - `typescript` / `ts-node` / `tsx` โ Bun handles TypeScript natively.
- - `dotenv` โ Bun loads `.env` automatically.
- - `jest` / `vitest` โ Use `bun:test`.
- - `esbuild` / `webpack` โ Use `bun build`.
- - `nodemon` โ Use `bun --watch`.
+ # Install all dependencies (10-100x faster than npm)
+ bun install
- 4. **Update `package.json` scripts:**
+ # Add a package
+ bun add hono zod drizzle-orm
- ```json
- {
- "scripts": {
- "dev": "bun --watch src/index.ts",
- "start": "bun src/index.ts",
- "build": "bun build ./src/index.ts --outdir ./dist --target bun --minify",
- "test": "bun test",
- "test:watch": "bun test --watch"
- }
- }
+ # Add dev dependency
+ bun add -d @types/bun vitest
```
- 5. **Check Node.js API compatibility:** Most `node:*` APIs are supported. Check [bun.sh/docs/runtime/nodejs-apis](https://bun.sh/docs/runtime/nodejs-apis) for the compatibility matrix.
-
- ### Common Migration Patterns
+ ### Bun.serve() โ High-Performance HTTP Server
+ `Bun.serve()` is a zero-dependency HTTP server with built-in TLS, WebSocket support, and hot module reloading.
+ #### Basic HTTP Server
```typescript
- // Node.js (before)
- import express from 'express';
- const app = express();
- app.get('/health', (req, res) => res.json({ ok: true }));
- app.listen(3000);
-
- // Bun (after) โ zero dependencies
Bun.serve({
port: 3000,
fetch(req) {
- if (new URL(req.url).pathname === '/health') {
- return Response.json({ ok: true });
+ const url = new URL(req.url);
+ if (url.pathname === '/api/health') {
+ return Response.json({ status: 'ok', runtime: 'bun' });
}
return new Response('Not Found', { status: 404 });
},
});
```
- ```typescript
- // Node.js file read (before)
- import fs from 'node:fs/promises';
- const content = await fs.readFile('./data.json', 'utf-8');
-
- // Bun file read (after) โ also supports node:fs
- const content = await Bun.file('./data.json').text();
- const json = await Bun.file('./data.json').json();
- ```
-
- ---
-
- ## Project Structure (Recommended)
-
- ```
- my-bun-app/
- โโโ src/
- โ โโโ index.ts # Entry point (Bun.serve or Hono app)
- โ โโโ routes/ # Route handlers
- โ โโโ middleware/ # Auth, CORS, rate limiting
- โ โโโ db/
- โ โ โโโ schema.ts # Drizzle ORM schema
- โ โ โโโ migrate.ts # Migration runner
- โ โ โโโ index.ts # Database client (Bun.sql or Drizzle)
- โ โโโ services/ # Business logic
- โ โโโ utils/ # Shared utilities
- โโโ __tests__/ # bun:test files
- โโโ .env # Environment variables (auto-loaded)
- โโโ bunfig.toml # Bun configuration
- โโโ tsconfig.json # TypeScript config
- โโโ bun.lock # Lockfile (JSONC-based, human-readable)
- โโโ package.json
- ```
-
- ### bunfig.toml Configuration
-
- ```toml
- [install]
- # Use exact versions by default
- exact = true
-
- [test]
- # Enable coverage by default
- coverage = true
- coverageDir = "coverage"
+ ### Bun.sql โ Unified Database Client
+ Zero-dependency SQL client supporting PostgreSQL, MySQL/MariaDB, and SQLite via tagged template literals.
- [run]
- # Auto-reload on file changes in development
- watch = true
+ #### PostgreSQL
+ ```typescript
+ import { sql } from 'bun';
+ const users = await sql`SELECT * FROM users WHERE active = ${true}`;
```
- ---
-
- ## Best Practices
-
- ### Performance
- - โ
Use `Bun.serve()` directly or Hono for HTTP โ avoid Express (slower compat layer).
- - โ
Use `Bun.sql` with tagged templates for parameterized, injection-safe queries.
- - โ
Use `Bun.file()` for file I/O โ it returns a lazy `BunFile` that streams efficiently.
- - โ
Use `bun build --minify --splitting` for production frontend bundles.
- - โ
Use `--watch` flag during development instead of `nodemon`.
-
- ### Security
- - โ
Always parameterize queries via template literals in `Bun.sql` (automatically prevents SQL injection).
- - โ
Validate all request bodies with Zod before processing.
- - โ
Use Bun's built-in package security scanner to audit dependencies.
- - โ Never concatenate user input into SQL strings manually.
-
- ### Testing
- - โ
Use `bun:test` โ it's Jest-compatible and significantly faster.
- - โ
Use `Bun.serve({ port: 0 })` in tests for random port allocation (prevents port conflicts).
- - โ
Run `bun test --coverage` to track coverage metrics.
-
- ---
-
- ## Troubleshooting
-
- **Problem:** `bun install` fails with native module compilation errors
- **Solution:** Some Node.js native addons (e.g., `bcrypt`, `sharp`) require specific platform binaries. Use `bun add sharp --force` or switch to pure-JS alternatives (`bcryptjs` instead of `bcrypt`).
-
- **Problem:** TypeScript types not recognized for Bun APIs
- **Solution:** Add `"types": ["bun-types"]` to your `tsconfig.json` `compilerOptions`, or run `bun add -d @types/bun`.
-
- **Problem:** Module not found errors for `node:*` imports
- **Solution:** Bun supports most `node:*` prefixed imports. Check the [compatibility table](https://bun.sh/docs/runtime/nodejs-apis). For unsupported modules, use Bun's native alternatives (e.g., `Bun.file()` instead of `fs`).
-
- **Problem:** Hot reload not working with `--watch`
- **Solution:** Ensure you're running `bun --watch src/index.ts` (not `bun run --watch`). The `--watch` flag must come before the file path.
+ ### Best Practices
+ - **Performance:** Use `Bun.serve()` directly or Hono for HTTP โ avoid Express (slower compat layer). Use `Bun.file()` for efficient file I/O.
+ - **Security:** Always parameterize queries via template literals in `Bun.sql` (automatically prevents SQL injection).
+ - **Testing:** Use `bun:test` โ it's Jest-compatible and significantly faster.
---
- ## Limitations
+ ### Limitations / Batasan
- Use this skill only when the task involves the Bun runtime specifically.
- - Bun's Node.js compatibility is extensive but not 100%. Always verify critical `node:*` API usage against the official compatibility matrix.
- - Some npm packages with native C/C++ bindings may require platform-specific handling.
- - Stop and ask for clarification if the user's project has strict Node.js-only requirements.
+ - Bun's Node.js compatibility is extensive but not 100%. Always verify critical `node:*` API usage.