新一代JS运行时——Bun
在2025 年 12 月,Bun 的开发团队正式宣布加入了Anthropic(也就是开发 Claude 的那家公司)。 这次收购在开发者圈子里引起了不小的轰动,因为它标志着 AI 模型公司开始深度垂

新一代JS运行时——Bun

发布时间:2026-04-22 (1分钟前)

2025 年 12 月,Bun 的开发团队正式宣布加入了Anthropic(也就是开发 Claude 的那家公司)。

这次收购在开发者圈子里引起了不小的轰动,因为它标志着 AI 模型公司开始深度垂直整合底层基础设施

为什么 Anthropic 要买一个 JS 运行时?

最直接的原因是Claude Code

  • 极致的性能需求: Claude Code 是 Anthropic 推出的 AI 编程工具。AI 智能体(Agent)在辅助编程时,需要频繁地执行代码、跑测试、安装依赖。Node.js 的启动速度和执行效率在“模型-代码-反馈”的高频循环中显得太重。
  • 单文件分发(Binary Distribution):Bun 能够将 JS/TS 项目打包成单个可执行文件。Claude Code 实际上就是作为一个Bun 编译的二进制文件 分发给数百万用户的。这意味着用户不需要预装 Node.js 环境,下载即用。
  • 掌控底层:随着 Claude Code 的年收入(Run-rate)迅速突破10 亿美元,它已经成为了 Anthropic 的核心产品。为了确保这个产品的稳定性,Anthropic 必须掌控它的底层运行环境,而不是依赖第三方社区的决策。

所以现在正是学习bun的好时机

安装Bun

Bun 提供了一键式安装脚本。无论你在什么系统上,通常只需要一行命令:

macOS / Linux / WSL:

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

Windows (PowerShell):

powershell -c "irm bun.sh/install.ps1 | iex"

通过npm安装

npm install -g bun

安装完成后,输入 bun --version。如果看到版本号,恭喜你,你已经拥有了目前最快的 JS 运行时。

学习 Bun 不仅仅是换一个命令名,而是要理解它如何简化了传统的 JS 开发流程

彻底告别转译配置

在 Node.js 中,运行 TypeScript 需要ts-nodetsx,运行 JSX 需要配置 Babel。 在 Bun 中,这一切都是原生的。

  • **知识点:**你可以直接运行bun index.tsbun component.tsx
  • **意义:**你的开发环境不再需要tsconfig.json(除非为了类型检查)或复杂的 Webpack/Vite 配置来做初步预览。

极速包管理 (The Package Manager)

Bun 完全兼容 npm 的生态(node_modules 结构),但速度快得惊人。

  • 常用命令:bun install(等同于npm i)
    • bun add <package>(等同于npm i <package>)
  • **知识点:**Bun 使用了特殊的二进制锁文件bun.lockb以实现极致的读取速度(当然你也可以导出为标准的yarn.lock)。

全能的 CLI 工具箱

Bun 奉行“全家桶”策略,它内置了许多原本需要第三方库的功能:

  • **读取环境变量:**默认支持.env,不需要dotenv库。直接使用process.env.PORT 即可。
  • **文件操作:**提供了高度优化的Bun.file()API,比 Node 的fs 快得多。
  • **原生 Web API:**在服务端直接支持fetchRequestResponseWebSocket,无需引入node-fetch

读取环境变量

在 Node.js 中,你通常需要npm install dotenv并在入口文件顶部写上require('dotenv').config()

**在 Bun 中:**你只需要创建一个.env文件:

PORT=3000
API_KEY=fengfeng_666

在代码里面直接读取

// index.ts
console.log(`服务端口: ${process.env.PORT}`);
console.log(`我的密钥: ${process.env.API_KEY}`);

// 甚至可以使用 Bun 提供的更现代的写法
console.log(Bun.env.API_KEY);

装一下类型

bun add -d @types/bun

文件操作

Node.js 的fs模块历史悠久,但 API 相对繁琐且同步/异步混杂。Bun.file()采用了类似 Web 标准的Blob对象,且底层针对系统调用做了零拷贝(Zero-copy)优化。

