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

@brpaz/bruno-openapi-sync

v1.0.4

Published

Sync an OpenAPI spec into a Bruno collection (OpenCollection YAML) without clobbering user-owned content.

Readme

bruno-openapi-sync

Sync an OpenAPI spec into a Bruno collection (OpenCollection YAML) while keeping manual changes like variables or scripts.

Motivation

Bruno collections built from an OpenAPI spec tend to get hand-edited over time — auth, test scripts, example bodies. Existing generators regenerate the whole collection on every run, so a re-sync after the spec changes wipes that work out. This project exists to make re-syncing safe: keep structure in lockstep with the spec while leaving anything a human touched untouched.

[!NOTE] AI-assisted / vibe-coded project, built for personal use. This tool was built end-to-end with an AI coding agent, from requirements-gathering through implementation and tests, with a human reviewing decisions and steering scope along the way. It's tested (30 tests, all passing) and has been run against a real hosted spec, but it hasn't seen production use. Use it at your own risk — read the code before trusting it with a collection you care about.

Why not Bruno's own built-in OpenAPI sync?

Bruno's Electron app has a native "sync collection from OpenAPI source" feature (bruno.json's openapi config: sourceUrl, groupBy, autoCheck, etc.) — but it's gated behind a paid plan. This tool is a free, open, CLI-based alternative: no app-side license check, works in CI/scripts, and (being closer to the metal) can implement the field-level ownership model above rather than a simpler regenerate-on-check.

Quick Start

npx @brpaz/bruno-openapi-sync sync --spec https://petstore3.swagger.io/api/v3/openapi.json --output ./my-collection

Open ./my-collection in Bruno. Change the spec, run the same command again — your edits stay, the structure stays in sync.

Features

  • Safe re-sync — generated fields (method, url, folder placement) always update; user-owned fields (runtime scripts, hand-added headers, edited auth/body) never do
  • Field-level, not file-level, ownership — a single request file can mix spec-derived and hand-written content; sync only ever touches the parts it owns
  • Orphan handling — a request whose operation was removed from the spec is deleted automatically if untouched, or kept with a warning if you've added anything to it
  • Folder sync — requests move between folders automatically when an operation's tag changes
  • --overwrite escape hatch — when you do want a clean, forced regeneration, one flag suspends every ownership rule
  • --dry-run preview — see exactly what would change (create/update/move/delete/skip) before anything is written
  • No hidden state in your request files — match-key tracking lives in a sidecar (.bruno-openapi-sync/state.yml), never in a field Bruno's own app might strip

Installation

Pre-requisites

From npm

npm install --global @brpaz/bruno-openapi-sync
bruno-openapi-sync sync --spec ./openapi.yaml --output ./my-collection

Or skip the install and run it directly with npx:

npx @brpaz/bruno-openapi-sync sync --spec ./openapi.yaml --output ./my-collection

From source

Additionally requires pnpm ≥ 11.

git clone <this-repo>
cd bruno-openapi-sync
pnpm install
pnpm build

dist/cli.mjs is then a runnable Node ESM script. Link it locally to use the bruno-openapi-sync command anywhere:

pnpm link --global
bruno-openapi-sync sync --spec ./openapi.yaml --output ./my-collection

Usage

bruno-openapi-sync sync --spec <path-or-url> --output <dir> [--overwrite] [--dry-run]

| Flag | Required | Description | | -------------------- | -------- | ------------------------------------------------------------------------------------------------- | | --spec <pathOrUrl> | yes | Local file path or http(s):// URL to an OpenAPI 3.0.x/3.1.x spec (Swagger 2.0 is rejected) | | --output <dir> | yes | Bruno collection directory. Created/bootstrapped automatically if it doesn't exist yet | | --overwrite | no | Suspend all field-ownership rules — the spec wins everywhere, including fields you've hand-edited | | --dry-run | no | Print the plan (creates/updates/moves/deletes/skips) without writing anything |

Examples

# First sync — creates the collection from scratch
bruno-openapi-sync sync --spec ./openapi.yaml --output ./my-collection

# Re-sync after the spec changed — updates structure, keeps your edits
bruno-openapi-sync sync --spec ./openapi.yaml --output ./my-collection

# Preview what a sync would doapidevtools/swagger-parser
bruno-openapi-sync sync --spec ./openapi.yaml --output ./my-collection --dry-run

# Force a clean regeneration, discarding hand-editsapidevtools/swagger-parser
bruno-openapi-sync sync --spec ./openapi.yaml --output ./my-collection --overwrite

Sample output:apidevtools/swagger-parser

Did update pets/List all pets.yml
Did move pets/Find pet by ID.yml -> animals/Find pet by ID.yml
Did delete pets/Create a pet.yml
Did skip deleting Health check.yml (has a runtime block (scripts/tests/assertions/variables))
1 created, 2 updated, 1 moved, 1 deleted, 1 skipped.
warning: Kept orphaned request at Health check.yml (operation "getHealth" is no longer in the spec) — has a runtime block (scripts/tests/assertions/variables).

How field ownership works

Every request/environment file is split into three kinds of field:

  • Generatedinfo.name, http.method, http.url, folder placement, and per-entry-matched http.params/http.headers. Always overwritten from the spec on every sync.
  • Seededhttp.auth, http.body, info.seq, and environment files. Given a best-effort default the first time a request is created, then left alone on every later sync — even if you edit them, even if the spec changes.
  • User-owned — everything else: runtime scripts, settings, custom headers/params you added by hand, any extra key you add to the file. Never touched.

The match key linking a spec operation to its file across syncs is the spec's operationId, tracked in .bruno-openapi-sync/state.yml — never written into the request file itself (Bruno's own schema validation can't be trusted to preserve an unrecognized field through an open-and-save round trip).

Full rationale is in CONTEXT.md and docs/adr/.

Development

pnpm install
pnpm test        # vitest
pnpm typecheck    # tsc --noEmit
pnpm build        # tsdown -> dist/

Tests live in test/, fixture OpenAPI specs in test/fixtures/specs/. The whole tool is exercised through one library seam — sync() in src/index.ts — which the CLI and every test call directly.

Project status

Feature-complete against its original spec (.scratch/openapi-sync/spec.md): spec loading (local/URL, 3.0/3.1 only), first-sync collection creation, safe re-sync, per-entry param/header diffing, orphan handling, folder-move-on-retag, and --overwrite/--dry-run. See .scratch/openapi-sync/issues/ for the ticket-by-ticket history.

License

MIT — see LICENSE.