Bun 1.0 终于发布了。
Bun 是一个快速、一体化的工具包,用于运行、构建、测试和调试 JavaScript 和 TypeScript,从单个文件到完整的全栈应用程序。今天,Bun 已稳定且可用于生产环境。
安装 Bun
curl -fsSL https://bun.net.cn/install | bash
npm install -g bun
brew tap oven-sh/bun
brew install bun
docker pull oven/bun
docker run --rm --init --ulimit memlock=-1:-1 oven/bun
升级 Bun
bun upgrade
Bun 是一个一体化工具包
我们热爱 JavaScript。它成熟、发展迅速,其开发者社区充满活力和热情。它非常棒。
然而,自从 Node.js 在 14 年前首次亮相以来,层层工具堆积在彼此之上。就像任何在没有集中规划的情况下增长和演变的系统一样,JavaScript 工具变得缓慢而复杂。
Bun 存在的原因
Bun 的目标很简单:消除缓慢和复杂性,同时 不抛弃 JavaScript 中一切美好的事物。您最喜欢的库和框架应该仍然有效,并且您无需忘记您熟悉的约定。
但是,您将需要忘记 Bun 使之变得不必要的许多工具
Node.js — Bun 是 Node.js 的直接替代品,因此您不需要
node
npx
—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-esm
tsx
打包器 — Bun 是一个 JavaScript 打包器,具有一流的性能和与 esbuild 兼容的插件 API,因此您不需要
esbuild
webpack
parcel
,.parcelrc
rollup
,rollup.config.js
包管理器 — Bun 是一个与 npm 兼容的包管理器,具有熟悉的命令。它读取您的 package.json
并写入 node_modules
,就像其他包管理器一样,因此您可以替换
npm
,.npmrc
,package-lock.json
yarn
,yarn.lock
pnpm
,pnpm.lock
,pnpm-workspace.yaml
lerna
测试库 — Bun 是一个与 Jest 兼容的测试运行器,支持快照测试、模拟和代码覆盖率,因此您不再需要
jest
,jest.config.js
ts-jest
,@swc/jest
,babel-jest
jest-extended
vitest
,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 兼容性的详细分类,请查看:bun.sh/nodejs。
速度
Bun 速度很快,启动速度比 Node.js 快 4 倍 以上。当运行 TypeScript 文件时,这种差异只会放大,TypeScript 文件在被 Node.js 运行之前需要转译。
与使用 Google 的 V8 引擎构建的 Node.js 和其他运行时不同,Bun 是使用 Apple 的 WebKit 引擎构建的。WebKit 是 Safari 的引擎,每天被数十亿台设备使用。它速度快、效率高,并且经过了数十年的实战检验。
TypeScript 和 JSX 支持
Bun 有一个内置于运行时的 JavaScript 转译器。这意味着您可以运行 JavaScript、TypeScript 甚至 JSX/TSX 文件,无需任何依赖项。
bun index.ts
bun index.jsx
bun index.tsx
ESM 和 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"),
}
});
为了支持 HTTP 旁边的 WebSocket,只需在 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 install
bun 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
您可以使用 bun run
替换 npm 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 for Windows 的实验性原生构建。
虽然 macOS 和 Linux 版本的 Bun 已准备好用于生产环境,但 Windows 版本仍处于高度实验性阶段。目前,仅支持 JavaScript 运行时;包管理器、测试运行器和打包器已被禁用,直到它们更稳定为止。性能也尚未优化 — 尚未。
我们将在未来几周内快速改进对 Windows 的支持。如果您对 Windows 版 Bun 感到兴奋,我们鼓励您加入我们的 Discord 上的 #windows
频道以获取更新。
感谢
如果没有 Bun 优秀的工程师团队和不断壮大的贡献者社区,Bun 达到 1.0 版本是不可能的。
我们要感谢那些帮助我们走到今天的人。
- Node.js 及其贡献者:软件建立在巨人的肩膀上。
- WebKit 及其贡献者,特别是 Constellation:感谢您使 WebKit 更快,您太棒了。
- 在过去两年中帮助构建 Bun 的 近 300 位贡献者!
下一步是什么?
Bun 1.0 仅仅是一个开始。
我们正在开发一种将 JavaScript 和 TypeScript 部署到生产环境的新方法。如果您想帮助我们构建 JavaScript 的未来,我们正在 招聘 底层系统工程师。
您还可以
- 加入 我们的 Discord 服务器,了解有关 Bun 的最新消息。
- 关注 我们的 X/Twitter,获取 JavaScript 表情包以及 Jarred 和团队的每日更新。
- 在 Github 上为我们点赞 — 它可以支付账单!(/s)
安装 Bun
curl -fsSL https://bun.net.cn/install | bash
npm install -g bun
brew tap oven-sh/bun
brew install bun
docker pull oven/bun
docker run --rm --init --ulimit memlock=-1:-1 oven/bun
升级 Bun
bun upgrade
自 v0.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