// 1. 读取文件(返回一个 BunFile 对象,它是懒加载的,不占内存)
const file = Bun.file("input.txt");

// 2. 获取文本内容(异步)
const text = await file.text();
console.log("文件内容是:", text);

// 3. 获取二进制内容
const arrayBuffer = await file.arrayBuffer();

// 4. 极简的写入操作 (代替 fs.writeFileSync)
await Bun.write("output.txt", "这是 Teacher Fengfeng 写入的新内容");

// 5. 甚至可以直接把一个 URL 的内容流式写入文件
const response = await fetch("https://example.com");
await Bun.write("website.html", response);

如果你的await报红

是因为在传统的 JS/TS 环境中,只有当一个文件包含了importexport时,它才会被视为一个ES Module (ESM),而只有 ESM 才允许在顶层直接使用await

虽然 Bun 默认就把所有文件当成模块处理(所以你能跑通),但编辑器里的 TypeScript 检查器还在坚持旧规则。

// 在最后加一个
export {}; // 加上这一行,警告立即消失

原生 Web API

Node.js 长期以来没有原生的fetch(直到最近几个版本才加入,且性能一般)。Bun 则是原生实现了 Web 标准,这意味着你的前端代码和后端代码可以高度复用。

// --- 发起 HTTP 请求 ---
const res = await fetch("https://api.github.com/repos/oven-sh/bun");
const data = await res.json();
console.log(`Bun 有 ${data.stargazers_count} 个 star!`);

// --- 建立一个简单的 WebSocket 服务 ---
Bun.serve({
  port: 8080,
  fetch(req, server) {
    // 升级 HTTP 请求为 WebSocket
    if (server.upgrade(req)) {
      return; 
    }
    return new Response("请使用 WebSocket 连接");
  },
  websocket: {
    message(ws, message) {
      console.log(`收到消息: ${message}`);
      ws.send(`Bun 已收到: ${message}`);
    },
    open(ws) {
      console.log("连接已开启");
    },
  },
});

高性能 HTTP 服务 (Bun.serve)

这是 Bun 的杀手锏。它内置了一个基于高性能 C++ 逻辑的 Web 服务器。

  • 示例代码:
Bun.serve({
    port: 3000,
    fetch(req) {
        return new Response("Welcome to Bun!");
    },
});
  • 知识点:Bun.serve支持热重载(Hot Reloading),只需运行bun --hot index.ts,修改代码后服务器会瞬间更新,无需重启。

路由

如果你想做类似 Next.js 或 Nuxt.js 那样的基于文件的路由,Bun 已经内置了引擎,不需要手动写if

const router = new Bun.FileSystemRouter({
  style: "nextjs", // 支持 [id].ts 这种动态路由语法
  dir: "./pages",  // 指定路由文件目录
});

Bun.serve({
  fetch(req) {
    const match = router.match(req);
    if (match) {
      // 匹配到了 ./pages/index.ts 或 ./pages/user/[id].ts
      return import(match.filePath).then(mod => mod.default(req, match));
    }
    return new Response("404", { status: 404 });
  },
});

或者使用类似express的路由模式

bun install elysia
import {Elysia} from 'elysia';

new Elysia()
    .get('/', () => '首页')
    .get('/user/:id', ({params: {id}}) => `用户ID: ${id}`)
    .post('/upload', ({body}) => {
        return {status: 'success'};
    })
    .listen(3000);

https配置

在 Node.js 中配置 HTTPS 通常需要引入https模块并读取文件,而 Bun 直接在配置对象中通过tls字段实现:

Bun.serve({
  port: 443,
  fetch(req) {
    return new Response("Hello from HTTPS!");
  },
  tls: {
    // 可以是字符串、Buffer,或者是 Bun.file 对象
    key: Bun.file("./key.pem"),
    cert: Bun.file("./cert.pem"),
    // 甚至可以配置证书链和密码
    ca: [Bun.file("./ca.pem")],
    passphrase: "fengfeng-secure",
  },
});

