Mark Ku's Blog
Podcast ConversationAI dialogue version of this article · Mandarin audio

Foreword: The Pain Points of API Testing Tools and the 2026 Turning Point

In the daily life of a backend developer, API testing tools are software that nearly every engineer opens every day. In the past, Postman became the de facto industry standard with its intuitive interface. However, as time went on, many teams began to feel the hidden burdens it brought. This was especially true in 2026, when Postman significantly adjusted its pricing strategy, limiting its free plan to single-user access. For team collaboration, you had to upgrade to a license costing 19美元的Team方案。這意味著一個僅僅5人的小團隊,每年就得支付高達19 美元的 Team 方案。這意味著一個僅僅 5 人的小團隊,每年就得支付高達 1,140 per person per month, which was undoubtedly a significant expense for many startups and small to medium-sized teams.

In the search for alternatives, we might have tried VS Code's REST Client extension. While lightweight, it lacks a standalone GUI and intuitive collection management, making it difficult to maintain as project scale increases. Another well-known open-source project, Hoppscotch (formerly Postwoman), is also a good choice, but its web-based design sometimes raises concerns for security teams regarding offline support and the privacy of sensitive corporate data.

As we mentioned in Reflecting on What I Did to Improve the Developer Experience, optimizing the development process and toolchain is key to improving team efficiency 2. Against this backdrop, an open-source API testing tool called Bruno has quietly emerged. It has not only garnered over 50,000 stars on GitHub and adopted a permissive MIT license, but it has also redefined the API testing workflow with its "Git-native" and "fully offline" design philosophy.


Why Choose Bruno? Core Advantages and Technical Architecture

The biggest difference between Bruno and traditional API testing tools lies in its approach to data storage architecture.

1. File-System First

Postman's data is synced to the cloud by default or exported as a single, massive JSON file that's difficult to version control. Bruno, on the other hand, adopts a file-system-first design. It stores every API request as a separate, plain text .bru file (using its custom Bru Markup Language).

This means you can place your API test files directly into your project directory, commit them into your Git repository along with your code, and conduct code reviews via Pull Requests (PRs). Here is an example of a typical .bru file:

meta {
  name: 取得會員資料
  type: http
  seq: 1
}

get {
  url: {{baseUrl}}/api/v1/users/123
  body: none
  auth: bearer
}

auth:bearer {
  token: {{token}}
}

assert {
  res.status: eq 200
  res.body.status: eq "success"
}

2. Fully Offline and Secure

By default, Bruno operates 100% offline. It doesn't force you to link a cloud account; all your API collections, environment variables, and secrets are stored only on your local hard drive. For enterprises that prioritize security and data privacy, this completely eliminates the risk of sensitive API information being leaked to third-party clouds.

3. Full Functionality and CI/CD Automation

Though lightweight, Bruno's feature set is quite complete. It supports not only REST, GraphQL, and WebSocket but also allows you to write pre-request scripts and post-response assertions using JavaScript. Paired with the official @usebruno/cli tool, we can easily integrate API tests into our deployment pipeline to achieve automated regression testing.

To give you a more intuitive understanding of the differences, we've compiled the following comparison table:

Feature / CharacteristicBrunoPostman (2026 Plan)VS Code REST Client
License ModelOpen Source (MIT)Closed Source Commercial (Limited Free)Open Source
Team Collaboration Cost$0$0** (開源版)$19 / user / month
Storage MethodLocal plain text (.bru)Cloud sync / Massive JSONLocal plain text (.http)
Git FriendlinessVery High (PR conflicts are easy to resolve)Poor (Hard to merge on conflict)High
GUI InterfaceStandalone desktop appStandalone desktop appIntegrated within VS Code
CLI ExecutionSupported (@usebruno/cli)Supported (Newman)More limited support

Implementation Steps: From Installation to a Team Collaboration Workflow

Next, we'll demonstrate how to integrate Bruno into your daily development workflow.

Step 1: Cross-Platform Installation and Creating a Collection

Bruno supports Windows, macOS, and Linux. You can download it directly from the official website or install it quickly via a package manager:

# macOS (Homebrew)
brew install bruno

# Windows (Chocolatey)
choco install bruno

After installation, open the Bruno interface and select "Create Collection". It's recommended to point this collection's directory directly inside your current project folder (e.g., ./tests/api). This allows your API test files to be managed alongside your project's source code.

Step 2: Configuring Environment Variables and API Requests

In actual development, we usually have different environments like development (Dev), testing (Test), and production (Production). In Bruno, you can click the environment settings icon in the top right corner to create different environment configurations.

For example, we can set up a Dev environment and add a baseUrl variable. When configuring an API request, you can dynamically insert this variable using double curly braces {{baseUrl}}.

💡 Pro Tip: If your project uses an API gateway to manage traffic, you can refer to Building an Efficient API Management Platform: Deploying Kong Gateway from Scratch - Part 1 to set up your backend infrastructure 3, and then use Bruno for end-to-end integration testing.

Step 3: Writing Test Assertions and Scripts

In Bruno, we can use JavaScript to handle complex API workflows. For instance, before sending a request, we might need to dynamically generate a signature, or after receiving a response, automatically write a token to an environment variable.

