Bun 是比 Node 更快、开箱即用、零配置的 JS/TS 运行时 + 包管理器。可以理解为 Node 的优化升级版,性能特别好。Anthropic 已收购 Bun,并将其用于 Claude Code 底层。
一、Bun 是什么
1. 一句话理解
Node 能做的 Bun 都能做(运行 JS、装包、跑脚本、跑测试),但 更快、更简单、零配置。
| 工具 | Node 生态需要装 | Bun 自带 |
|---|---|---|
| 运行 JS/TS | node + tsc + ts-node | ✅ bun run index.ts 直接跑 |
| 包管理器 | npm / pnpm / yarn | ✅ bun add axios |
| 打包 | webpack / vite / rollup | ✅ bun build |
| 测试 | jest / vitest | ✅ bun test |
| .env 加载 | 装 dotenv + dotenv.config() |
✅ 自动加载,无需代码 |
| TypeScript | tsc + tsconfig + 一堆配置 | ✅ 直接执行 .ts,零配置 |
Bun 的野心:一个工具干掉 Node 生态里的 5~10 个独立工具。
2. 为什么快
- 底层用 Zig 语言写(像 C 一样快)
- JS 引擎用 JavaScriptCore(Safari 引擎),启动和内存比 V8 更优
- 直接操作系统调用,绕过 Node 的中间层
3. 与 Node 的兼容性
高度兼容 :绝大多数 Node 项目直接把 node 换成 bun、npm install 换成 bun install 就能跑。核心模块(fs、path、http)和全局变量(process、Buffer)都实现了。
二、TypeScript 为什么是 AI Agent 的标配
1. JS 的易错性(为什么需要 TS)
来自微软的 TypeScript 是 JS 的超集------在 JS 基础上加了一层类型约束。
JS 是弱类型,经典坑:
js
// 坑 1:浏览器 input 拿到的是字符串,不是数字
const age = input.value; // 输入 12,但拿到的是 '12'(字符串)
console.log(age + 1); // '121'(字符串拼接),不是 13
// 坑 2:+ 身兼多职,加法和字符串拼接混用
1 + '2'; // '12' (转字符串拼接)
1 + 2; // 3 (加法)
'1' + 2; // '12' (拼接)
// 坑 3:错误不报错,藏在系统里
function add(a, b) { return a + b; }
add(1, '2'); // 不报任何错,静默返回 '12'
add('用户', 20); // 不报错,返回 '用户20'
这些坑在 AI Agent、LLM 调用链里是致命的------类型错了,拼出来的 prompt、传进去的参数全是错的,排查起来非常痛苦。
2. TS 怎么解决:静态类型检查
在编译阶段(TS → JS)就提前检查类型错误,代码还没跑就把坑暴露出来。
ts
// [1.ts] 变量加类型
const nickname: string = "9527"; // nickname 只能是字符串
const age: number = 123; // age 只能是数字
age = '123'; // ❌ 立刻报错:不能把字符串赋值给数字
// [2.ts] 函数参数加类型
function add(a: number, b: number) {
return a + b; // 两个都是 number,+ 一定是加法
}
let a = 1;
let b = "2";
add(a, b); // ❌ 编译报错:第二个参数得是 number
add(a, Number(b)); // ✅ 先转类型,再传
add(a, parseInt(b)); // ✅ 或用 parseInt
add(a, +b); // ✅ 或用 + 隐式转换
关键优势:
- 静态的类型编译:TS → JS 的过程中检查类型和代码错误,不是运行时才崩
- IDE 提示极好:写代码时能看到每个参数该传什么类型,减少文档翻找
- AI Agent 标配:大型 AI 项目(nlp-demo、LLM 接入)组件多、调用链长,TS 能帮你在写代码时就把参数、返回值、接口形状锁死,降低系统风险
三、安装 Bun
Windows(PowerShell)
powershell
powershell -c "irm bun.sh/install/windows | iex"
验证安装
powershell
bun --version
# 例如:1.3.14
如果提示"无法将 bun 项识别为命令",说明环境变量还没生效,重启终端 即可(或手动把 C:\Users\用户名\.bun\bin 加到 PATH)。
四、Bun 常用命令速查
| 需求 | Bun 命令 | 对应 Node 命令 |
|---|---|---|
| 运行 JS | bun index.js |
node index.js |
| 运行 TS | bun index.ts |
需装 ts-node 等一堆 |
| 初始化项目 | bun init |
npm init |
| 安装依赖 | bun install / bun i |
npm install |
| 加一个包 | bun add axios |
npm i axios |
| 加开发依赖 | bun add -d typescript |
npm i -D typescript |
| 跑 package.json 脚本 | bun run dev |
npm run dev |
| 跑测试 | bun test |
需装 jest/vitest |
| 打包 | bun build index.ts |
需装 webpack/vite |
实战:跑你的第一个 TS 文件
1.ts:
ts
const nickname: string = "9527";
const age: number = 123;
console.log(`我是${nickname},我今年${age}岁`);
直接跑:
bash
bun 1.ts
# 输出:我是9527,我今年123岁
零配置:不需要 tsconfig、不需要 tsc 编译、不需要 ts-node,bun 直接执行 .ts。
五、Bun 自带 .env 自动加载
Node 时代的写法
js
// 需要先 bun add dotenv
import dotenv from "dotenv";
dotenv.config(); // 手动调用加载
console.log(process.env.DEEPSEEK_API_KEY);
Bun 的写法
ts
// 什么都不用装,什么都不用调用,直接用
console.log(process.env.DEEPSEEK_API_KEY);
Bun 运行时会自动读取项目目录下的 .env 文件,并注入 process.env。
运行时会看到这样的日志:
bash
◇ injected env (2) from .env ← 已加载 2 个环境变量
如果显示 injected env (0) from .env,说明 .env 文件没写对或路径不对,先检查文件名是不是 .env(没有后缀),内容是不是 KEY=VALUE 格式。
六、实战场景 1:TS 函数 + 类型安全
2.ts 演示了类型约束的实际作用:
ts
function add(a: number, b: number) { // 两个参数必须是 number
return a + b; // 保证 + 是加法,不是字符串拼接
}
let a = 1;
let b = "2"; // 这里 b 是字符串
add(a, b); // ❌ TS 直接报错,不允许传字符串
add(a, Number(b)); // ✅ 先转 number,再传
运行测试:
bash
bun 2.ts
七、实战场景 2:Promise + async/await 异步编程
3.js 演示了封装一个可 await 的 sleep 函数:
js
function sleep(t) {
// 许下一个"t 毫秒后兑现"的承诺
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(); // t 毫秒后,兑现承诺
}, t);
})
}
async function main() {
console.log('--start--');
await sleep(2000); // 等 2 秒,再往下走(异步任务同步化)
console.log('--end--');
}
main();
运行:
bash
bun 3.js
# --start--
# (等 2 秒)
# --end--
这套 Promise + async/await 是所有异步操作的通用模式:定时器、HTTP 请求、文件读取、数据库查询、LLM 调用。
八、实战场景 3:用 Bun + axios 调用 LLM
演示完整的企业级调用链:
项目结构
csharp
axios-demo/
├── index.ts ← 业务代码:写 prompt、调用 LLM
├── .env ← 存 API Key 和 Base URL(Bun 自动加载)
├── package.json ← bun add axios 自动生成
├── bun.lock ← Bun 的锁文件(对应 package-lock.json)
└── tsconfig.json ← TS 配置(Bun 自动生成)
初始化流程
bash
# 1. 进入目录
cd axios-demo
# 2. 装 axios(Bun 装包比 npm 快 10~100 倍)
bun add axios
# 3. 直接跑 TS
bun index.ts
核心代码结构
ts
import axios from "axios";
async function chat() {
try {
const res = await axios.post(
`${process.env.DEEPSEEK_BASE_URL}`, // Bun 自动从 .env 加载
{
model: 'deepseek-chat',
messages: [{
role: 'user',
content: '你好,介绍一下Bun'
}]
},
{
headers: {
'Content-Type': "application/json",
Authorization: `Bearer ${process.env.DEEPSEEK_API_KEY}`
}
}
)
console.log(res.data.choices[0].message.content);
} catch (err) {
console.log(err.message);
}
}
chat();
关于为什么 POST 比 GET 更适合 LLM 调用:
- GET 参数长度有上限,prompt 可能非常长
- API Key 放 URL 明文传输不安全
- 上传图片/文件需要请求体(body),GET 只有请求行和请求头
九、Bun 常见问题排查
| 问题 | 原因 | 解决 |
|---|---|---|
bun : 无法将"bun"项识别为命令 |
环境变量 PATH 未生效 | 重启终端 / 手动加 .bun\bin 到 PATH |
Cannot find package 'axios' |
依赖没装 | 在项目目录 bun add axios |
injected env (0) from .env |
.env 没加载到 | 检查文件名是 .env 不是 .env.txt,内容格式 KEY=VALUE |
| API 调用 401 / 认证失败 | API Key 错 / BASE_URL 错 | .env 里确认:BASE_URL 要有 api. 前缀,Key 完整 |
| 模型报 400 / 不认识 | 模型名写错 | 用官方名 deepseek-chat,不是 deepseek-v4-flash |
| TS 报错"参数类型不匹配" | 类型传错 | 用 Number() / +x / parseInt 转类型 |
十、总结
Bun 的三件套
- 运行时 :直接跑
.js和.ts,零配置 - 包管理器 :
bun add / install,比 npm 快得多 - 全家桶工具链 :.env 自动加载、打包、测试、脚本运行,全在一个
bun命令里
TypeScript 的核心价值
- 静态类型检查:编译期拦住类型坑,不在运行时炸
- AI Agent 标配:大型项目组件多、调用链长,TS 是最低成本的质量保障
- 解决 JS 弱类型三大坑 :input 拿字符串、
+拼接歧义、静默错误藏系统
什么时候用 Bun
- ✅ 新项目:直接 Bun 起手,零配置
- ✅ Node 老项目 :试下
bun install提速 +bun run跑脚本 - ✅ AI / LLM 项目:TS 类型锁死参数 + Bun 快启动,体验极佳
- ⚠️ 深度依赖特定 Node C++ 插件的老项目:先小范围试,兼容性可能有小问题
一句话 :Bun + TypeScript 是现代 AI 全栈开发的黄金组合------够快、够稳、够省心。