全部文章

Bun 与 Deno 运行时

Bun 和 Deno 的安装使用、与 Node.js 对比、包管理与实用命令

目录 25 节

Bun 与 Deno 运行时

这页适合作为“Node.js 之外现代 JavaScript 运行时的入门比较”。Bun 和 Deno 都很强,但它们适合解决的问题并不完全一样;先按项目目标选,比单纯追新更重要。

先按场景选

  • 想在 Node 生态里提速:优先 Bun
  • 想一套工具同时管运行、测试、打包:优先 Bun
  • 想要默认权限隔离与更强约束:优先 Deno
  • 想要标准 Web API 风格和内置工具链:优先 Deno
  • 已有大型 Node 项目要稳妥迁移:先小范围尝试,不要整仓库直接切

Bun

Bun 是用 Zig 编写的高性能 JavaScript 运行时,集成了包管理器、打包器和测试运行器。

安装

# Windows
scoop install bun
# 或
powershell -c "irm bun.sh/install.ps1 | iex"

# macOS/Linux
curl -fsSL https://bun.sh/install | bash

运行脚本

bun run index.ts          # 直接运行 TypeScript
bun run dev               # 运行 package.json scripts
bun --watch index.ts      # 文件变更自动重启

包管理

bun init                  # 初始化项目
bun add express           # 添加依赖
bun add -d vitest         # 添加开发依赖
bun remove express        # 移除
bun install               # 安装所有依赖
bun update                # 更新依赖

Bun 使用 bun.lock(二进制格式),速度远快于 npm/pnpm。

Bun 更适合什么

  • 前端工具链
  • 本地脚本和 CLI
  • 追求安装速度、测试速度和开发反馈速度的项目
  • 与 Node.js 兼容度要求高,但想减少工具碎片化的团队

内置 API

// 文件操作
const file = Bun.file("data.json");
const text = await file.text();
await Bun.write("output.txt", "hello");

// HTTP 服务器
Bun.serve({
  port: 3000,
  fetch(req) {
    return new Response("Hello Bun!");
  },
});

// 密码哈希
const hash = await Bun.password.hash("mypassword");
const valid = await Bun.password.verify("mypassword", hash);

// Shell
import { $ } from "bun";
const result = await $`ls -la`.text();

测试

bun test
bun test --watch
// test.ts
import { expect, test } from "bun:test";

test("2 + 2", () => {
  expect(2 + 2).toBe(4);
});

打包

bun build ./src/index.ts --outdir ./dist --target browser
bun build ./src/index.ts --outdir ./dist --target node --minify

Deno

Deno 是 Node.js 创始人 Ryan Dahl 的新运行时,默认安全、原生 TypeScript。

安装

# Windows
scoop install deno
# 或
winget install DenoLand.Deno

# macOS/Linux
curl -fsSL https://deno.land/install.sh | sh

运行

deno run index.ts                    # 运行(无权限)
deno run --allow-net index.ts        # 允许网络
deno run --allow-read --allow-write index.ts
deno run -A index.ts                 # 允许所有权限
deno task dev                        # 运行 deno.json 中的 task

权限模型

Deno 默认不允许任何系统访问:

权限说明
--allow-net网络访问
--allow-read文件读取
--allow-write文件写入
--allow-env环境变量
--allow-run运行子进程
--allow-ffi外部函数接口
-A所有权限

包管理

// deno.json
{
  "imports": {
    "oak": "jsr:@oak/oak@^17",
    "std/": "jsr:@std/",
  },
  "tasks": {
    "dev": "deno run --watch -A main.ts",
    "build": "deno compile -A main.ts",
  },
}
deno add jsr:@oak/oak       # 添加依赖
deno install                 # 安装依赖

Deno 2.x 也支持 npm: 前缀直接使用 npm 包:

import express from "npm:express";

Deno 更适合什么

  • 对权限边界敏感的脚本和服务
  • 希望默认集成 fmtlinttestcompile 的项目
  • 偏标准 Web API 和现代运行时体验的团队
  • 想把单文件工具直接编译成可执行文件的场景

内置工具

deno fmt                     # 格式化
deno lint                    # Lint
deno test                    # 测试
deno bench                   # 基准测试
deno compile main.ts         # 编译为单文件可执行
deno doc mod.ts              # 生成文档

对比

特性Node.jsBunDeno
语言C++ZigRust
TypeScript需要编译原生支持原生支持
包管理npm/pnpm/yarnbun(内置)deno add / npm
安全模型无限制无限制默认沙箱
兼容性生态最大高度兼容 Node兼容 Node/npm
速度基准最快

推荐落地顺序

建议不要一开始就“主项目整体迁移”。更稳的做法是:

  1. 先拿小脚本或新建工具项目试运行时
  2. 再验证依赖兼容性、测试工具和构建流程
  3. 再决定是否扩大到服务或前端项目
  4. 最后才考虑作为团队默认运行时

常见问题

Bun 能不能完全替代 Node.js

很多项目可以部分替代,但不代表所有项目都该马上切。重点要看:

  • 依赖兼容性
  • CI/CD 环境
  • 原生模块需求
  • 团队对 Node 工具链的绑定程度

Deno 默认权限很烦吗

刚开始会有一点约束感,但这正是它的价值之一。对脚本、自动化和边界敏感场景来说,这种显式授权反而更清晰。

一个仓库里能不能同时有 Node、Bun、Deno

可以,但要有明确边界。比如主应用仍用 Node,单独工具脚本用 Bun 或 Deno。最怕的是没人知道哪个命令该用哪个运行时。

风险提醒

  • 不要为了“新”而迁移成熟项目
  • 锁文件和 CI 运行时要统一
  • 运行时切换前先验证第三方依赖、测试和部署链路

延伸阅读

参考链接

  • Bun — 官网与文档
  • Deno — 官网与文档
  • JSR — Deno 包仓库
阅读建议
  • - 先读标题和摘要,再结合目录决定从哪个章节开始精读。
  • - 看到具体命令、配置或步骤时,尽量在自己的环境里同步验证。
  • - 如果你只是快速查资料,可先看目录和相关文档,再决定是否深入全文。
适合谁看
  • - 希望把零散经验整理成长期可复用工作流的人
  • - 想先建立认知,再决定是否深入实践的人
  • - 希望阅读时顺手建立自己的操作清单或收藏体系的人
执行前检查
  • - 先浏览标题、摘要和目录,带着问题阅读会更高效
  • - 顺手记录真正对你有用的命令、链接和注意事项,避免重复搜索
  • - 如果页面里提到相关文档,尽量一起打开对照,效果通常更完整
同类内容
← 上一篇Android 精简与优化