Skip to content

Latest commit

 

History

History
308 lines (226 loc) · 5.58 KB

File metadata and controls

308 lines (226 loc) · 5.58 KB

Bun Cheat Sheet


Installation

# Install Bun
curl -fsSL https://bun.sh/install | bash

# Upgrade Bun
bun upgrade

# Check version
bun --version

Project Setup

# Create new project
bun init

# Create new Next.js project
bunx create-next-app@latest my-app

# Install dependencies
bun install

# Add a package
bun add express

# Add dev dependency
bun add -d typescript

# Remove a package
bun remove express

# Run a script
bun run dev
bun run build
bun run start

Running Files

# Run a file directly
bun index.ts
bun index.js

# Run with watch mode (auto restart)
bun --watch index.ts

# Run with hot reload
bun --hot index.ts

# Execute a one-liner
bun -e "console.log('hello')"

Package Management

Command Description
bun install Install all dependencies
bun add <pkg> Add a package
bun add -d <pkg> Add a dev dependency
bun add -g <pkg> Add a global package
bun remove <pkg> Remove a package
bun update Update all packages
bun update <pkg> Update specific package
bun pm ls List installed packages
bun pm cache rm Clear package cache

bun install is up to 25x faster than npm — uses a binary lockfile bun.lockb


Scripts (package.json)

{
  "scripts": {
    "dev": "bun --watch index.ts",
    "build": "bun build ./index.ts --outdir ./dist",
    "start": "bun index.ts",
    "test": "bun test"
  }
}
bun run dev
bun run build

Bundler

# Bundle for browser
bun build ./index.ts --outdir ./dist

# Bundle as single file
bun build ./index.ts --outfile bundle.js

# Minify output
bun build ./index.ts --outdir ./dist --minify

# Target specific environment
bun build ./index.ts --outdir ./dist --target browser
bun build ./index.ts --outdir ./dist --target node
bun build ./index.ts --outdir ./dist --target bun

# Watch mode
bun build ./index.ts --outdir ./dist --watch

HTTP Server (Built-in)

// No express needed — Bun has a built-in fast HTTP server
Bun.serve({
  port: 3000,
  fetch(req) {
    const url = new URL(req.url)

    if (url.pathname === '/') {
      return new Response('Hello World')
    }

    if (url.pathname === '/json') {
      return Response.json({ message: 'Hello' })
    }

    return new Response('Not Found', { status: 404 })
  },
})

console.log('Server running at http://localhost:3000')

File I/O (Built-in)

// Read file
const file = Bun.file('data.txt')
const text = await file.text()
const json = await file.json()
const buffer = await file.arrayBuffer()

// Write file
await Bun.write('output.txt', 'Hello World')
await Bun.write('data.json', JSON.stringify({ key: 'value' }))

// Check if file exists
const exists = await Bun.file('data.txt').exists()

// File size
const size = Bun.file('data.txt').size

Environment Variables

// Bun auto-loads .env, .env.local, .env.production
console.log(Bun.env.DATABASE_URL)
console.log(process.env.DATABASE_URL)  // also works
# .env
DATABASE_URL=postgres://localhost/mydb
API_KEY=secret123

No need for dotenv package — Bun loads .env automatically


Testing (Built-in)

// math.test.ts
import { test, expect, describe, beforeEach } from 'bun:test'

describe('math', () => {
  test('adds two numbers', () => {
    expect(1 + 1).toBe(2)
  })

  test('async test', async () => {
    const result = await Promise.resolve(42)
    expect(result).toBe(42)
  })
})
# Run all tests
bun test

# Run specific file
bun test math.test.ts

# Watch mode
bun test --watch

# Coverage
bun test --coverage

SQLite (Built-in)

// No external package needed
import { Database } from 'bun:sqlite'

const db = new Database('mydb.sqlite')

// Create table
db.run('CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT)')

// Insert
db.run('INSERT INTO users (name) VALUES (?)', ['Alice'])

// Query
const users = db.query('SELECT * FROM users').all()
console.log(users)

// Prepared statement
const getUser = db.query('SELECT * FROM users WHERE id = ?')
const user = getUser.get(1)

WebSocket (Built-in)

Bun.serve({
  port: 3000,
  fetch(req, server) {
    if (server.upgrade(req)) return   // upgrade to WebSocket
    return new Response('Not a WebSocket', { status: 400 })
  },
  websocket: {
    open(ws) { console.log('connected') },
    message(ws, msg) { ws.send(`echo: ${msg}`) },
    close(ws) { console.log('disconnected') },
  },
})

bunx (like npx)

# Run a package without installing
bunx cowsay "Hello"
bunx create-next-app@latest
bunx prettier --write .
bunx eslint .

Bun vs npm vs Node — Quick Comparison

Node + npm Bun
Runtime V8 JavaScriptCore
Install speed baseline up to 25x faster
TypeScript needs ts-node/tsx ✅ native, zero config
.env loading needs dotenv ✅ built-in
Test runner needs Jest/Vitest ✅ built-in
Bundler needs webpack/esbuild ✅ built-in
SQLite needs better-sqlite3 ✅ built-in
HTTP server needs express/fastify ✅ built-in
npm compatible ✅ fully compatible

Tips

  • Use bun --watch during development instead of nodemon
  • No need for ts-node, dotenv, jest — Bun replaces all of them
  • bun.lockb is binary — commit it to git, don't edit manually
  • Use bunx instead of npx for faster one-off package execution
  • Bun is a drop-in replacement — existing package.json scripts work as-is
  • For packages with known Bun issues (e.g. Qwen Code), fall back to npm install -g