07-Node.js、Bun、Deno、Edge Runtime对比
要点
- JavaScript 服务端运行时从 Node.js 一家独大变成了多运行时并存
- 不同运行时使用的 JS 引擎不同,启动速度和内存表现差异显著
- Node.js 生态最成熟,但启动性能是短板
- Bun 和 Deno 各有侧重,生态成熟度仍在追赶
- Edge Runtime 不是单一产品,而是一类按 Web Standards 构建的部署模型
- Hono 通过适配器模式屏蔽运行时差异,同一份代码可以部署到不同平台
- 选择运行时的核心依据是部署需求,不是运行时本身
1. 从单一到多元的运行时格局
上一篇讲 Web Standards 时提到,Request、Response、fetch 这些 API 提供了跨平台的编程基础。但「跨平台」具体指哪些平台?这就引出了 JavaScript 运行时的问题。
JavaScript 最初只在浏览器里执行。Node.js 在 2009 年把这个限制打破了——它用 V8 引擎加上 libuv(处理文件系统和网络等系统调用的 C 库),让 JavaScript 可以跑在服务器上。此后很长一段时间,Node.js 是服务端 JavaScript 的唯一选择。npm 也随之成了最大的包管理平台。
2020 年前后,格局开始变化:
- Deno 由 Node.js 创始人 Ryan Dahl 打造,目标是解决 Node.js 的「历史包袱」——安全模型、TypeScript 支持、标准库设计
- Bun 在 2022 年发布,走的是另一条路——不纠结于纠正 Node.js 的设计,而是用不同的 JS 引擎(JavaScriptCore)追求极致速度
- Edge Runtime 由 Cloudflare、Vercel 等平台推动,把 JS 运行时搬到了全球分布的边缘节点上
多运行时并存的原因不复杂:不同场景对运行时的要求不同。长连接服务需要稳定的进程模型,Serverless 需要快速冷启动,全球分发的 API 需要低延迟。一个运行时很难同时满足所有需求。
接下来逐个看。
2. Node.js:最成熟的选项
Node.js 基于 V8 引擎和 libuv,目前最新的 LTS 版本是 v22。它的核心架构特点:
- 事件循环 + 非阻塞 IO:适合高并发的网络请求场景
- npm 生态:超过 200 万个包,几乎所有第三方服务都有 Node.js SDK
- 长期支持:企业级项目的首选,社区和文档最完善
Web Standards 支持方面,Node.js 从 v18 开始将 fetch、ReadableStream、URL 等 API 标记为稳定。到 v22,大多数 Web Standards API 已经内置可用,不再需要 --experimental-fetch 标志。这意味着前面几篇介绍的 Request、Response、Web Standards 写法,在 Node.js 里可以直接使用。
Node.js 的短板在启动性能和内存占用:
- 进程启动时间通常在 50-100ms(取决于依赖加载量)
- 空进程内存占用约 30-50MB
- 在 Serverless 场景下,冷启动延迟明显
对于长期运行的 HTTP 服务,这些不是问题。但如果你的部署目标是 Serverless 或 Edge,Node.js 的启动开销就需要认真评估。
对 AI 后端来说,Node.js 的优势在于生态:OpenAI、Anthropic、LangChain 等 SDK 都以 Node.js 为主要目标平台,文档最全、更新最快。而 AI 后端的核心操作——调用模型 API——本质上是网络 IO,Node.js 的事件循环处理这类并发非常高效。
3. Bun:追求速度的一体化运行时
Bun 使用 JavaScriptCore(Safari 的 JS 引擎)而非 V8,定位是「快速、一体化的 JavaScript/TypeScript 运行时」。
核心特点:
- 原生 TypeScript:直接运行
.ts文件,不需要tsc或ts-node - 内置工具链:包管理器(
bun install)、打包器(bun build)、测试运行器(bun test)全部内置 - 启动速度:通常在 5ms 以内,比 Node.js 快一个数量级
- npm 兼容:通过
bun install安装 npm 包,大部分纯 JS 包可以直接使用
Web Standards 覆盖率较高。fetch、Request、Response、URL、FormData、ReadableStream 等 API 均已内置。Bun 还实现了不少 Node.js 内置模块(fs、path、http 等),兼容层在持续完善中。
对 AI 后端来说,Bun 的优势是启动快、开发体验好。不用配 tsconfig.json 就能跑 TypeScript,对项目脚手架和快速原型有帮助。
需要注意的实际问题:
- 部分 npm 包(特别是依赖 native addon 的)在 Bun 下可能不兼容
- 第三方 SDK 的测试覆盖通常以 Node.js 为主,Bun 上的边界情况文档较少
- 生产环境的长期稳定性案例还在积累中
4. Deno:安全优先的 TypeScript 运行时
Deno 同样基于 V8 引擎,但和 Node.js 走了不同的设计路线。它的核心特点:
- 默认安全沙箱:脚本默认无法访问文件系统、网络和环境变量,需要显式授权(
--allow-read、--allow-net、--allow-env) - 原生 TypeScript:和 Bun 类似,直接运行
.ts文件 - 标准库:提供
@std系列模块(原std/),覆盖文件操作、路径处理、HTTP 服务等常见需求 - 内置测试框架:
deno test开箱即用
Node.js 兼容性方面,Deno 近两年进展明显。通过 npm: 导入语法(import express from "npm:express")和 Node.js 兼容层(node:fs、node:http 等),大部分 npm 包可以在 Deno 中使用。但实际兼容程度因包而异——依赖底层系统调用的包(特别是 native addon)仍有兼容问题。
Deno Deploy 是 Deno 官方的边缘部署平台,全球多个区域运行 Deno 运行时。它和 Edge Runtime 的思路接近,后面会一起讨论。
对 AI 后端来说,Deno 的安全模型适合处理不可信代码的场景(比如执行用户提交的脚本)。但在 AI 后端最常见的需求——调用模型 API、处理流式响应——方面,Deno 的生态和部署选项不如 Node.js 和 Cloudflare Workers 丰富。
5. Edge Runtime:一类运行模型,不是单一产品
Edge Runtime 不是一个具体的运行时产品,而是一类部署模型的统称。Cloudflare Workers、Vercel Edge Functions、Deno Deploy 都属于这个范畴。
它们的共同特征:
- 全球分布:代码部署在全球数百个边缘节点,请求由最近的节点处理
- 按需启动:没有持久进程,每次请求触发执行,请求结束即释放资源
- 资源受限:CPU 时间(通常每次请求 10-50ms)和内存(128MB 左右)有硬性上限
- Web Standards 优先:几乎不提供 Node.js 专属 API(
fs、child_process等不可用),编程接口以 Web Standards 为基础
这意味着前面几篇介绍的 Web Standards API(fetch、Request、Response、ReadableStream)在 Edge Runtime 上是原生支持的——因为 Edge Runtime 的实现基础就是这些标准。
以 Cloudflare Workers 为例,它使用的 V8 Isolate 模型:
- 冷启动时间通常在 5ms 以内
- 多个 Worker 共享同一个 V8 实例,通过 Isolate 隔离
- 不需要为每个请求启动新的进程或线程
对 AI 后端来说,Edge Runtime 的特点:
- 适合:API 端点、请求转发、流式响应代理。模型调用主要是网络 IO,CPU 时间受限影响不大
- 需要注意:如果需要在服务端做大量数据处理(JSON 解析、向量计算、图像编码),CPU 时间上限可能不够用
- 适合:需要全球低延迟的场景(用户分布在不同地区时,边缘节点的网络延迟优势明显)
- 不适合:需要长连接、WebSocket 持久会话、后台定时任务的场景(部分平台已支持但有限制)
6. 对比表格
| 维度 | Node.js | Bun | Deno | Edge Runtime |
|---|---|---|---|---|
| JS 引擎 | V8 | JavaScriptCore | V8 | V8(通常) |
| 启动速度 | 50-100ms | ~5ms | 20-40ms | ~5ms |
| 空进程内存 | ~30-50MB | ~15-25MB | ~20-30MB | ~5-10MB |
| TypeScript 支持 | 需要配置(tsc/tsx) | 原生支持 | 原生支持 | 视平台而定 |
| npm 兼容性 | 完整 | 大部分兼容 | 大部分兼容(npm: 语法) | 受限或不可用 |
| Web Standards 覆盖率 | v22 较高 | 高 | 高 | 最高(几乎仅靠 Web Standards) |
| 部署模型 | 长期进程 / 容器 | 长期进程 / 容器 | 长期进程 / Deno Deploy | 边缘按需执行 |
| 适用场景 | 通用后端、微服务 | 快速开发、原型、脚本 | 安全敏感场景、边缘部署 | 全球低延迟 API、边缘计算 |
| Hono 支持 | ✅ hono/node-server | ✅ hono/bun | ✅ hono/deno | ✅ hono/cloudflare-workers 等 |
表格里的数据是 2026 年中期的典型值,实际表现取决于具体版本、代码复杂度和运行环境。启动速度的差异主要来源于 JS 引擎初始化和模块加载的开销。
7. 如何选择运行时
选择运行时的决策路径:
选 Node.js,如果你:
- 需要丰富的 npm 生态(数据库驱动、AI SDK、企业内部系统对接)
- 团队对 Node.js 最熟悉
- 部署目标是传统服务器或容器(Docker、Kubernetes)
选 Bun,如果你:
- 追求开发速度和一体化体验(不用额外配置 TypeScript 和打包工具)
- 项目依赖以纯 JavaScript 包为主
- 愿意承受生态成熟度的风险
选 Edge Runtime(Cloudflare Workers),如果你:
- 需要全球低延迟、低成本部署
- API 主要是网络 IO(转发请求、调用模型、聚合数据)
- 不需要 Node.js 专属 API
AI 后端的具体考量:
AI 后端的核心操作是调用模型 API(OpenAI、Anthropic 等),这本质上是发一个 HTTP 请求然后等流式响应。这个过程对运行时的要求:
- 需要稳定的
fetch和流式读取能力 → 四个运行时都支持 - CPU 计算量小(拼接请求参数、解析 JSON)→ CPU 时间受限的 Edge Runtime 也能胜任
- 网络延迟敏感(用户等待首个 token 的时间)→ Edge Runtime 的全球分布优势明显
实际建议:如果你的 AI 后端主要是 API 转发和流式代理,Cloudflare Workers(Edge Runtime)是性价比最高的选择。如果你需要用到只支持 Node.js 的 SDK 或数据库驱动,就用 Node.js。
Hono 的跨运行时能力意味着你不需要在写代码之前就做出最终选择。先用 Web Standards API 写业务逻辑,部署时再选平台。这种开发方式在 AI 后端项目中尤其实用——你可以先在本地用 Bun 快速开发调试,部署时切换到 Cloudflare Workers 获得全球低延迟。
8. Hono 如何屏蔽运行时差异
来看一个具体例子。同一份 Hono 代码如何运行在不同平台。
先写路由逻辑,这部分和运行时无关:
// app.ts
import { Hono } from 'hono'
const app = new Hono()
app.get('/', (c) => {
return c.json({ message: 'Hello from Hono' })
})
app.post('/api/echo', async (c) => {
const body = await c.req.json()
return c.json({ received: body })
})
export default app这份代码用的是 c.req.json() 和 c.json()——这些是 Hono 封装的 API,底层在不同运行时会适配到对应的 Web Standards 实现。
接下来,为不同运行时写入口文件:
Node.js 入口:
// node.ts
import { serve } from '@hono/node-server'
import app from './app'
serve({
fetch: app.fetch,
port: 3000,
})Bun 入口:
// bun.ts
import app from './app'
export default appBun 直接支持导出 Request → Response 的对象作为 HTTP 服务,不需要额外的 server 封装。
Cloudflare Workers 入口:
// cloudflare.ts
import app from './app'
export default appCloudflare Workers 的 export default 约定和 Bun 类似,Hono 实例本身就是符合 Worker 规范的导出。
核心路由只写了一次,不同运行时的差异由入口文件和 Hono 的适配器处理。这就是 Hono 的「Write Once, Run Anywhere」设计。
需要注意的一点:虽然 Hono 屏蔽了路由层的差异,但如果你在路由中使用了运行时专属 API(比如 Node.js 的 fs 读写文件、Bun 的 Bun.serve),这部分代码就不再跨平台。保持路由逻辑只用 Web Standards API 和 Hono API,就能最大化跨运行时的兼容性。
延伸阅读
总结
JavaScript 运行时的选择直接影响部署方式、启动性能和开发体验。Node.js 生态最完善,适合需要丰富 npm 包的传统后端;Bun 启动快、开发体验好,但生产稳定性仍在验证中;Deno 的安全模型有独到价值,生态还在建设;Edge Runtime 通过全球分布实现低延迟,适合以网络 IO 为主的 AI 后端。
Hono 的价值在于通过适配器模式屏蔽运行时差异,让你先用 Web Standards API 写业务逻辑,再根据部署需求选择平台。这种「先写代码,再选部署目标」的开发方式,在本教程后续章节中会反复用到。
下一篇聊 Serverless 与 Edge Computing 的架构特点——理解这些部署模型,才能更好地做运行时选择。