Skip to content
Back to all posts
Article

Bruno for Local AI APIs: Faster, Reviewable Workflows

Using Bruno to drive local AI APIs — file-based requests, OpenAPI sync, and reviewable diffs instead of throwaway curl.

9 min read

Watch (11:09)


Overview

Using Bruno to drive local AI APIs — file-based requests, OpenAPI sync, and reviewable diffs instead of throwaway curl.


Full transcript (from the video)

This talk is for engineers who already use API tools and want a cleaner mental model for Bruno. I'm not going to sell it as a prettier postman. I want to explain it as a local system. We will walk through the filebased model, the monorrepo, the parsing and file store layer, the electron shell, the CLI runner, the scripting sandbox, and the open API sync path. Then we will connect that architecture to AI applications in a concrete way. The key idea is simple.

Bruno keeps API state in local text files and gives you deterministic ways to run and verify changes. A lot of technical talks get abstract too fast.

So let us start with one product. Imagine an AI copilot for API engineering inside your repo. It reads a Bruno collection from git, notices that an authentication header changed, proposes edits to a few request files, adds a regression test, runs the collection with the Bruno CLI, and leaves a reviewable diff behind. That is the running example for this deck. It matters because it makes the AI angle concrete. We are not asking a model to wave around a gooey e. We are asking it to operate on versioned files, then hand the result to a deterministic runner.

The quickest way to understand Bruno is to separate the UI from the system underneath it. Bruno is not just a desktop app with tabs. It is a local API workflow system built around files on disk. Those files can be opened in the desktop app parsed by shared packages executed by the CLI and versioned in Git. That is why Bruno is more interesting than a simple replacement story. The important contract is not a hidden serverside workspace. The important contract is the collection on your falsy stippen and the shared code that knows how to read and run it. If you want a fast mental map of the Bruno repo, start in the packages directory.

One package holds the React UI. Another package holds the Electron shell and native desktop behavior. Another package holds the CLI runner. The file store and language packages handle parsing and writing files. The JavaScript pack package handles scripts. The request request package handles network execution details like HTTP, gRPC, websockets, DLS and proxies. Once you see that split, the repo becomes much easier to explain. Bruno is not one giant application. It is a layered system with clear package boundaries.

This is the Bruno design choice that changes everything else. The source of truth is the falsy system. Collections are just folders. Requests are files.

Environments are files. The root readme is explicit that Bruno is offline first and keeps collections directly on disk.

That means it becomes a natural collaboration layer. It also means the app does not own the truth by itself.

You can edit files outside the UI, commit them, diff them, and review them like code. For AI systems, that is a gift. Models work much better with explicit artifacts than with hidden state buried inside a desktop database.

The next important idea is the Brew file format. A Bruno request is not trapped in a binary blob or a remote workspace.

It is just a text file. That file can hold the method, URL, headers, body scripts, and tests in one place. The request example in the Bruno language package shows the pattern clearly. This is why AI assisted editing is realistic.

A model can read a request, understand its structure, propose a patch, and hand the result back for review. It does not need to reverse engineer pixels from a UI. The collection is already plain text. This is one of the most important architecture slides. Bruno does not treat the file format as a private implementation detail. The repo has dedicated packages for language conversion and file storage. The file store package exposes parse and ser sing serify functions for requests, collections, folders, environments, and deboy files. That means the desktop app and the CLI can share the same file contract. It also means external tooling has a real seam to hook into. If you ever want an AI assistant to reason about Bruno collection safely, this layer is where you want it to operate, not through click simulation. The Electron package is the runtime edge for the desktop app. It owns the parts that need local machine access, reading collections, watching files, cloning repositories, handling network execution, and storing secrets. That is a cleaned design. The React app can stay focused on presentation and interaction.

Electron can own the machine facing work. If you remember the comfy UI talk, this plays a role similar to a runtime boundary. It is the layer where local capabilities become explicit. That matters because AI tools should integrate at clear boundaries, not by poking through UI internals hoping the side effects line up. Once files on disk become the source of truth, you need a strong sync story. Bruno has one. The Electron layer watches collections and workspace metadata with Chuckyar. It reparses files, reloads environment data, and pushes updates back into the UI.

That is more important than it sounds. It means a file changed by git, a shell script, or even an AI agent still becomes part of the normal product flow.

