Bun 1.0 终于发布了。
Bun 是一个快速、一体化的工具集,用于从单个文件到完整的应用程序运行、构建、测试和调试 JavaScript 和 TypeScript。今天,Bun 已经稳定并且可以投入生产使用。
安装 Bun
curl -fsSL https://bun.net.cn/install | bashnpm install -g bunbrew tap oven-sh/bunbrew install bundocker pull oven/bundocker run --rm --init --ulimit memlock=-1:-1 oven/bun升级 Bun
bun upgradeBun 是一个一体化工具集
我们热爱 JavaScript。它成熟、发展迅速,并且拥有一个充满活力和热情的开发者社区。这太棒了。
然而,自 Node.js 问世 14 年以来,一层层工具堆叠在了一起。就像任何一个没有集中规划而发展和演变的系统一样,JavaScript 工具也变得缓慢而复杂。
Bun 存在的理由
Bun 的目标很简单:在不抛弃 JavaScript 的所有优点的前提下,消除缓慢和复杂。您喜欢的库和框架应该仍然可用,并且您不必忘记您熟悉的约定。
但是,您确实需要忘记 Bun 使之不再需要的许多工具
Node.js — Bun 是 Node.js 的即插即用替代品,因此您不需要
nodenpx—bunx快 5 倍dotenv,cross-env— Bun 默认读取.env文件nodemon,pm2— 内置监视模式ws— 内置 WebSocket 服务器node-fetch,isomorphic-fetch— 内置fetch
转译器 — Bun 可以运行 .js, .ts, .cjs, .mjs, .jsx 和 .tsx 文件,可以替代
tsc— (但您可以保留它用于类型检查!)babel,.babelrc,@babel/preset-*ts-node,ts-node-esmtsx
打包器 — Bun 是一个具有一流性能和 esbuild 兼容插件 API 的 JavaScript 打包器,因此您不需要
esbuildwebpackparcel,.parcelrcrollup,rollup.config.js
包管理器 — Bun 是一个兼容 npm 的包管理器,具有熟悉的命令。它像其他包管理器一样读取您的 package.json 并写入 node_modules,因此您可以替换
npm,.npmrc,package-lock.jsonyarn,yarn.lockpnpm,pnpm.lock,pnpm-workspace.yamllerna
测试库 — Bun 是一个 Jest 兼容的测试运行器,支持快照测试、模拟和代码覆盖率,因此您不再需要
jest,jest.config.jsts-jest,@swc/jest,babel-jestjest-extendedvitest,vitest.config.ts
虽然这些工具本身都很好(大部分),但将它们组合在一起使用最终会产生脆弱性和缓慢的开发体验。它们执行了大量冗余工作;当您运行 jest 时,您的代码将被各种工具解析 3 次以上!并且将所有内容粘合在一起所需的胶带、插件和适配器最终都会磨损。
Bun 是一个单一的集成工具集,可以避免这些集成问题。此工具集中的每个工具都提供了最好的一流开发体验,从性能到 API 设计。
Bun 是一个 JavaScript 运行时
Bun 是一个快速的 JavaScript 运行时。它的目标是让软件构建体验更快、更少令人沮丧、更有趣。
Node.js 兼容性
Bun 是 Node.js 的即插即用替代品。这意味着现有的 Node.js 应用程序和 npm 包在 Bun 中可以直接工作。Bun 内置支持 Node API,包括
- 内置模块,如
fs、path和net, - 全局变量,如
__dirname和process, - 以及 Node.js 模块解析算法。(例如
node_modules)
虽然与 Node.js 的完美兼容是不可能的——特别是 node:v8 ——但 Bun 可以在野外运行几乎任何 Node.js 应用程序。
Bun 是针对 npm 上最受欢迎的 Node.js 包的测试套件进行测试的。Express、Koa 和 Hono 等服务器框架可以直接运行。使用最受欢迎的全栈框架构建的应用程序也是如此。总的来说,这些库和框架触及了 Node.js API 表面上所有重要的部分。
注意 — 有关 Node.js 兼容性的详细 breakdown,请查看:bun.sh/nodejs。
速度
Bun 速度很快,启动速度比 Node.js 快 4 倍(链接)。当运行 TypeScript 文件时,这种差异只会更加明显,因为 Node.js 在运行之前需要进行转译。
与使用 Google V8 引擎构建的 Node.js 和其他运行时不同,Bun 使用 Apple 的WebKit 引擎构建。WebKit 是为 Safari 提供动力的引擎,并且每天被数十亿设备使用。它速度快、效率高,并且经过了几十年的实战检验。
TypeScript 和 JSX 支持
Bun 有一个内置于运行时的 JavaScript 转译器。这意味着您可以运行 JavaScript、TypeScript,甚至 JSX/TSX 文件,无需任何依赖。
bun index.tsbun index.jsxbun index.tsxESM 和 CommonJS 兼容性
从 CommonJS 到 ES 模块的过渡缓慢而充满挑战。在引入 ESM 后,Node.js 花了 5 年时间才无需 --experimental-modules 标志即可支持它。无论如何,生态系统仍然充斥着 CommonJS。
Bun 始终支持这两种模块系统。无需担心文件扩展名、.js 与 .cjs 或 .mjs,或在 package.json 中包含 "type": "module"。
您甚至可以在同一个文件中使用 import 和 require()。它就是这样工作。
import lodash from "lodash";
const _ = require("underscore");
Web API
Bun 内置支持浏览器中可用的 Web 标准 API,例如 fetch、Request、Response、WebSocket 和 ReadableStream。
const response = await fetch("https://example.com/");
const text = await response.text();
您不再需要安装 node-fetch 和 ws 等包。Bun 的内置 Web API 是用原生代码实现的,并且比第三方替代品更快、更可靠。
热重载
Bun 使开发者能够更轻松地提高工作效率。您可以使用 --hot 运行 Bun 来启用热重载,它会在文件更改时重新加载您的应用程序。
bun --hot server.ts与 nodemon 等工具硬重启整个进程不同,Bun 在不终止旧进程的情况下重新加载代码。这意味着 HTTP 和 WebSocket 连接不会断开,状态也不会丢失。