性能与限制参数

这些参数对于构建稳健的后端服务(如你的网盘项目)至关重要,能有效防止恶意攻击或内存溢出。

  • hostname: 默认为0.0.0.0。你可以设置为localhost 仅允许本地访问。
  • maxRequestBodySize: 限制上传文件的大小(字节)。
    • 默认值: 128MB。
  • reusePort: (仅限 Linux) 允许开启多个进程监听同一个端口,实现负载均衡。
Bun.serve({
  port: 3000,
  hostname: "localhost",
  maxRequestBodySize: 1024 * 1024 * 512, // 限制为 512MB
  reusePort: true,
  fetch(req) { ... }
});

环境与模式

  • development: 布尔值。如果设为true,Bun 会在页面上直接显示详细的错误堆栈信息(类似 PHP 的报错页面),方便调试。
  • unix: 指定 Unix Domain Socket 的路径。如果设置了这个参数,porthostname 将被忽略。这在通过 Nginx 反向代理到本地进程时非常有用,速度比 TCP 更快。
Bun.serve({
  unix: "/tmp/my-app.sock", // 使用 Unix 套接字通信
  development: process.env.NODE_ENV !== "production",
  fetch(req) { ... }
});

极其强大的原生 SQLite 支持

这是 Bun 区别于 Node.js 的一大特色。Bun 内置了高性能的 SQLite 驱动,不需要安装任何驱动或编译 C++ 插件,速度比better-sqlite3还要快。

import { Database } from "bun:sqlite";

const db = new Database(":memory:"); // 或 "mydb.sqlite"
const query = db.query("SELECT 'Hello Bun!' as message");
console.log(query.get()); // { message: "Hello Bun!" }

测试框架

测试也不再需要 Jest 或 Vitest。Bun 内置了bun test

  • 语法完全兼容 Jest(expect,test,describe)。
  • 惊人的速度: 由于不需要启动复杂的转换层,运行速度通常比 Vitest 快 10-100 倍。
bun test # 自动寻找 *.test.ts 文件

Bun Shell:跨平台的脚本利器

在 Node.js 中写复杂的 Shell 脚本(如ls,mkdir)通常需要处理 Windows 和 Linux 的差异,或者引入zx库。Bun 内置了$符号。

import { $ } from "bun";

// 跨平台运行 shell 命令
await $`mkdir -p new_folder`;
const files = await $`ls`.text();

单文件打包 (Bun Shell & Bun.build)

正如你提到的 Claude Code 的分发方式,Bun 可以将你的整个应用打包成一个独立的二进制执行文件

  • 命令:bun build ./index.ts --compile --outfile my-app
  • **意义:**你可以将这个my-app 文件发给任何没有安装 Node 或 Bun 的人,他们直接双击就能运行。这对于分发 AI Agent 工具或 CLI 工具简直是神技。

在 Node.js 时代,我们要分发一个工具,通常需要用户先安装 Node 环境,或者使用像pkg 这样极其沉重且容易出错的第三方包。

Bun 的--compile是原生集成的,它会将Bun 运行时、你的代码、以及node_modules** 中所有的依赖** 全部“揉”进一个几十兆的二进制文件中。

宏 (Macros) —— 进阶黑科技

这是 Bun 的杀手锏功能,允许在编译时执行代码。

你可以在打包时从数据库读取数据或进行复杂的计算,然后将结果直接硬编码进输出的 JS 文件中。

比如在编译的时候,读取package.json里面的版本

// utils.ts
import packageJson from "./package.json" assert { type: "json" };

/**
 * 这个函数会被 Bun 在打包时执行
 * 它必须返回一个可以被序列化的值(字符串、数字、对象、数组等)
 */
export function getVersion() {
  console.log("正在打包... 正在提取版本号"); // 这行日志只会在你执行 bun build 时出现在控制台
  return packageJson.version;
}
import { getVersion } from "./utils.ts" with { type: "macro" };
console.log(getVersion()); // 编译后直接变成字符串 "1.0.0"