Bruno 是一个开源、离线优先的 API 客户端(MIT 协议,GitHub 40k+ star)。和 Postman、Insomnia 最大的不同只有一条:你的接口集合是本地文件夹里的一堆纯文本文件,不是厂商云端的 JSON 大对象。不需要注册账号,不需要同步服务,接口集合和你的代码一起进 Git、一起走 Code Review。
一个真正带界面的实用软件——而且是每个做后端、做客户端联调的人都绕不开的那类工具。
一、为什么是它
用 Postman 的人多少都遇到过这几件事:
换个电脑,集合在云端,但得登录、得等同步、离线时功能受限;
团队协作要按人头买席位;
集合导出是一个几万行的 JSON,Git diff 出来完全没法看,评审更无从谈起;
内网 / 涉密环境不方便把请求 URL、Token 往第三方服务器上送。
Bruno 的设计取舍正好戳在这些点上:
一句话概括它的价值:接口调试从"某个人云端账号里的一份资产",变成了"跟着代码走的工程产物"。
二、安装
它是带界面的桌面软件,Windows / macOS / Linux 三平台都有。
# macOS
brew install bruno
# Windows(三选一)
winget install Bruno.Bruno
choco install bruno
scoop install bruno
# Linux
sudo snap install bruno
flatpak install flathub com.usebruno.Bruno
也可以直接从官网下载安装包:.exe / .msi(Windows)、.dmg(macOS)、.AppImage / .deb / .rpm(Linux)。
Windows 用 MSI 批量部署的公司注意:可以用
msiexec /i Bruno.msi AUTOUPDATE_ENABLED=false统一关掉自动更新。企业部署时这个参数挺有用。
配套的 CLI(跑 CI 用,跟桌面端是两个东西):
npm install -g @usebruno/cli
bru --version
装完打开就是工作区,没有注册、没有登录、没有引导广告——这不是功能缺失,是它的产品立场。
三、集合就是文件夹
Bruno 里一个 collection 就是一个目录,每个请求是一个文件:
my-api/
├── bruno.json # 集合元信息(名称、忽略规则)
├── environments/ # 环境变量
│ ├── dev.bru
│ ├── staging.bru
│ └── production.bru
├── auth/
│ ├── login.bru
│ └── refresh-token.bru
├── users/
│ ├── list-users.bru
│ ├── get-user.bru
│ └── create-user.bru
└── orders/
└── create-order.bru
目录结构就是你的 API 资源结构,文件夹怎么分、文件怎么命名,直接决定 Git diff 好不好读。建议一开始就把集合目录建在项目仓库里(比如 api-collection/),而不是随便找个桌面文件夹。
格式演进提醒:早期及目前主流的请求文件是
.bru格式(下面的例子都是它),Bruno v4 起官方在推 OpenCollection YAML 格式(集合根目录会出现opencollection.yml,环境文件变成environments/local.yml)。老集合照常能用,官方也提供转换。两者思路一样:纯文本、可读、可 diff。
四、一个请求文件长什么样
这是 Bruno 最值得看的东西——一个完整的 POST 请求带鉴权、带断言:
meta {
name: Create User
type: http
seq: 2
}
post {
url: {{baseUrl}}/users
body: json
auth: bearer
}
headers {
Content-Type: application/json
X-Request-ID: {{$randomUUID}}
}
auth:bearer {
token: {{authToken}}
}
body:json {
{
"name": "{{userName}}",
"email": "{{userEmail}}"
}
}
script:post-response {
bru.setVar("createdUserId", res.body.id);
}
tests {
test("状态码是 201", function() {
expect(res.status).to.equal(201);
});
test("返回了用户 ID", function() {
expect(res.body.id).to.be.a('number');
});
}
三十来行,一个不懂这个工具的人也能看懂改了什么。这就是它能进 Code Review 的原因——换成 Postman 那种导出的 JSON,评审时你只会看到一坨 diff。
常用块一览:
环境文件(environments/dev.bru):
vars {
baseUrl: http://localhost:3000/api
userName: dev-user
}
vars:secret [
authToken
]
vars:secret 里的变量名会被提交(团队知道有这么个变量),但值不落盘,存到本地的 .env 文件里,你把那个文件加进 .gitignore 就完事了。这是"团队知道有哪些密钥"和"密钥不进仓库"之间的一个很好平衡。
五、速查表
GUI 里最常用的
CLI
脚本里能用的 API
六、五个真实场景
场景 1:登录拿 Token,后续请求自动带上
这是接口调试里最高频的痛点。在 auth/login.bru 的后置脚本里一句话解决:
script:post-response {
if (res.status === 200) {
bru.setEnvVar("authToken", res.body.token);
}
}
之后所有请求的 auth:bearer 里都写 {{authToken}},登录一次,全集合畅通。再也不用每次手动复制 Token 粘到别的请求里。
场景 2:一套请求,三个环境
同一份集合,在 environments/ 下建 dev.bru、staging.bru、production.bru,各自的 baseUrl 写自己的值。GUI 里点下拉切换,CI 里用 --env staging。
不要在请求里硬编码 URL——这是新手最常犯的错,一旦硬编码,换环境就得逐个文件改。
场景 3:密钥留在本地,不进仓库
vars:secret [
authToken
apiKey
]
变量名进 Git(同事知道集合依赖哪些密钥),值写进本地 .env,.env 进 .gitignore。再配合 bru run --env-file .env.local 在 CI 里注入。
看着不起眼,但这是很多团队从 Postman 迁到 Bruno 的直接动机——接口调试不该意味着把生产 Token 托管在别人服务器上。
场景 4:CI 里跑接口回归测试
npm install -g @usebruno/cli
bru run --env ci \
--reporter-html reports/api-test.html \
--reporter-junit reports/api-test.xml
JUnit 格式能被绝大多数 CI(Jenkins、GitLab CI、GitHub Actions)直接解析成测试报告;HTML 报告丢成构建产物,出问题时直接翻。官方也提供 CLI 的 Docker 镜像,CI 里不想装 Node 就直接用镜像跑。
场景 5:从 Postman / OpenAPI 迁过来
# 从 Postman 导出的集合文件导入
bru import postman collection.json
# 直接照着线上 OpenAPI 规范生成一整套集合
bru import openapi \
--source https://petstore3.swagger.io/api/v3/openapi.json \
--output ./petstore-api \
--collection-name "Petstore API"
第二条尤其香:你的后端只要维护了 OpenAPI 文档,就能一键生成可跑的接口集合,文档和调试工具不会脱节。
七、和其他工具怎么选
我的建议:个人或小团队、代码放 Git、在意数据隐私 → 直接上 Bruno;需要产品、测试、后端一起在线协作、要 Mock 服务 → Apifox 这类一体化平台更省事。两者不冲突,不少人 Bruno 负责日常调试、平台工具负责团队协作。
八、常见坑
九、上手路径
第一天:装好桌面端,在项目仓库里建一个
api-collection/目录当集合,把最常用的 3 个接口建进去;第二天:把接口里的 URL 全部抽成变量,建
dev/staging两个环境文件;第一周:写一个登录请求,在后置脚本里
setEnvVar存 Token,让其余请求自动带上;第二周:给关键接口补
tests断言,在 GUI 里用集合运行器跑一遍;再往后:装 CLI,把
bru run --env ci --reporter-junit接进流水线,接口测试正式变成工程的一环。
一句话总结:如果你在意"接口调试产物该不该进版本库",Bruno 给出的答案是——该,而且它本来就该是一堆能读能 diff 的文本文件。
参考
官网:https://www.usebruno.com/
下载与安装:https://docs.usebruno.com/get-started/bruno-basics/download
官方快速上手教程:https://blog.usebruno.com/bruno-tutorial
CLI 文档:https://docs.usebruno.com/bru-cli/overview
从 Postman 迁移:https://docs.usebruno.com/get-started/import-export-data/import-collections
源码:https://github.com/usebruno/bruno
本文基于 2026 年 Bruno 官方文档与 v4 版本编写。v4 起官方在推行 OpenCollection YAML 格式,旧
.bru集合仍可用,具体细节以官方文档为准。