The app does not break because the change happened outside the window. For AI applications, that is excellent. A model can edit the artifact and Bruno can react to the artifact. That is exactly the kind of deterministic handoff you want. Bruno becomes especially powerful when you stop thinking only about the window and start thinking about the runner. The CLI can execute collections, apply environments, emit JSON or JUnit or HTML reports, and return useful exit codes in CI.

Underneath that, the request package handles the hard parts like transport, proxy behavior, TLS options, and more.

This is where the AI story becomes credible. The model can draft changes, but the runner verifies them. that keeps the probabilistic step small and the deterministic step strong. Without a runner, AI tooling is a demo. With a runner, it becomes engineering. Bruno keeps validation close to the request itself. Scriptets can run before or after the request. Assertions and tests live next to the request file. That is a smart design because the artifact stays self-describing. When you inspect a file, you can see not just what call gets made, but how success is defined.

AI systems benefit from that locality. A model does not have to chase separate systems to understand intent. It can inspect the request and its checks together, propose a change, and let the runner confirm whether the new behavior still passes. This slide matters a lot for the AI angle. Bruno exposes an explicit choice between a safer sandbox and a more powerful developer mode. The CLI map safe mode to quickjs and developer mode to a node VM. The UI description is clear that the secure mode prevents fily spy spin fily spim and system command style access. That is exactly the kind of boundary you want when AI starts writing or editing scripts in an untrusted or review heavy workflow. Keep generated logic and safe mode in a trusted internal automation path. Developer mode can unlock deeper scripting. The point is not maximum power. The point is deliberate power.

Bruno already has a deterministic answer to one messy API tooling problem.

Keeping collections aligned with specs. The CLI can import open API. The Electron side also has a sync path that fetches specs, validates them, stores metadata, and reviews changes. The UI tries to preserve tests and scripts while request structure changes. That is the right split of responsibilities. Let deterministic conversion handle the boring structure. Let humans or AI help with naming examples and new tests. Do not ask the model to reinvent the import pipeline when the repo already gives you one. Bruno also has a clean story for environments and secrets. Environment files live with the collection. So the shape of the environment is easy to review. Secret values do not have to live in those files. The Electron secret store can write them separately and encrypt them locally. That split is useful for normal engineering and even more useful for AI workflows. You do not want credentials leaking into git diffs, generated patches or prompt transcripts.

Bruno gives you a cleaner boundary. Review the structure in text. Keep the sensitive values in a local store and still run real authenticated workflows.

Here is the core argument. Bruno matters to AI applications because its architecture reduces ambiguity. A model can read a request as text. The repo can parse that text into structure. Git can show the exact diff. The CLI can run the result and produce a report. The product does not depend on a hidden cloud workspace to keep state in sync. The important distinction is simple. Bruno is not valuable because it advertises AI. Bruno is valuable because it uses good software boundaries. Those boundaries make AI assistance more practical and easier to trust. Here is the concrete loop. I would actually recommend keep the collection in Git, import or sync from Open API. When the contract changes, let the AI produce a first draft for request files, examples, or tests. Review the patch like normal code. Then run Bruno headlessly in CI and feed the failures back into the next iteration. That loop is strong because each stage is legible. The model handles suggestion and synthesis. Git handles review. Bruno handles execution. Reports handle feedback. No part of the system has to pretend the model is always right. And no part of the system has to hide what changed. There are a few easy mistakes to avoid. First, do not turn Bruno back into an opaque system by building hidden state around it. Keep the collection as the contract. Second, do not let a model invent execution behavior that never becomes a file or a test. Third, do not confuse a plausible request edit with a verified one. Always run the CLI or the app runner. And fourth, do not grant maximum script power by default just because the model asked for it. Bruno already gives you better boundaries than that. Use them.

That is how the AI layer stays helpful instead of becoming a new source of drift. So the final takeaway is simple.

Bruno is not most interesting as a feature checklist. It is most interesting as a local system with strong artifacts. Collections live on disk. The language and file store packages turn them into structured data.

The electron layer connects them to a desktop experience. The CLI runner turns them into deterministic execution and those same qualities make Bruno a strong substrate for AI assisted API work. If you want models to help with API engineering, give them reviewable text, stable contracts, and a real runner.

Bruno already gives you most of that foundation.