npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

bru2openapi

v0.0.1

Published

Generate OpenAPI specs from Bruno API collections

Readme

bru2openapi

Generate OpenAPI 3.0 specs from Bruno API collections.

bru2openapi takes a Bruno collection directory, runs every request through a capture proxy, and converts the recorded traffic into an OpenAPI specification using mitmproxy2swagger.

How it works

flowchart LR
    A[Bruno Collection] -->|bru run| B[mitmdump proxy]
    B -->|captures traffic| C[flows.mitm]
    C -->|mitmproxy2swagger| D[openapi.yaml]
  1. Reads the base URL from your Bruno environment file
  2. Starts mitmdump as a capture proxy
  3. Runs all collection requests through the proxy via the bru CLI
  4. Converts captured traffic to HAR format
  5. Generates an OpenAPI spec with mitmproxy2swagger

Installation

Requires Node.js 22+.

npm install -g bru2openapi

Quick start

# Docker mode (default) -- only requires Docker
bru2openapi ./my-collection --env Development --base-url-var BaseUrl

# Local mode -- requires mitmproxy, mitmproxy2swagger, and bru CLI
bru2openapi ./my-collection --env Development --base-url-var BaseUrl --local

If you omit required flags, the CLI will prompt you interactively.

Usage

bru2openapi <collection-dir> [flags]

ARGUMENTS
  collection-dir            Path to Bruno collection directory

FLAGS
  -e, --env <name>          Bruno environment name
  -b, --base-url-var <name> Name of the env variable holding the base URL
      --format json|xml     Expected API response format (default: json)
      --[no-]get-only       Only run GET requests (default: true)
      --include <folders>   Comma-separated folders to include, or ALL (default: ALL)
      --exclude <folders>   Comma-separated folders to exclude
      --out <dir>           Output directory (default: .)
      --local               Run locally instead of Docker
  -y, --yes                 Skip confirmation prompts

Execution modes

Docker mode (default)

Only requires Docker. The CLI builds and caches a Docker image (bru2openapi:<version>) containing mitmproxy, mitmproxy2swagger, and the Bruno CLI. The image is rebuilt automatically when the CLI version changes.

bru2openapi ./collection -e Production -b ApiBaseUrl

Local mode (--local)

Runs the pipeline directly on your machine. You need to install the dependencies yourself:

pip install mitmproxy mitmproxy2swagger
npm i -g @usebruno/cli

Then:

bru2openapi ./collection -e Production -b ApiBaseUrl --local

The CLI checks for all three dependencies at startup and tells you what to install if anything is missing.

Config file

Place a .bru2openapi.yml in your collection root to save per-collection settings:

env: Development
baseUrlVar: BaseUrl
format: xml
getOnly: true
include:
  - Stores
  - Products
forceArrayJPaths:
  - Stores
  - Order.Payments
  - Persons

Resolution order

CLI flags take precedence over the config file, which takes precedence over interactive prompts, which fall back to built-in defaults:

CLI flags > .bru2openapi.yml > interactive prompts > defaults

forceArrayJPaths (XML only)

When format: xml, XML responses are converted to JSON before schema generation. XML-to-JSON conversion can lose array semantics when a collection contains only one element. The forceArrayJPaths list tells the converter which jPaths are always arrays, using dot-separated paths from the document root (e.g. Order.Payments).

Array jPaths are also auto-discovered via two heuristics:

  • Parent element has @Type="Array" attribute
  • Multiple same-name sibling elements exist in the raw XML

Folder filtering

--include

Limit which collection folders are run. Accepts a comma-separated list or the keyword ALL:

# Only run Stores and Products folders
bru2openapi ./collection -e Dev -b BaseUrl --include Stores,Products

# Run all folders (override a restrictive config file)
bru2openapi ./collection -e Dev -b BaseUrl --include ALL

ALL cannot be combined with specific folder names (e.g. --include ALL,Stores is an error).

--exclude

Skip specific folders:

bru2openapi ./collection -e Dev -b BaseUrl --exclude Returns,Coupons

--include and --exclude are mutually exclusive.

Interactive prompts

When run in a terminal without all required flags, the CLI prompts for missing values with defaults pre-filled from the config file:

? Bruno environment (Development):
? Base URL variable (BaseUrl):
? Response format (json):
? GET requests only (Y/n):
? Include folders (ALL):
? Output directory (.):
? Run locally (no Docker) (y/N):

Press Enter to accept the default or type a new value.

Use --yes / -y to skip all prompts (for CI/scripts). If required values are still missing, the CLI exits with an error.

Output

The CLI produces these files in the output directory:

| File | Description | |---|---| | <collection-name>-openapi.yml | The generated OpenAPI spec | | flows.mitm | Raw mitmproxy capture file | | flows.har | HAR file (converted from flows) | | requests-report.json | Execution log with failures and array jPath info |

Post-generation

The generated spec is a starting point. Consider these improvements:

  1. Add descriptions to paths and parameters
  2. Add tags to group endpoints
  3. Add security schemes (e.g. Basic Auth)
  4. Parameterise path variables (replace hardcoded IDs with {paramName})
  5. Add error responses (400, 401, 404, 500)
  6. Validate: npx @redocly/cli lint <spec-file>

Development

pnpm install
pnpm test

License

ISC