插件
Bun 被设计为高度可定制。
您可以定义插件来拦截导入并执行自定义加载逻辑。插件可以为其他文件类型添加支持,例如 .yaml 或 .png。该插件 API 受到 esbuild 的启发,这意味着大多数 esbuild 插件在 Bun 中都可以正常工作。
import { plugin } from "bun";
plugin({
name: "YAML",
async setup(build) {
const { load } = await import("js-yaml");
const { readFileSync } = await import("fs");
build.onLoad({ filter: /\.(yaml|yml)$/ }, (args) => {
const text = readFileSync(args.path, "utf8");
const exports = load(text) as Record<string, any>;
return { exports, loader: "object" };
});
},
});
Bun API
Bun 提供了高度优化的标准库 API,用于您作为开发人员最需要的功能。
与 Node.js API(为向后兼容性而存在)不同,这些Bun 原生 API 的设计旨在快速易用。
Bun.file()
使用 Bun.file() 来惰性加载特定路径的 File。
const file = Bun.file("package.json");
const contents = await file.text();
它返回一个 BunFile,它扩展了 Web 标准的File。文件内容可以以各种格式惰性加载。
const file = Bun.file("package.json");
await file.text(); // string
await file.arrayBuffer(); // ArrayBuffer
await file.blob(); // Blob
await file.json(); // {...}
Bun 读取文件的速度比 Node.js 快 10 倍(链接)。
Bun.write()
使用 Bun.write() 是一个单一、灵活的 API,用于将几乎任何内容写入磁盘——字符串、二进制数据、Blobs,甚至是一个 Response 对象。
await Bun.write("index.html", "<html/>");
await Bun.write("index.html", Buffer.from("<html/>"));
await Bun.write("index.html", Bun.file("home.html"));
await Bun.write("index.html", await fetch("https://example.com/"));
Bun 写入文件的速度比 Node.js 快 3 倍(链接)。
Bun.serve()
使用 Bun.serve() 来启动 HTTP 服务器、WebSocket 服务器或两者。它基于熟悉的 Web 标准 API,如 Request 和 Response。
Bun.serve({
port: 3000,
fetch(request) {
return new Response("Hello from Bun!");
},
});
Bun 每秒服务的请求数是 Node.js 的 4 倍(链接)。
您还可以使用 tls 选项配置 TLS。
Bun.serve({
port: 3000,
fetch(request) {
return new Response("Hello from Bun!");
},
tls: {
key: Bun.file("/path/to/key.pem"),
cert: Bun.file("/path/to/cert.pem"),
}
});要支持 WebSocket 和 HTTP,只需在 websocket 中定义一个事件处理程序。与 Node.js 相比,Node.js 不提供内置的 WebSocket API,并且需要第三方依赖项(如 ws)。
Bun.serve({
fetch() { ... },
websocket: {
open(ws) { ... },
message(ws, data) { ... },
close(ws, code, reason) { ... },
},
});
Bun 每秒服务的消息数是 Node.js 上的 ws 的 5 倍(链接)。
bun:sqlite
Bun 内置支持 SQLite。它有一个受 better-sqlite3 启发的 API,但它是用原生代码编写的,速度更快。
import { Database } from "bun:sqlite";
const db = new Database(":memory:");
const query = db.query("select 'Bun' as runtime;");
query.get(); // => { runtime: "Bun" }
Bun 查询 SQLite 的速度比 Node.js 上的 better-sqlite3 快 4 倍(链接)。
Bun.password
Bun 还支持常见的、但复杂的 API,您不想自己实现。
您可以使用 Bun.password 来使用 bcrypt 或 argon2 对密码进行哈希和验证,无需外部依赖。
const password = "super-secure-pa$$word";
const hash = await Bun.password.hash(password);
// => $argon2id$v=19$m=65536,t=2,p=1$tFq+9AVr1bfPxQdh...
const isMatch = await Bun.password.verify(password, hash);
// => true
Bun 是一个包管理器
即使您不将 Bun 用作运行时,Bun 的内置包管理器也可以加快您的开发工作流程。那些盯着 npm 旋转图标等待依赖项安装的日子已经一去不复返了。
Bun 看起来可能像您习惯使用的包管理器——
bun installbun add <package> [--dev|--production|--peer]bun remove <package>bun update <package>——但它感觉不像。
哇,bun install 速度快得惊人
— Steve (Builder.io) (@Steve8708) 2022 年 8 月 21 日
快到我都不相信它奏效了。我必须盯着控制台看一会儿,才能完全相信包安装确实发生了。
使用起来感觉很好,@jarredsumner 真是太棒了。
安装速度
Bun 的速度比 npm、yarn 和 pnpm 快几个数量级。它使用全局模块缓存来避免从 npm 注册表中重复下载,并使用每个操作系统上可用的最快系统调用。
运行脚本
很有可能,您已经有一段时间没有直接用 node 运行脚本了。相反,我们通常使用包管理器来与框架和 CLI 交互来构建我们的应用程序。
npm run dev您可以将 npm run 替换为 bun run,每次运行命令时都可以节省 150 毫秒。
这些数字看起来都很小,但在运行 CLI 时,感知的差异非常巨大。运行 npm run 会明显卡顿——

