| name | bun-development |
| description | Modern JavaScript/TypeScript development with Bun runtime. Covers package management, bundling, testing, and migration from Node.js. Use when working with Bun, optimizing JS/TS development speed, o... |
| risk | unknown |
| source | community |
| date_added | 2026-02-27 |
⚡ Bun Development
Fast, modern JavaScript/TypeScript development with the Bun runtime, inspired by oven-sh/bun.
When to Use This Skill
Use this skill when:
- Starting new JS/TS projects with Bun
- Migrating from Node.js to Bun
- Optimizing development speed
- Using Bun's built-in tools (bundler, test runner)
- Troubleshooting Bun-specific issues
1. Getting Started
1.1 Installation
curl -fsSL https://bun.sh/install | bash
powershell -c "irm bun.sh/install.ps1 | iex"
brew tap oven-sh/bun
brew install bun
npm install -g bun
bun upgrade
1.2 Why Bun?
| Feature | Bun | Node.js |
|---|
| Startup time | ~25ms | ~100ms+ |
| Package install | 10-100x faster | Baseline |
| TypeScript | Native | Requires transpiler |
| JSX | Native | Requires transpiler |
| Test runner | Built-in | External (Jest, Vitest) |
| Bundler | Built-in | External (Webpack, esbuild) |
2. Project Setup
2.1 Create New Project
bun init
bun create <template> <project-name>
bun create react my-app
bun create next my-app
bun create vite my-app
bun create elysia my-api
2.2 package.json
{
"name": "my-bun-project",
"version": "1.0.0",
"module": "index.ts",
"type": "module",
"scripts": {
"dev": "bun run --watch index.ts",
"start": "bun run index.ts",
"test": "bun test",
"build": "bun build ./index.ts --outdir ./dist",
"lint": "bunx eslint ."
},
"devDependencies": {
"@types/bun": "latest"
},
"peerDependencies": {
"typescript": "^5.0.0"
}
}
2.3 tsconfig.json (Bun-optimized)
{
"compilerOptions": {
"lib": ["ESNext"],
"module": "esnext",
"target": "esnext",
"moduleResolution": "bundler",
"moduleDetection": "force",
"allowImportingTsExtensions": true,
"noEmit": true,
"composite": true,
"strict": true,
"downlevelIteration": true,
"skipLibCheck": true,
"jsx": "react-jsx",
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true,
"allowJs": true,
"types": ["bun-types"]
}
}
3. Package Management
3.1 Installing Packages
bun install
bun add express
bun add -d typescript
bun add -D @types/node
bun add --optional pkg
bun add lodash --registry https://registry.npmmirror.com
bun add react@18.2.0
bun add react@latest
bun add react@next
bun add github:user/repo
bun add git+https://github.com/user/repo.git
3.2 Removing & Updating
bun remove lodash
bun update
bun update lodash
bun update --latest
bun outdated
3.3 bunx (npx equivalent)
bunx prettier --write .
bunx tsc --init
bunx create-react-app my-app
bunx -p typescript@4.9 tsc --version
bunx cowsay "Hello from Bun!"
3.4 Lockfile
bun install --yarn
bun install --frozen-lockfile
4. Running Code
4.1 Basic Execution
bun run index.ts
bun run index.js
bun run server.ts --port 3000
bun run dev
bun run build
bun dev
bun build
4.2 Watch Mode
bun --watch run index.ts
bun --hot run server.ts
4.3 Environment Variables
const apiKey = Bun.env.API_KEY;
const port = Bun.env.PORT ?? '3000';
const dbUrl = process.env.DATABASE_URL;
bun --env-file=.env.production run index.ts
5. Built-in APIs
5.1 File System (Bun.file)
const file = Bun.file('./data.json');
const text = await file.text();
const json = await file.json();
const buffer = await file.arrayBuffer();
console.log(file.size);
console.log(file.type);
await Bun.write('./output.txt', 'Hello, Bun!');
await Bun.write('./data.json', JSON.stringify({ foo: 'bar' }));
const reader = file.stream();
for await (const chunk of reader) {
console.log(chunk);
}
5.2 HTTP Server (Bun.serve)
const server = Bun.serve({
port: 3000,
fetch(request) {
const url = new URL(request.url);
if (url.pathname === '/') {
return new Response('Hello World!');
}
if (url.pathname === '/api/users') {
return Response.json([
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' },
]);
}
return new Response('Not Found', { status: 404 });
},
error(error) {
return new Response(`Error: ${error.message}`, { status: 500 });
},
});
console.log(`Server running at http://localhost:${server.port}`);
5.3 WebSocket Server
const server = Bun.serve({
port: 3000,
fetch(req, server) {
if (server.upgrade(req)) {
return;
}
return new Response('Upgrade failed', { status: 500 });
},
websocket: {
open(ws) {
console.log('Client connected');
ws.send('Welcome!');
},
message(ws, message) {
console.log(`Received: ${message}`);
ws.send(`Echo: ${message}`);
},
close(ws) {
console.log('Client disconnected');
},
},
});
5.4 SQLite (Bun.sql)
import { Database } from 'bun:sqlite';
const db = new Database('mydb.sqlite');
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', 'alice@example.com');
const query = db.prepare('SELECT * FROM users WHERE name = ?');
const user = query.get('Alice');
console.log(user);
const allUsers = db.query('SELECT * FROM users').all();
5.5 Password Hashing
const password = 'super-secret';
const hash = await Bun.password.hash(password);
const isValid = await Bun.password.verify(password, hash);
console.log(isValid);
const bcryptHash = await Bun.password.hash(password, {
algorithm: 'bcrypt',
cost: 12,
});
6. Testing
6.1 Basic Tests
import { describe, it, expect, beforeAll, afterAll } from 'bun:test';
describe('Math operations', () => {
it('adds two numbers', () => {
expect(1 + 1).toBe(2);
});
it('subtracts two numbers', () => {
expect(5 - 3).toBe(2);
});
});
6.2 Running Tests
bun test
bun test math.test.ts
bun test --grep "adds"
bun test --watch
bun test --coverage
bun test --timeout 5000
6.3 Matchers
import { expect, test } from 'bun:test';
test('matchers', () => {
expect(1).toBe(1);
expect({ a: 1 }).toEqual({ a: 1 });
expect([1, 2]).toContain(1);
expect(10).toBeGreaterThan(5);
expect(5).toBeLessThanOrEqual(5);
expect(true).toBeTruthy();
expect(null).toBeNull();
expect(undefined).toBeUndefined();
expect('hello').toMatch(/ell/);
expect('hello').toContain('ell');
expect([1, 2, 3]).toHaveLength(3);
expect(() => {
throw new Error('fail');
}).toThrow('fail');
await expect(Promise.resolve(1)).resolves.toBe(1);
await expect(Promise.reject('err')).rejects.toBe('err');
});
6.4 Mocking
import { mock, spyOn } from 'bun:test';
const mockFn = mock((x: number) => x * 2);
mockFn(5);
expect(mockFn).toHaveBeenCalled();
expect(mockFn).toHaveBeenCalledWith(5);
expect(mockFn.mock.results[0].value).toBe(10);
const obj = {
method: () => 'original',
};
const spy = spyOn(obj, 'method').mockReturnValue('mocked');
expect(obj.method()).toBe('mocked');
expect(spy).toHaveBeenCalled();
7. Bundling
7.1 Basic Build
bun build ./src/index.ts --outdir ./dist
bun build ./src/index.ts \
--outdir ./dist \
--target browser \
--minify \
--sourcemap
7.2 Build API
const result = await Bun.build({
entrypoints: ['./src/index.ts'],
outdir: './dist',
target: 'browser',
minify: true,
sourcemap: 'external',
splitting: true,
format: 'esm',
external: ['react', 'react-dom'],
define: {
'process.env.NODE_ENV': JSON.stringify('production'),
},
naming: {
entry: '[name].[hash].js',
chunk: 'chunks/[name].[hash].js',
asset: 'assets/[name].[hash][ext]',
},
});
if (!result.success) {
console.error(result.logs);
}
7.3 Compile to Executable
bun build ./src/cli.ts --compile --outfile myapp
bun build ./src/cli.ts --compile --target=bun-linux-x64 --outfile myapp-linux
bun build ./src/cli.ts --compile --target=bun-darwin-arm64 --outfile myapp-mac
bun build ./src/cli.ts --compile --outfile myapp --embed ./assets
8. Migration from Node.js
8.1 Compatibility
import fs from 'fs';
import path from 'path';
import crypto from 'crypto';
console.log(process.cwd());
console.log(process.env.HOME);
const buf = Buffer.from('hello');
console.log(__dirname);
console.log(__filename);
8.2 Common Migration Steps
curl -fsSL https://bun.sh/install | bash
rm -rf node_modules package-lock.json
bun install
bun add -d @types/bun
8.3 Differences from Node.js
require("module")
require.resolve("pkg")
__non_webpack_require__
import pkg from "pkg";
const resolved = import.meta.resolve("pkg");
Bun.resolveSync("pkg", process.cwd());
process.hrtime()
setImmediate()
const file = Bun.file("./data.txt");
Bun.serve({ port: 3000, fetch: ... });
Bun.password.hash(password);
9. Performance Tips
9.1 Use Bun-native APIs
import fs from 'fs/promises';
const content = await fs.readFile('./data.txt', 'utf-8');
const file = Bun.file('./data.txt');
const content = await file.text();
9.2 Use Bun.serve for HTTP
import express from 'express';
const app = express();
Bun.serve({
fetch(req) {
return new Response('Hello!');
},
});
import { Elysia } from 'elysia';
new Elysia().get('/', () => 'Hello!').listen(3000);
9.3 Bundle for Production
bun build ./src/index.ts --outdir ./dist --minify --target node
bun run ./dist/index.js
Quick Reference
| Task | Command |
|---|
| Init project | bun init |
| Install deps | bun install |
| Add package | bun add <pkg> |
| Run script | bun run <script> |
| Run file | bun run file.ts |
| Watch mode | bun --watch run file.ts |
| Run tests | bun test |
| Build | bun build ./src/index.ts --outdir ./dist |
| Execute pkg | bunx <pkg> |
Resources