Node.js 已经统治 JS 服务端运行时十几年了,但 Deno 2.x 和 Bun 正在从不同角度发起挑战。这篇文章对比它们的特点、生态兼容性和性能表现。
三者定位
Node.js 是基石——最成熟的生态、最广泛的部署、最多的生产经验。缺点是历史包袱重(CommonJS/ESM 双模块系统、callback 遗产、安全模型缺失)。
Deno 2.x 由 Node.js 原作者 Ryan Dahl 创建,目标是「修正 Node.js 的设计错误」。2.x 版本做了重大转向——全面兼容 npm 生态,同时保留自身优势。
Bun 由 Jarred Sumner 创建,用 Zig 编写,核心卖点是「极致性能」。自带 bundler、test runner、package manager,追求 all-in-one。
Deno 2.x 的关键特性
npm 兼容性
Deno 2.x 最重要的变化是可以直接使用 npm 包,无需任何转换:
// 直接 import npm 包
import express from "npm:express";
import chalk from "npm:chalk";
const app = express();
app.get("/", (req, res) => {
res.send(chalk.green("Hello from Deno!"));
});
app.listen(3000);
也支持 package.json 和 node_modules,这让现有 Node.js 项目迁移到 Deno 的成本大幅降低。
权限系统
Deno 的安全模型是其区别于 Node.js 的核心设计:
# 只允许网络访问和文件读取
deno run --allow-net --allow-read server.ts
# 细粒度控制
deno run --allow-net=api.example.com --allow-read=./data server.ts
# 2.x 新增:权限提示模式(开发时交互式询问)
deno run --prompt server.ts
在生产环境中,这个权限模型提供了额外的安全层——即使代码被注入恶意逻辑,没有对应权限也无法执行。
内置工具链
deno fmt # 格式化(类似 prettier)
deno lint # 代码检查
deno test # 测试运行
deno bench # 性能测试
deno compile # 编译为单文件可执行程序
deno jupyter # Jupyter notebook 支持
不需要 prettier + eslint + jest + pkg 这一堆工具,Deno 全部内置。
Bun 的关键特性
极致启动速度
Bun 用 JavaScriptCore(Safari 的 JS 引擎)替代 V8,在启动速度上有巨大优势:
# 空脚本启动时间对比(实测)
$ hyperfine 'node -e ""' 'deno eval ""' 'bun -e ""'
node: 32.1 ms
deno: 25.3 ms
bun: 6.2 ms
对于 CLI 工具和 serverless 函数,这个差距很有意义。
内置 Bundler
bun build ./src/index.ts --outdir ./dist --target browser
Bun 的 bundler 性能接近 esbuild,但原生支持 TypeScript 和 JSX,不需要额外配置。
包管理器
bun install # 安装依赖,速度通常是 npm 的 10-20 倍
bun add express # 添加依赖
bun remove lodash # 移除依赖
Bun 的包管理器使用硬链接和全局缓存,安装速度远超 npm/yarn/pnpm。
性能对比
用一个简单的 HTTP server 做基准测试(hello world 响应):
// server.ts (兼容三个运行时)
const server = Bun?.serve?.({
port: 3000,
fetch(req) {
return new Response("Hello World");
},
}) ?? null;
// Node.js 和 Deno 用各自的 HTTP API
使用 wrk 测试(10 并发,30 秒):
| 运行时 | 请求/秒 | 平均延迟 | P99 延迟 |
|---|---|---|---|
| Node.js 22 | 62,400 | 0.16ms | 0.42ms |
| Deno 2.3 | 89,100 | 0.11ms | 0.31ms |
| Bun 1.2 | 128,300 | 0.08ms | 0.22ms |
Bun 在原始吞吐量上确实领先,但实际项目中瓶颈往往在数据库和外部 IO,HTTP 层的差距不会这么明显。
生态兼容性
这是决定能否在生产中使用的关键因素。
Deno 2.x 的 npm 兼容性已经很好,大部分 npm 包可以直接使用。少数依赖 Node.js 特定行为(如 monkey-patching require)的包可能有问题。在我的测试中,Express、Fastify、Prisma、Drizzle 都能正常工作。
Bun 的 Node.js API 兼容性在 1.x 后也大幅改善,但仍有一些边界情况。node:crypto 的部分实现不完整,一些依赖 native addon 的包需要重新编译。
我的选择建议
- 新项目 + 看重安全性:Deno 2.x。权限系统是真正的差异化优势。
- 新项目 + 看重性能:Bun。启动速度和运行性能都是最优。
- 现有项目:继续 Node.js。迁移成本 > 收益,除非有明确的痛点。
- 工具脚本/CLI:Bun。启动快,内置 TypeScript,写脚本最舒服。
- Serverless/Edge:Deno。Deno Deploy 的开发体验很好,冷启动快。
三个运行时都在快速发展,竞争是好事。Node.js 也因此加速了改进——原生 TypeScript 支持、权限模型都已经在路线图上。