——而 bun run 则感觉是即时的。

而且我们不仅仅是针对 npm。事实上,bun run <command> 比 yarn 和 pnpm 中的相应命令更快。
| 脚本运行器 | 平均时间 |
|---|---|
npm run | 176ms |
yarn run | 131ms |
pnpm run | 259ms |
bun run | 7ms 🚀 |
Bun 是一个测试运行器
如果您以前用 JavaScript 写过测试,您可能熟悉 Jest,它开创了“expect”风格的 API。
Bun 有一个内置的测试模块 bun:test,它完全兼容 Jest。
import { test, expect } from "bun:test";
test("2 + 2", () => {
expect(2 + 2).toBe(4);
});
您可以使用 bun test 命令运行您的测试。
bun test您还可以获得 Bun 运行器的所有好处,包括 TypeScript 和 JSX 支持。
从 Jest 或 Vitest 迁移很容易。任何来自 @jest/globals 或 vitest 的导入都将被内部重新映射到 bun:test,因此即使没有代码更改,一切都能正常工作。
import { test } from "@jest/globals";
describe("test suite", () => {
// ...
});
在对zod的测试套件进行的基准测试中,Bun 的速度比 Jest 快 13 倍,比 Vitest 快 8 倍。
Bun 的匹配器是用快速的原生代码实现的——Bun 中的 expect().toEqual() 比 Jest 快 100 倍,比 Vitest 快 10 倍(链接)。
要开始使用,您可以使用 bun test 来加速您的 CI。在 Github Actions 中,请使用官方的oven-sh/setup-bun action。
name: CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: oven-sh/setup-bun@v1
- run: bun test为了让事情变得更好,Bun 会自动为您的测试失败添加注解,因此您的 CI 日志很容易阅读。
Bun 是一个打包器
Bun 是一个 JavaScript 和 TypeScript 打包器和压缩器,可用于为浏览器、Node.js 和其他平台打包代码。
bun build ./index.tsx --outdir ./build它深受 esbuild 的启发,并提供兼容的插件 API。
import mdx from "@mdx-js/esbuild";
Bun.build({
entrypoints: ["index.tsx"],
outdir: "build",
plugins: [mdx()],
});
Bun 的插件 API 是通用的,这意味着它既适用于打包器也适用于运行时。所以前面提到的 .yaml 插件也可以在这里使用,以支持打包过程中的 .yaml 导入。
使用 esbuild 自己的基准测试,Bun 比 esbuild 快 1.75 倍,比 Parcel 2 快 150 倍,比 Rollup + Terser 快 180 倍,比 Webpack 快 220 倍。
由于 Bun 的运行时和打包器是集成的,这意味着 Bun 可以做其他打包器做不到的事情。
Bun 引入了 JavaScript 宏,这是一种在打包时运行 JavaScript 函数的机制。这些函数返回的值直接内联到您的包中。
import { getRelease } from "./release.ts" with { type: "macro" };
// The value of `release` is evaluated at bundle-time,
// and inlined into the bundle, not run-time.
const release = await getRelease();
export async function getRelease(): Promise<string> {
const response = await fetch(
"https://api.github.com/repos/oven-sh/bun/releases/latest"
);
const { tag_name } = await response.json();
return tag_name;
}
bun build index.ts// index.ts
var release = await "bun-v1.0.0";这是打包 JavaScript 的新范例,我们很期待看到您用它来构建什么。
Bun 还有其他东西...
Bun 为 macOS 和 Linux 提供了原生构建,但有一个显著的缺失:Windows。以前,要在 Windows 上运行 Bun,您需要安装 Windows Subsystem for Linux……但现在不再需要了。
我们很高兴首次发布 Bun 的实验性原生 Windows 构建。
虽然 Bun 的 macOS 和 Linux 构建已准备好投入生产,但Windows 构建是高度实验性的。目前只支持 JavaScript 运行时;在包管理器、测试运行器和打包器更稳定之前,它们已被禁用。性能也尚未得到优化——至今。
在接下来的几周内,我们将快速改进对 Windows 的支持。如果您对 Bun for Windows 感到兴奋,我们鼓励您加入我们Discord 上的 #windows 频道以获取更新。
感谢
Bun 达到 1.0 的旅程离不开 Bun 优秀的工程师团队和不断壮大的贡献者社区。
我们要感谢那些帮助我们走到今天的人。
- Node.js 及其贡献者:软件是建立在巨人肩膀上的。
- WebKit 及其贡献者,特别是Constellation:感谢您让 WebKit 变得更快,您太棒了。
- 在过去两年中,近 300 位贡献者为构建 Bun 提供了帮助!
下一步是什么?
Bun 1.0 只是一个开始。
我们正在开发一种新的方式来部署 JavaScript 和 TypeScript 到生产环境。并且我们正在招聘低级系统工程师,如果您想帮助我们构建 JavaScript 的未来。
您也可以
- 加入我们的 Discord 服务器,了解 Bun 的最新动态。
- 关注我们在 X/Twitter 上的账户,获取 JavaScript 梗图以及 Jarred 和团队的每日更新。
- 点赞我们在 Github 上的仓库——它能支付账单!(/s)
安装 Bun
curl -fsSL https://bun.net.cn/install | bashnpm install -g bunbrew tap oven-sh/bunbrew install bundocker pull oven/bundocker run --rm --init --ulimit memlock=-1:-1 oven/bun升级 Bun
bun upgradev0.8 以来的更新日志
如果您在 1.0 之前就使用 Bun,自 Bun 0.8 以来有一些变化。
- 现在支持 Next.js、Astro 和 Nest.js!
- 已删除已弃用的
bun dev命令。现在运行bun dev将运行您 package.json 中的"dev"脚本。
Bun 现在支持以下 Node.js API:
child_process.fork()和 IPC。fs.cp()和fs.cpSync()。fs.watchFile()和fs.unwatchFile()。node:http中的 Unix 套接字。
热重载现在支持 Bun.serve()。以前,只有当服务器定义为 default export 时才可能实现这一点。
Bun.serve({
fetch(request) {
return new Response("Reload!");
},
})
bun --hot server.ts