I Built an npm Package to Stop Manually Adding Express.js Routes to Bruno
I started my full-stack journey with MERN and was heavily dependent on Postman. Over time I realised Postman is too heavy for my system…
I Built an npm Package to Stop Manually Adding Express.js Routes to Bruno

I started my full-stack journey with MERN and was heavily dependent on Postman. Over time I realised Postman is too heavy for my system with too many features I’ll never touch. I was using maybe 1% of what it have.
The funny part is that I have an 8 GB RAM laptop. And lol… Postman is built on Electron.js. So imagine VS Code and Postman both uses Electron, Electron and Brave both runs on Chromium and Chromium loves RAM which I don’t have. It was a bad combination.
So I opened my browser, searched for a Postman alternative, and saw a dog.
Why I Love Bruno
Bruno is simple. The UI doesn’t hit you in the face. Collections are easy to customise and everything just works. I spent less than 8 months with Postman and over a year with Bruno, which says a lot.
But after a year, I started noticing a problem and it wasn’t Bruno’s fault. It’s a problem with API clients in general.
The Problem With Any API Client
Pick any API client like Bruno, Postman, Insomnia, whatever. When you build a server with Express.js and want to test your endpoints, you have to manually create every single endpoint inside that client. One by one.
There was no way to take your Express.js endpoints and send them directly into these tools.
Half Solution: Swagger Docs
Swagger Docs lets you generate API documentation and some backend frameworks like FastAPI have great built-in support for it. But with Express.js, the truth is you need a lot of manual configuration for each endpoint and you’re back to square one. A lot of setup just to send a request to your own backend.
The Real Solution: Auto-Generating Bruno Collections
The solution is Bruno. But the question was how do you get your Express.js endpoints into Bruno automatically, without creating each one by hand?
Here’s what I found out. when you create a new collection in Bruno, it stores the collection data in .bru files. In Bruno v3, it switched to .yml (Open Collection format). So the question becames what if we just tracked all Express.js endpoints and generated that .yml file automatically when the server starts?
Why Bruno Went From .bru to .yml
Bruno v3 introduced Open Collection, which is essentially YML with some special fields like name, type, and body. The reason for the switch? .yml is something most developers and DevOps folks already work with. It's easier to read and edit compared to .bru, which had its own slight learning curve.
And why not JSON? Honestly, I don't know either.
I Almost Reinvented the Wheel
My first instinct was to build my own API client specifically for Express.js. But API clients aren’t just request-and-response tools, they handle headers, cookies, WebSockets, GraphQL, gRPC, auth flows, and a hundred other things we don’t think about, and still sucks. Building one from scratch sounded simple on paper, like Quar Studio, but it’s a completely different beast in practice.
So instead of building yet another client, I went through Bruno’s docs on .bru and .yml formats and asked myself, what if we just generate these files automatically, without doing anything extra?
How Express Router Helps
Express Router (express.Router) does more than just organise your routes. It actually tracks every endpoint you define with .get, .post, .put, .delete, etc. and stores the path and method inside Router.stack.
But Router.stack alone wasn't enough. What about mounted routes? In any real Express app you're doing something like:
app.use('/api/v1/auth', authRouter);
So we also need to handle the mounted path. And Bruno collections need a folder structure not just a single .bru or .yml file. The folder has to contain some specific files for Bruno to recognise it as a valid collection. Like a opencollection.yml in root of collection folder, folder.yml in each folders etc.
The Solution: @postdog/express
To solve the problem of manually copying your Express routes into Bruno, I built a simple npm package with a single main function. It takes your Express Router with some options and generates a Bruno Collection in .yml format automatically.
Here’s how you use it:
npm i @postdog/express
// routes/auth.js
import { Router } from "express";
import { Postdog } from "@postdog/express";
const router = Router();
router.post("/register", (req, res) => {
res.status(201).json({ success: true });
});
export default Postdog(router, { name: "collections", mount: "/auth" });
Postdog takes two parameters your Express Router instance and an options object. It returns a normal Express Router with no special changes. Under the hood, it creates all the files Bruno needs in .yml format. If the collection doesn't exist yet, or if a particular endpoint is missing, it adds it. Endpoint names are auto-generated based on the route path. so /register becomes register with method post.
You can find the full options and details on the Postdog GitHub.
What’s Next
Right now @postdog/express targets Bruno, but the same idea can work for other clients that support importable collection formats. If you're tired of manually syncing your Express routes with your API client, give it a try and let me know how it goes.
메타데이터
- post_id
- d73d2c5a396b
- slug
- i-built-an-npm-package-to-stop-manually-adding-express-js-routes-to-bruno-d73d2c5a396b
- url
- https://medium.com/@ismailbinmujeeb/i-built-an-npm-package-to-stop-manually-adding-express-js-routes-to-bruno-d73d2c5a396b
- canonical_url
- https://medium.com/@ismailbinmujeeb/i-built-an-npm-package-to-stop-manually-adding-express-js-routes-to-bruno-d73d2c5a396b
- author_url
- https://medium.com/@ismailbinmujeeb
- status
- ok
- fetched_at
- 2026-06-20 20:29:01