In the Post-Response section of the Script tab, you can write something like this:

// 取得回應中的 Token 並寫入環境變數
const data = res.getBody();
if (data && data.token) {
  bru.setEnvVar("token", data.token);
}

Meanwhile, in the Assert tab, we can set expected results in a declarative way without writing complex JS code:

ExpressionOperatorValue
res.statuseq200
res.body.data.idisDefined

Step 4: CI/CD and Git Collaboration

When you add or modify an API request in Bruno, you'll notice that corresponding .bru files are added to the tests/api folder in your project directory. Simply commit and push them to Git:

git add tests/api/
git commit -m "feat: 新增使用者 API 與相關測試案例"
git push

In our CI/CD pipeline, we can use the official CLI tool to run these tests automatically. Here is an example GitHub Actions workflow:

name: API Regression Testing

on: [push, pull_request]

jobs:
  api-test:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Code
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Install Bruno CLI
        run: npm install -g @usebruno/cli

      - name: Run API Tests
        run: bru run tests/api --env Dev

This way, every time a team member submits a PR, the system will automatically run the API tests, ensuring no existing interfaces are broken.

💡 Further Reading: In addition to API-level contract testing, if you also need to perform end-to-end full-scenario validation for your front-end interface or core business website, you can refer to Easily Build an End-to-End Automated Testing Environment with Microsoft Playwright to Protect Your Company's Core Website, with Teams Notifications and External Triggers. Using both together can build a more robust testing safety net 1.


Caveats: Limitations and Pitfalls During Migration

Although Bruno's advantages are very clear, we've also observed some details that require special attention when migrating from Postman:

  • Script Migration Costs: While Bruno supports JavaScript, its built-in API objects are not fully compatible with Postman's pm.* object (e.g., pm.test, pm.expect). If your Postman collections contain a large number of complex pre-request/post-response scripts, you may need to spend some time manually rewriting them after importing them into Bruno.
  • The Paywall Boundary: Bruno's core features (including the CLI, environment variables, scripting, etc.) are completely open-source and free. However, it also offers a paid Ultimate Edition (annual subscription) that mainly includes advanced enterprise features (like built-in LDAP integration, more granular UI customization, etc.). When evaluating, we recommend starting with the open-source version, which can usually satisfy the daily needs of over 95% of development teams.

Conclusion: Benefits After Adoption and Next Steps

After adopting Bruno, our most significant benefit has been the elimination of the separation between code and API documentation/test scripts. Now, API changes are reviewed and tested in the same PR as the feature code. We no longer face the dilemma of "the code has changed, but the collection in the testing tool is still on the old version." Even better, the team is completely free from the pressure of Postman's per-user licensing fees.

If your team is currently trapped by the pricing models of your API tools or wishes to bring API testing closer to a Git-based workflow, we recommend starting with a trial on a single microservice in an existing project. Create an API collection within the project and experience the seamlessness of collaborating on APIs via Git PRs. We believe that, like us, once you try it, you'll never go back.


References

Author

Mark Ku

擁有 10+ 年經驗的資深軟體工程師,現為 AI 應用 Builder,專注於大型平台架構與簡化複雜系統設計,從電商系統到訂閱與收費平台,結合 AI Agent、AI 整合與自動化開發,打造高效率且可持續演進的產品技術基礎。Read More

Found this useful?

The author's free tools, daily podcasts and newsletter are all here.

Mark Ku · This article is licensed under CC BY 4.0. Credit the author and link back to the original when reusing it.

Comments

Subscribe to Newsletter

Subscribe to get new posts delivered instantly — never miss a tech share.

By submitting, you agree to receive emails. You can anytime.

Popular Posts

View all
Mark Ku
··625

Oracle Cloud Always Free Tier: Linux Host and Static IP for a $0 Cloud Solution

Oracle Cloud Always Free Tier: Linux Host and Static IP for a $0 Cloud Solution
Mark Ku
··485

Say Goodbye to Postman's Fee Trap! A Hands-on Guide to Bruno, the Open-Source Git-Native API Testing Powerhouse.

Say Goodbye to Postman's Fee Trap! A Hands-on Guide to Bruno, the Open-Source Git-Native API Testing Powerhouse.
Mark Ku
··335

A Free, Open-Source, Notion-like Knowledge Base — A Complete Guide to Deploying and Backing Up Outline Wiki

A Free, Open-Source, Notion-like Knowledge Base — A Complete Guide to Deploying and Backing Up Outline Wiki
Mark Ku
··247

Training Your Own AI Voice: Hardware Requirements, Open-Source Model Comparison, and LoRA Fine-Tuning

Training Your Own AI Voice: Hardware Requirements, Open-Source Model Comparison, and LoRA Fine-Tuning
Mark Ku
··232

Building an Efficient API Management Platform: Deploying Kong Gateway from Scratch - Part 1

Building an Efficient API Management Platform: Deploying Kong Gateway from Scratch - Part 1
Mark Ku
··208

Setting Up Samba on Ubuntu to Share Folders with Windows 11

Setting Up Samba on Ubuntu to Share Folders with Windows 11
告別 Postman 收費陷阱!開源 Git 原生 API 測試神器 Bruno 實戰指南 - Mark Ku's Tech Notes