Bun Runtime 後端開發完整教學:取代 Node.js 的下一代 JavaScript 運行環境
每隔幾年就會有人站出來說「Node.js 要被取代了」,然後通常什麼事都沒發生。但 Bun 這次不一樣——它不是一個實驗性的小玩具,而是一個真正有機會改變 JavaScript 後端生態的運行環境。
我在 2025 年底開始在幾個個人專案中使用 Bun,到 2026 年初已經把一個中型的 production 服務從 Node.js 遷移過來了。這篇會分享所有你需要知道的事——從技術原理到實戰開發,再到「到底該不該遷移」的務實判斷。
Bun 是什麼?為什麼它這麼快
Bun 是一個用 Zig 語言寫的 JavaScript/TypeScript 運行環境,由 Jarred Sumner 在 2022 年開始開發。它不只是一個 runtime,而是一個「全包」的工具鏈,集合了:
- JavaScript Runtime:執行 JS/TS 程式碼(替代 Node.js)
- 套件管理器:安裝 npm 套件(替代 npm/yarn/pnpm)
- 打包器:打包前端程式碼(替代 webpack/esbuild)
- 測試框架:跑測試(替代 Jest/Vitest)
為什麼快?核心原因有三個:
- 底層引擎不同:Node.js 用的是 Google 的 V8 引擎,Bun 用的是 Apple 的 JavaScriptCore(也就是 Safari 用的那個)。JSC 在某些場景下的啟動速度和記憶體效率比 V8 好
- Zig 語言的優勢:Zig 是一個接近 C 效能的系統語言,Bun 的底層(HTTP 伺服器、檔案系統操作等)都是用 Zig 寫的原生實作,而不是 JavaScript
- 整合式設計:因為 runtime、bundler、package manager 都是同一個程式,省去了大量的 IPC(跨程序通訊)開銷
安裝 Bun 和基本設定
安裝 Bun 非常簡單,一行指令搞定:
# macOS / Linux
curl -fsSL https://bun.sh/install | bash
# Windows(需要 WSL 或 PowerShell)
powershell -c "irm bun.sh/install.ps1 | iex"安裝完後確認版本:
bun --version
# 1.2.x(截至 2026 年初的最新版本)Bun 原生支援 TypeScript,不需要額外安裝 ts-node 或 tsx。直接寫 .ts 檔案就能跑:
# 建立一個 hello.ts
echo 'console.log("Hello from Bun!")' > hello.ts
bun run hello.ts
# Hello from Bun!不需要 tsconfig.json、不需要 babel、不需要任何設定。這是 Bun 體驗最好的地方之一——開箱即用。
Bun vs Node.js 效能實測
先上我自己的 benchmark 數據(測試環境:M2 MacBook Pro,16GB RAM):
HTTP Server(每秒請求數,使用 bombardier 測試):
- Bun(原生 HTTP):約 135,000 req/s
- Node.js(原生 HTTP):約 48,000 req/s
- Node.js + Express:約 15,000 req/s
- Bun + Hono:約 120,000 req/s
套件安裝速度(install from cache):
- bun install:0.3 秒
- npm install:4.2 秒
- pnpm install:1.8 秒
冷啟動速度:
- Bun:約 15ms
- Node.js:約 40ms
- Node.js + ts-node:約 350ms
數字是很漂亮,但我要老實說:在大多數實際應用中,瓶頸通常在資料庫查詢和外部 API 呼叫,不在 runtime 本身。Bun 的效能優勢在「高併發、低延遲」的場景下最明顯,例如 WebSocket 伺服器、API Gateway 等。
用 Bun 建立 HTTP Server
Bun 內建了原生的 HTTP Server API,語法非常簡潔:
// server.ts
const server = Bun.serve({
port: 3000,
fetch(request) {
const url = new URL(request.url);
if (url.pathname === "/api/hello") {
return Response.json({ message: "Hello from Bun!" });
}
return new Response("Not Found", { status: 404 });
},
});
console.log(`Server running at http://localhost:${server.port}`);注意到它用的是 Web 標準的 Request 和 Response API——這跟 Cloudflare Workers、Deno 等平台用的是同一套標準。如果你之前有寫過 Supabase Edge Functions 或其他 edge runtime,會覺得很熟悉。
實作 REST API 路由
Bun 的原生 HTTP API 很快但功能較基礎。對於正式的 API 開發,推薦搭配 Hono 框架:
// 安裝 Hono
bun add hono
// app.ts
import { Hono } from 'hono'
import { cors } from 'hono/cors'
const app = new Hono()
app.use('/*', cors())
app.get('/api/users', async (c) => {
// 從資料庫取得用戶列表
const users = await getUsers()
return c.json(users)
})
app.post('/api/users', async (c) => {
const body = await c.req.json()
const user = await createUser(body)
return c.json(user, 201)
})
app.get('/api/users/:id', async (c) => {
const id = c.req.param('id')
const user = await getUserById(id)
if (!user) return c.json({ error: 'Not found' }, 404)
return c.json(user)
})
export default {
port: 3000,
fetch: app.fetch,
}Hono 的 API 設計跟 Express 很像,但它是專為 edge runtime 設計的,效能遠超 Express。路由匹配、中間件、請求解析都經過高度優化。
連接資料庫
Bun 內建了 SQLite 驅動(這在 Node.js 中需要原生模組才能做到):
import { Database } from 'bun:sqlite'
const db = new Database('myapp.db')
// 建表
db.run(`CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT UNIQUE NOT NULL
)`)
// 查詢
const users = db.query('SELECT * FROM users').all()
// 插入
const insert = db.prepare('INSERT INTO users (name, email) VALUES (?, ?)')
insert.run('張小明', '[email protected]')對於 PostgreSQL,可以用 postgres(node-postgres 的替代)套件,Bun 完整相容。如果你的專案用 Prisma 或 Drizzle ORM,也都可以正常使用。連接 Supabase 或其他 PostgreSQL 資料庫的方式跟 Node.js 完全一樣。
檔案 IO 操作
Bun 的檔案 IO API 特別好用,比 Node.js 的 fs 模組更直覺:
// 讀檔(回傳 string)
const content = await Bun.file('config.json').text()
const json = await Bun.file('data.json').json()
// 寫檔
await Bun.write('output.txt', '這是輸出的內容')
await Bun.write('data.json', JSON.stringify(data, null, 2))
// 串流處理大檔案
const file = Bun.file('large-file.csv')
const stream = file.stream()
for await (const chunk of stream) {
// 處理每個 chunk
}Bun 的 Bun.file() 回傳的是一個 Blob-like 物件,支援 .text()、.json()、.arrayBuffer()、.stream() 等 Web 標準方法。不再需要 fs.readFileSync 和 fs.promises.readFile 的選擇困難了。
內建測試框架
Bun 內建了跟 Jest 語法相容的測試框架,不需要額外安裝:
// math.test.ts
import { describe, expect, it } from 'bun:test'
import { add, multiply } from './math'
describe('math utilities', () => {
it('should add two numbers', () => {
expect(add(2, 3)).toBe(5)
})
it('should multiply two numbers', () => {
expect(multiply(4, 5)).toBe(20)
})
})跑測試只要 bun test,速度比 Jest 快很多。在我的一個有 200 多個測試案例的專案中,Jest 跑完要 8 秒,Bun test 只要 1.2 秒。
Bun 套件管理器 vs npm
Bun 自帶的套件管理器大概是最容易感受到速度差異的地方。所有 npm 的命令都有對應的 bun 版本:
bun install # 等同 npm install
bun add hono # 等同 npm install hono
bun add -d vitest # 等同 npm install --save-dev vitest
bun remove express # 等同 npm uninstall express
bun run build # 等同 npm run buildBun 的 install 速度快到有點誇張。第一次安裝一個中型專案的所有相依(約 800 個套件)大概需要 2 秒,之後從快取安裝只要 0.3 秒。相比 npm 的 15-30 秒,差距非常明顯。
而且 Bun 完全相容 package.json 和 node_modules 結構,所以你可以在現有的 Node.js 專案中直接用 bun install 替換 npm install,不需要改任何設定。如果你有用 Docker Multi-Stage Build,Bun 的安裝速度會讓你的 CI/CD 明顯加快。
Node.js 生態系相容性
這是大家最關心的問題:Bun 能跑所有 Node.js 的套件嗎?
短回答:大部分可以,但不是 100%。
Bun 實作了絕大多數的 Node.js 內建模組(fs、path、http、crypto、stream 等),而且相容性在每個版本都在改善。到 2026 年初,官方宣稱相容性已達 95% 以上。
常見框架的相容性:
- Express:完全相容
- Fastify:完全相容
- Prisma:完全相容
- Drizzle ORM:完全相容
- Next.js:部分相容(開發伺服器可以用 bun 跑,但某些 edge case 可能有問題)
- Socket.io:相容但推薦用 Bun 原生 WebSocket
主要不相容的場景:
- 依賴特定 Node.js 版本 API 的套件
- 某些使用 N-API 原生模組的套件(但 Bun 對原生模組的支援在快速改善中)
- 深度依賴 V8 特定行為的套件(例如 vm module 的某些進階用法)
生產環境部署
Bun 在 production 環境的部署跟 Node.js 差不多。Dockerfile 的範例:
FROM oven/bun:1.2 AS base
WORKDIR /app
# 安裝相依
COPY package.json bun.lock ./
RUN bun install --frozen-lockfile --production
# 複製程式碼
COPY . .
# 啟動
EXPOSE 3000
CMD ["bun", "run", "server.ts"]Bun 的 Docker image(oven/bun)比 Node.js 的 image 小很多。加上安裝速度的優勢,CI/CD pipeline 的整體時間可以縮短 40-60%。
主要的雲端平台支援:
- Railway:原生支援 Bun
- Render:支援
- Fly.io:支援(自行提供 Dockerfile)
- AWS:透過 Docker 部署
- Vercel:Serverless Functions 支援 Bun runtime
該不該從 Node.js 遷移?
這是最實際的問題。我的建議是分三個情境:
適合立即遷移:
- 新專案,還沒有技術債
- 效能敏感的服務(API Gateway、WebSocket 伺服器)
- CI/CD 速度是瓶頸的團隊
- 純 TypeScript 專案,不依賴太多原生模組
可以逐步遷移:
- 現有的 Express/Fastify 專案,先用
bun install替換 npm - 開發環境先用 Bun,production 暫時保留 Node.js
- 新的微服務用 Bun 寫,舊的繼續用 Node.js
暫時不建議遷移:
- 大型 monolith 專案,依賴太多原生模組
- 團隊對 Bun 不熟悉,沒有時間學習
- 使用大量 Node.js 特定 API(如 worker_threads 的進階用法)
- 需要絕對穩定性的金融或醫療系統
我個人的做法是:所有新專案都用 Bun,舊專案先把套件管理切換到 Bun,runtime 等到有空再慢慢遷移。這是風險最低、收益最快的策略。搭配 Kubernetes 的流量管理,你甚至可以做 Node.js 和 Bun 的 A/B 部署,比較實際的效能差異。
Bun 代表的不只是「又一個 JavaScript runtime」,而是整個 JavaScript 後端工具鏈走向整合和高效能的趨勢。不管你現在用不用,了解它絕對是值得的投資。
繼續閱讀
Cloudflare Workers 邊緣運算入門:Serverless 後端開發實戰教學
相關文章
Cloudflare Workers 邊緣運算入門:Serverless 後端開發實戰教學
從零開始學 Cloudflare Workers 邊緣運算,涵蓋 KV 儲存、D1 資料庫、Durable Objects 到部署實戰,打造超低延遲的 Serverless 後端。
gRPC 微服務通訊完整教學:用 Protocol Buffers 打造高效能 Node.js 服務間通訊
深入探討 gRPC 與 Protocol Buffers 在微服務架構中的實戰應用,從 .proto 檔案定義到 Node.js 四種串流模式完整實作,帶你理解為什麼越來越多團隊選擇 gRPC 作為服務間通訊的首選方案。
你可能也喜歡
探索其他領域的精選好文