Hono + Bun:Bun 的 Bun.serve 与 Hono 的兼容性
利用 Bun 的原生 JS 解析器,进一步提升性能
Bun 是一个现代的 JavaScript 运行时,以其极快的启动速度、原生的 TypeScript 支持和内置的 HTTP 服务器而闻名。Hono 作为一个为边缘和快速环境设计的微型 Web 框架,与 Bun 高度兼容,能够充分发挥 Bun 的性能优势。
本文将深入探讨 Bun 的 Bun.serve 如何与 Hono 无缝集成,并如何利用 Bun 的原生特性(如 JS 解析器、WebSocket 支持)构建超高性能的 Web 服务。
一、为什么选择 Hono + Bun?
| 特性 | 说明 |
|---|---|
| 极致性能 | Bun 使用 Zig 编写,启动快,内存占用低 |
| 原生 TS/JSX 支持 | 无需转译,直接运行 .ts、.tsx |
| 内置 HTTP 服务器 | Bun.serve() 性能优于 Node.js 的 http 模块 |
| Hono 轻量高效 | ~2KB,无依赖,路由匹配极快 |
| 边缘友好 | 可部署到 Bun Cloud、Fly.io、Docker 等 |
Hono + Bun = 当前最快的 TypeScript Web 开发栈之一
二、Bun.serve 与 Hono 的兼容性
Bun 提供了两种方式运行 HTTP 服务:
Bun.serve(options):Bun 原生 HTTP 服务器;node:http兼容层:用于兼容 Express、Hono 等传统框架。
Hono 完美支持 Bun.serve,你可以直接将 Hono 的 fetch handler 传递给 fetch 选项。
完全兼容,无需适配器
// app.ts
import { Hono } from 'hono'
const app = new Hono()
app.get('/', (c) => c.text('Hello from Hono on Bun!'))
app.get('/json', (c) => c.json({ msg: 'Bun is fast!' }))
app.post('/echo', async (c) => {
const body = await c.req.json()
return c.json({ youSent: body })
})
// 直接使用 Bun.serve
Bun.serve({
port: 3000,
fetch: app.fetch
})
console.log('Server running on http://localhost:3000')无需 @hono/node-server 或任何适配器,Hono 的 app.fetch 天然符合 Web Standard 的 FetchEvent#respondWith 接口。
三、性能优势:Bun 的原生 JS 解析器
Bun 的核心优势之一是其原生用 Zig 实现的 JavaScript/TypeScript 解析器,相比 Node.js 的 V8 有显著性能提升。
1. 启动速度极快
# Bun 启动 Hono 应用
time bun app.ts
# real 0m0.023s 👈
# 对比:Node.js + ts-node
time node --loader ts-node/esm app.ts
# real 0m1.245sBun 启动速度快 50 倍以上
2. 无需构建步骤
- 直接运行
.ts文件; - 无
tsc或esbuild构建; - 开发体验接近
ts-node,但性能接近原生 JS。
3. 内置 TypeScript 支持
// tsconfig.json(可选)
{
"compilerOptions": {
"target": "es2022",
"module": "esnext",
"moduleResolution": "bundler",
"strict": true
}
}Bun 会自动读取 tsconfig.json,但即使没有也能运行。
四、WebSocket 支持(Bun 原生)
Bun 提供了一流的 WebSocket 支持,Hono 可以通过 upgradeWebSocket 与之集成。
// websocket.ts
import { Hono } from 'hono'
import { upgradeWebSocket } from 'hono/ws'
const app = new Hono()
app.get('/ws', upgradeWebSocket((c) => {
return {
onMessage(ws, message) {
console.log('Received:', message)
ws.send(`Echo: ${message}`)
},
onOpen(ws) {
console.log('Client connected')
ws.send('Welcome to Bun + Hono WebSocket!')
},
onClose(ws, code, reason) {
console.log(`Disconnected: ${code} ${reason}`)
}
}
}))
Bun.serve({
port: 3000,
fetch: app.fetch,
websocket: {
open: (ws) => app.fetch(new Request('/ws'), { webSocket: ws }),
message: (ws, message) => ws.send(`Echo: ${message}`),
close: (ws, code, reason) => console.log('Closed')
}
})Hono 的 upgradeWebSocket 与 Bun 的 WebSocket API 完美协作。
五、性能基准测试(Hono + Bun vs Express + Node.js)
| 框架 | 环境 | RPS(Requests Per Second) | 延迟(p95) |
|---|---|---|---|
| Hono + Bun | Bun 1.1+ | ~28,000 | ~3ms |
| Express + Node.js | Node.js 20 | ~8,500 | ~12ms |
| Hono + Node.js | Node.js 20 | ~22,000 | ~5ms |
数据来源:Bun 官方基准 + 社区测试
Hono + Bun 在简单 JSON 响应场景下性能领先 3-4 倍。
六、开发体验优化
1. 热重载(Watch Mode)
{
"scripts": {
"dev": "bun --watch app.ts",
"build": "echo 'No build needed!'",
"start": "bun app.ts"
}
}--watch 会监听文件变化并自动重启。
2. 环境变量
// .env
PORT=3000
API_KEY=your-key
// app.ts
const port = process.env.PORT || 3000
Bun.serve({ port, fetch: app.fetch })Bun 原生支持 .env 文件。
3. 静态文件服务
app.get('/static/*', async (c) => {
const filepath = c.req.path.replace('/static/', '')
const file = Bun.file(`public/${filepath}`)
if (await file.exists()) {
return new Response(file.stream(), { headers: { 'Content-Type': file.type } })
}
return c.text('Not Found', 404)
})利用 Bun.file() 高效读取文件。
七、部署选项
| 平台 | 支持情况 |
|---|---|
| Bun Cloud | 原生支持,一键部署 |
| Fly.io | 支持 Docker 或直接运行 |
| Docker | 构建轻量镜像 |
| Cloudflare Workers | 不兼容(Bun 特有 API) |
| Vercel / Netlify | 不支持 Bun 运行时 |
Bun 应用适合自托管或 Bun 原生平台。
八、最佳实践
- 使用
Bun.serve而非 Express 兼容层 - 避免
require(),使用import - 利用
Bun.file()和Bun.sleep()等原生 API - 开启
--watch提升开发效率 - 在
prod中使用Bun.build()打包(可选)
九、总结
| 能力 | Hono + Bun 实现 |
|---|---|
| 极致性能 | 原生 JS 解析 + 轻量框架 |
| TypeScript 开箱即用 | 无需构建 |
| 热重载开发 | bun --watch |
| WebSocket 支持 | 原生集成 |
| 轻量部署 | 单文件运行 |
Hono + Bun 是构建高性能 API、微服务、边缘函数的理想组合。
它不仅速度快,而且开发体验流畅,是现代 Web 后端的未来之选。
立即尝试将你的下一个项目迁移到 Hono + Bun,感受 亚毫秒级响应 的开发体验。