V8 不是 Node.js:JS 引擎、Runtime、产品三层区分与常见误判
把 JavaScript 运行时统称为「引擎」是很常见的省略。实际上面向开发者的一整套东西分成三层:引擎是发动机,runtime 是整车系统,产品是最终交付的车。
三层的职责边界大致是:
- JS 引擎:负责把 JavaScript 解析、编译、执行。
- Runtime:负责给这段 JavaScript 提供宿主环境,比如文件系统、网络、权限、事件循环、模块系统。
- 产品:最终被开发者或用户接触到的东西,比如浏览器、移动框架、云函数平台、嵌入式 SDK。
日常听到的混淆大多发生在第一层和第二层之间:说「Node 引擎」时,指的其实是 V8;说「Safari 引擎」时,指的其实是 JavaScriptCore。引擎提供语言能力,runtime 决定这段语言能碰到什么。
引擎与 runtime / 产品对照
| 引擎 | 对应的 runtime / 产品 |
|---|---|
| V8 | Node.js、Deno、Cloudflare Workers、Chromium 系浏览器 |
| SpiderMonkey | Firefox、Servo、MongoDB server-side JavaScript(已废弃路径)、CouchDB 默认 query server(同时已有 QuickJS 选项) |
| JavaScriptCore | Safari / WebKit、Apple 平台应用、Bun、React Native 的可选回退 |
| Hermes | React Native |
| QuickJS | 各种嵌入式工具、脚本宿主、自定义应用 |
| JerryScript | IoT、微控制器、极低资源设备 |
| XS | Moddable SDK、嵌入式设备 |
| MuJS | 自定义宿主程序、轻量级脚本扩展 |
| GraalJS | GraalVM、Java 应用、JVM 生态脚本嵌入 |
| ChakraCore | 存量项目、旧式嵌入场景 |
从这张表往下看,几个引擎的定位差异就清楚了。
V8 覆盖面最广,驱动 Node、Deno、Cloudflare Workers 以及 Chromium 系浏览器。它是通用生态里的默认底座,兼容性、性能工具链、周边库都围绕它长出来。
JavaScriptCore 走的是另一条路,成为 Safari 和 Bun 的核心选择,强调启动速度与嵌入体验。它和 WebKit 绑得很紧,所以在 Apple 平台上几乎是天然选项。
SpiderMonkey 是 Firefox 生态的老牌主心骨,同时也出现在 Servo 这类项目里。它在服务端的痕迹主要集中在存量场景:MongoDB 曾把 server-side JavaScript 跑在这条路径上,但该路径已经废弃;CouchDB 的默认 query server 也在这一系,并且已经提供了 QuickJS 选项。
轻量引擎靠嵌入场景生存。QuickJS、JerryScript、XS 服务于 IoT、微控制器和自定义宿主,目标不是跑大型应用,而是在资源受限或宿主自定义的环境里提供一个可控的脚本层。MuJS 也属于这一类,常见于自定义宿主程序和轻量级脚本扩展。
Hermes 是为 React Native 优化启动速度和包体积的,属于产品反向定义引擎的典型:不是先有引擎再找场景,而是移动端的需求倒推出一个引擎该长什么样。
GraalJS 卡在 JVM 生态里,服务的是 GraalVM、Java 应用和 JVM 生态的脚本嵌入需求。
容易混的几个地方
最典型的一条:V8 本身不是 Node.js,JavaScriptCore 也不是 Safari。Node.js、Deno、Bun、Cloudflare Workers 这些 runtime,才是真正把引擎包装成开发者每天会用的东西——模块解析、网络栈、权限模型、CLI、包管理,全都属于 runtime 这一层,不属于引擎。
第二条是 Bun 的引擎选择。Bun 选择 JavaScriptCore 而不是 V8,本质上是在赌启动速度和嵌入体验,而不是沿着 Node 的既有路径走。
第三条在 React Native 上:Hermes 是 React Native 的默认引擎,JavaScriptCore 是可选的回退引擎。默认与回退的差别,直接影响到启动表现和包体积约束。
日常会接触到的三层生态
如果只是日常写前端、Node、Bun、Deno,最常接触的其实只有三层:
- V8 生态:Node、Deno、Workers 很多都在这上面;
- JavaScriptCore 生态:Bun 是典型代表;
- Hermes 生态:React Native 是典型代表。
选择依据
选型时,引擎背后对应的其实是场景约束:
- 选 V8,往往意味着你更接近通用生态和成熟兼容;
- 选 JavaScriptCore,往往意味着你看重启动速度、嵌入体验,或者你本来就处在 Apple / WebKit 生态里;
- 选 Hermes,往往意味着你在移动端和包体积上有明确约束;
- 选 QuickJS、JerryScript、XS、MuJS,往往意味着你在做嵌入式或自定义宿主;
- 选 GraalJS,往往意味着你在 Java 世界里找脚本能力。
项目信息
- V8:https://v8.dev/
- JavaScriptCore / WebKit:https://webkit.org/
- Node.js:https://nodejs.org/
- Deno:https://deno.com/
- Bun:https://bun.sh/
- Hermes:https://hermesengine.dev/
- QuickJS:https://bellard.org/quickjs/
- JerryScript:https://github.com/jerryscript-project/jerryscript
- GraalJS:https://www.graalvm.org/javascript/
Tags: JavaScript, JavaScript Runtime, V8, JavaScriptCore, Hermes, JS 引擎