07-Node.js、Bun、Deno、Edge Runtime对比

要点

  • JavaScript 服务端运行时从 Node.js 一家独大变成了多运行时并存
  • 不同运行时使用的 JS 引擎不同,启动速度和内存表现差异显著
  • Node.js 生态最成熟,但启动性能是短板
  • Bun 和 Deno 各有侧重,生态成熟度仍在追赶
  • Edge Runtime 不是单一产品,而是一类按 Web Standards 构建的部署模型
  • Hono 通过适配器模式屏蔽运行时差异,同一份代码可以部署到不同平台
  • 选择运行时的核心依据是部署需求,不是运行时本身

1. 从单一到多元的运行时格局

上一篇讲 Web Standards 时提到,RequestResponsefetch 这些 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 开始将 fetchReadableStreamURL 等 API 标记为稳定。到 v22,大多数 Web Standards API 已经内置可用,不再需要 --experimental-fetch 标志。这意味着前面几篇介绍的 RequestResponse、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 文件,不需要 tscts-node
  • 内置工具链:包管理器(bun install)、打包器(bun build)、测试运行器(bun test)全部内置
  • 启动速度:通常在 5ms 以内,比 Node.js 快一个数量级
  • npm 兼容:通过 bun install 安装 npm 包,大部分纯 JS 包可以直接使用

Web Standards 覆盖率较高。fetchRequestResponseURLFormDataReadableStream 等 API 均已内置。Bun 还实现了不少 Node.js 内置模块(fspathhttp 等),兼容层在持续完善中。

对 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:fsnode: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(fschild_process 等不可用),编程接口以 Web Standards 为基础

这意味着前面几篇介绍的 Web Standards API(fetchRequestResponseReadableStream)在 Edge Runtime 上是原生支持的——因为 Edge Runtime 的实现基础就是这些标准。

以 Cloudflare Workers 为例,它使用的 V8 Isolate 模型:

  • 冷启动时间通常在 5ms 以内
  • 多个 Worker 共享同一个 V8 实例,通过 Isolate 隔离
  • 不需要为每个请求启动新的进程或线程

对 AI 后端来说,Edge Runtime 的特点:

  • 适合:API 端点、请求转发、流式响应代理。模型调用主要是网络 IO,CPU 时间受限影响不大
  • 需要注意:如果需要在服务端做大量数据处理(JSON 解析、向量计算、图像编码),CPU 时间上限可能不够用
  • 适合:需要全球低延迟的场景(用户分布在不同地区时,边缘节点的网络延迟优势明显)
  • 不适合:需要长连接、WebSocket 持久会话、后台定时任务的场景(部分平台已支持但有限制)

6. 对比表格

维度Node.jsBunDenoEdge Runtime
JS 引擎V8JavaScriptCoreV8V8(通常)
启动速度50-100ms~5ms20-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-serverhono/bunhono/denohono/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 app

Bun 直接支持导出 RequestResponse 的对象作为 HTTP 服务,不需要额外的 server 封装。

Cloudflare Workers 入口

// cloudflare.ts
import app from './app'
 
export default app

Cloudflare 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 的架构特点——理解这些部署模型,才能更好地做运行时选择。