Migrate from Postman to Bruno

Moving from Postman to Bruno means exporting collections as JSON, importing them, rewriting Postman-specific scripts and committing collection folders to Git. This page plans that work.

On this page

Migrate from Postman to Bruno: what the move involves

Most teams start this move after Postman's March 2026 plan change, which limited the Free plan to one user who cannot create a team, or after a data residency review that asks where collections and embedded credentials live. The move is mostly collection export, import and script review, and Git replaces Postman's cloud sharing. Bruno is offline-only and has no plans for cloud sync, so a shared collection becomes a folder in a Git repository that the team clones, branches and reviews like source code. Platform or QA leads usually own the migration, with a security reviewer checking how credentials and environment files are handled before anything is committed.

The effort is driven by how much of the Postman estate is actually in use. Bruno's Migrating from Postman guide describes exporting each collection as a Collection v2 or v2.1 JSON file and importing it through the Import Collections menu, which is free on the Open Source edition. Bulk import of a full Postman data dump, the zip file Postman emails, is included only in Bruno Ultimate Edition, so teams with many collections should confirm whether they need that edition or will export one collection at a time. Bruno translates common script APIs such as pm.test, pm.environment and pm.response during import, but it flags Postman-specific packages such as postman-collection, newman and @postman/* as unsupported. Those scripts need rewriting and retesting, which is the main source of risk.

Before the first commit, decide where secrets go. Postman stores collections and environments in its cloud, while Bruno stores them as plain files in a folder, so tokens and passwords copied into environments would end up in Git history unless they are removed or referenced from a secret store. Set up a .gitignore rule for local environment files, review each imported collection for hard-coded credentials, and agree with the security owner how shared values are provided to each developer. Then run a pilot with one collection, confirm that bru run produces the test results your pipeline expects, and check the current feature list on Bruno's pricing page, since Git push, branch operations and merge conflict resolution inside the app are paid features while plain Git works on any edition.

Which Postman capabilities move cleanly to Bruno

This table maps the main Postman capabilities to their Bruno equivalents and marks each as clean, needs rework or gap. Read the status column first, then check the notes on paid editions, cloud sync and features to confirm with the vendor before you commit to a migration plan. Bruno has no cloud sync by design, so any workflow that relies on Postman's hosted sharing needs a Git-based replacement.

Postman capabilityBruno equivalentStatus and notes
Collections and foldersCollection folders on diskClean. Imports from Collection v2 or v2.1 JSON keep the folder structure.
Requests and request bodiesRequests stored as .bru or OpenCollection YAML filesClean. Review auth and body types after import against the original requests.
EnvironmentsEnvironment files in the collectionClean for plain values. Secret values need a secret manager or local handling outside Git.
Collection variables and globalsCollection and global variablesClean. Bruno translates pm.collectionVariables and pm.globals during import.
Pre-request and test scriptsBruno scripts using bru and req or res objectsNeeds rework. pm.test, pm.environment and pm.response translate, but custom logic should be tested after import.
npm packages in scriptsInstalled npm packages or rewritten logicGap. Postman-specific packages such as postman-collection, postman-runtime and newman are marked unsupported and must be rewritten.
OpenAPI importbru import command or the app's OpenAPI importClean for well-formed specs. Confirm generated requests against the source definition.
Bulk import of a full Postman data dumpBulk Postman import in Bruno Ultimate EditionPaid feature. The open-source edition imports collections one at a time from JSON exports.
Postman cloud sharing and team workspacesShared collection folders in GitGap. Bruno has no cloud sync, so sharing moves to Git branches, pull requests and access rules in your repository host.
SAML SSO and SCIMSingle sign-on and provisioning through Bruno's paid licensingPaid feature. The open-source edition does not include SAML SSO or SCIM. Confirm current scope with Bruno before planning.
Mock servers, monitors and Postman-only featuresNot covered by Bruno's documented importConfirm with Postman and Bruno. Plan alternatives such as a separate mock service if these are in use.

Which exports and integrations to move

Postman collections reach Bruno through a small set of files and import paths, and each one carries a different amount of work. Per-collection JSON exports, the account-wide data dump, OpenAPI definitions and CI jobs each need their own check before the old workspace is closed.

Per-collection Collection JSON exports

Export each collection from Postman as Collection v2 or v2.1 JSON, then import the files with Bruno's Import Collections menu. This is the path available on every edition, so it is the default for most teams. Check each imported request count against the Postman collection, and confirm that folders, auth settings and pre-request scripts came across intact before you rely on the copy.

Account-wide data dump

Postman emails a zip file containing all collections and environments when a bulk export is requested. Bruno can read this dump, but bulk import from Postman is included only in Bruno Ultimate Edition. Teams on Open Source should either import collections one at a time or budget for an Ultimate seat, and should confirm the request with a team admin, since the download window is short.

OpenAPI definitions via bru import

Where an API already has an OpenAPI specification, the bru import command can create a Bruno collection from it. This is a second import path, not a copy of Postman content: examples, tests and scripts stored only in Postman will not appear. Compare the generated requests with the Postman collection and add the missing test logic by hand.

Environments and secrets handled separately

Environment exports and Postman variables often hold base URLs, tokens and client secrets. Do not commit these into the Bruno collection folder, which lives in Git. Split non-sensitive values into environment files and move credentials into a secret store or local-only storage. Confirm with your security team which store is approved before you migrate the first environment.

Script and package rewrites

Bruno translates common pm.test, pm.environment and pm.response calls during import, but flags Postman-specific packages such as postman-collection and newman as unsupported. Any require() call to those packages must be rewritten before the collection runs. List every flagged package in the import report so the rewrite work is scoped before cutover.

CI runs rebuilt with the Bruno CLI

Pipelines that call Newman or the Postman CLI need their run step rebuilt around bru run, which produces test reports for CI. Keep the collection folder in the same repository as the pipeline definition, so a change to a request and its test ship together. Confirm that your CI runner can reach the environment hosts without Postman's cloud, and that report formats match what your dashboards expect.

Migration sequence from inventory to decommission

This sequence moves Postman collections into Bruno as Git-tracked folders, proves each step with a pilot, and ends with Postman switched off only after the team has confirmed the results. Each step names the artifact that closes it, so the team can stop at any point with a known state.

  1. Inventory collections, environments and scripts

    Export a list of every collection, environment and global in the Postman workspaces your team uses, and note which scripts contain pm.test, pm.environment or other pm.* calls and which contain require() calls. Ask a Postman team admin whether a full account data dump is needed, since Bruno's bulk import of that dump is included only in Bruno Ultimate Edition. The step is done when you have a written inventory with an owner and a flag for each collection that uses custom packages.

  2. Pilot one collection in Bruno

    Export a single low-risk collection from Postman as Collection v2 or v2.1 JSON, then open Bruno and use the Import Collections menu to bring it in, following Bruno's Migrating from Postman guide. Send a few requests against a non-production environment and compare status codes and response bodies with Postman. The step closes when the pilot collection runs end to end and the differences are recorded.

  3. Translate scripts and review flagged packages

    Review the translated pre-request and test scripts, since Bruno converts common APIs such as pm.test, pm.environment, pm.globals, pm.collectionVariables and pm.response. During import Bruno scans for require() calls and marks Postman-specific packages such as postman-collection, postman-runtime, newman and @postman/* as not supported. Produce a list of every flagged package with the rewrite it needs, and have a developer confirm each rewrite. The step is done when no script depends on an unsupported package.

  4. Move collection folders into a Git repository

    Create a Git repository for the API collections, place each imported collection in its own folder, and commit them with a short README that explains which environment files are shared and which hold local values. Keep secrets out of the repository by using local or CI-injected variables, not committed values. Confirm that a second team member can clone the repository, open it in Bruno and see the same requests. The step closes with a reviewed commit on the main branch.

  5. Run Bruno and Postman in parallel

    For a set period agreed by the team, run each migrated collection in both Postman and Bruno against the same environments and log any mismatch in responses, assertions or variables. Record the mismatches and the fix for each one in the repository's issue tracker. The step is done when a full cycle of requests has matched in both tools, or when every difference has a documented reason.

  6. Cut over and archive Postman collections

    Announce the cutover date, direct all users to the Git-backed Bruno collections, and make the Git repository the single source for changes. Keep a final Postman export of each collection in your records before anyone stops using the old workspaces. The step closes when every active collection is maintained in Git and no one needs Postman to run a request.

  7. Decommission Postman access

    Remove team members from Postman workspaces and cancel or downgrade any paid seats only after the cutover step is signed off and the exports are stored. Confirm with Postman's documentation or your account owner how long data remains available after cancellation, and keep the archive for the period your own records policy requires. The step is complete when access is revoked, seats are released and the archive location is recorded.

How Bruno imports Postman scripts and flags unsupported packages

Bruno's importer does most of the script work for you, but it does not rewrite everything. During import it translates common Postman script APIs, including pm.test, pm.environment, pm.globals, pm.collectionVariables and pm.response, into Bruno equivalents. Treat that translation as a starting point and confirm it on each request that carries a test or pre-request script. Run the request against a known response and check that each assertion still passes for the right reason, not just because the translated call returns without error. The importer also scans every script for require() calls and offers to install the npm packages it finds. Before accepting those installs, list the packages each collection depends on. Packages named postman-collection, postman-runtime, newman and anything under @postman/* are marked as unsupported in Bruno, because they depend on Postman's own runtime. Any script that imports them must be rewritten, not just re-run. Ask the team who wrote each flagged script and what it checks, since that determines the replacement logic.

Handle each flagged script as a code change with its own review. Move the rewritten script into a branch, add or update a test that fails on the old behavior and passes on the new one, and have a second engineer review the diff. Keep a short record of each script's original purpose so reviewers can confirm the replacement covers the same checks. Scripts that only used Newman for reporting may be better moved to the bru run command-line workflow, where the test results are produced by the CLI rather than by a script. Because the importer output lives in files, these fixes are tracked like any other source change. The collection folder is committed to Git, so every rewritten script shows up in review history. Confirm the exact package behavior and CLI options against Bruno's current documentation, since the supported package list can change between releases, and check the release you deploy against the Bruno GitHub releases page before you rely on it.

What drives the cost and duration of the move

This table lists the inputs that change how much work and spend the move from Postman to Bruno involves, and whether each cost is paid once or recurs. Use it to scope the migration and to write a precise request for current pricing. Bruno's paid seats only matter for the specific Git push and bulk import features listed on its pricing page.

DriverWhy it changes cost or effortOne-time or recurringHow to keep it down
Collection count and sizeEach collection is exported as Collection v2 or v2.1 JSON and imported separately, so volume drives export, review and clean-up hoursOne-timeArchive unused collections before export and migrate in batches by team
Script complexityScripts using pm.test, pm.environment and pm.response are translated on import, but custom logic still needs manual reviewOne-timeInventory scripts first and move only assertions that CI or teams still depend on
Postman-only packagesScripts that require postman-collection, postman-runtime, newman or @postman/* are flagged unsupported and must be rewrittenOne-timeSearch scripts for require() calls before import and plan rewrites per package
Environments and secretsEnvironment variables and embedded credentials must be re-linked and moved out of Git-tracked filesOne-time, then recurring for rotationStore secrets in a manager or local vault and keep only variable names in collection files
Bulk import from a data dumpImporting the full zip Postman emails for all collections and environments is a feature of Bruno Ultimate, so the edition choice affects the import pathRecurring seat fee if chosenAsk Bruno for current Ultimate pricing and compare with the one-time per-collection export effort
Git push and branch operationsTeam collaboration through the app's Git UI, including push and merge conflict resolution, is a paid feature, while plain Git still works outside the appRecurring per user seat if chosenCount only users who need in-app push or merge tools and use command-line Git for the rest
CI pipelines calling NewmanPipelines that run Newman must move to the Bruno CLI (bru run) and their reporters must be checkedOne-time change, then recurring pipeline upkeepInventory every pipeline step that calls Newman before migrating collections
Staff time for review and trainingEngineers rewrite scripts, reconfigure environments and teach Git workflows, which is a recurring staff cost until the team is settledOne-time, with ongoing support loadAssign one owner per collection set and agree a Git branching convention early
Current pricingBruno publishes per-user monthly rates on its pricing page, and those rates can changeRecurringAsk Bruno for a written quote covering the exact seat count and billing period

What usually goes wrong and how to prevent it

Most failed Postman to Bruno moves do not fail on the import itself. They fail on what the import carries across: credentials, script behavior, packages, and the timing of the cutover. Each card below names one of these risks and the check that catches it before users rely on the new collections.

Secrets copied into Git

Postman collections and environments often hold live API keys, bearer tokens and passwords in variables. When these files move into a Git folder, a single commit can publish them to everyone with repository access. Before the first commit, search exported JSON and Bruno environment files for tokens and move them into a secret store or a local, git-ignored environment file. Use a `.gitignore` rule for environment secrets and confirm the rule works with a test commit.

Scripts that change behavior silently

Bruno translates common Postman APIs such as pm.test, pm.environment and pm.response during import, but a translated script can still behave differently from the original. An assertion may pass because a variable scope changed, or a pre-request value may resolve in a different order. Run each migrated collection against a known test environment and compare the results with the Postman run history for the same requests. Treat any difference in status codes or assertion counts as a defect until it is explained.

Unsupported packages found late

During import Bruno scans scripts for require() calls and marks Postman-specific packages such as postman-collection, postman-runtime, newman and @postman/* as not supported. Teams often discover these only when a scheduled run fails. Export the list of require() calls from every collection before cutover, and rewrite each script that depends on a flagged package to use plain JavaScript or a package your team can install and maintain.

Assuming Git push works on the free edition

Bruno's Open Source edition covers clone, initialize, diffs, pull and commit in its Git UI, while push, branch operations, remote connections and merge conflict resolution are paid features. Git itself still works from a terminal on any edition, so the workflow is not blocked, but the team's documented process must match what each person can do in the app. Confirm the edition each reader uses, write the push and branch steps as terminal commands where needed, and check the current Bruno pricing page before budgeting seats.

Two-day export window and bulk limits

Postman's account-wide data dump is requested by a team admin and is available for a limited download window, so a missed email or an expired link can stall the project. Bulk import of that dump into Bruno is included only in the Ultimate edition. Plan the export early, store the zip in controlled storage, and if bulk import is not in budget, export each collection as Collection v2 or v2.1 JSON and import those one by one.

Drift during parallel runs

While teams keep using Postman during the transition, edits made in Postman will not appear in the Git copy, and edits made in Git will not appear in Postman. Within a few weeks the two versions can differ in requests, variables and tests. Name one source of truth for each collection and a cutover date per collection, freeze edits in the retired source once it is migrated, and compare request counts and variable names before the freeze takes effect.

How the move differs by team size and starting point

A single engineer moving personal or project collections usually has the simplest path. Bruno keeps each collection as a folder on the local disk, so the work is mostly exporting, importing and checking requests. There is no shared workspace to recreate, and the engineer decides the folder layout alone. Because the Postman Free plan now supports one user, many individuals will hit this case first.

  • Folder layout: Choose one folder per collection, named after the API, and keep environment files beside the collection rather than in a separate tree.
  • Git hosting: A private repository on any Git host is enough. The Open Source edition covers clone, initialize, diffs, pull and commit, while Git itself works from the command line on any edition.
  • Review ownership: The engineer owns review. A self-review checklist covering script rewrites and removed secrets is the main control.
  • Import order: Export each collection as Collection v2 or v2.1 JSON and import them one at a time so unsupported packages are easy to trace.
  • Secrets: Keep tokens out of committed environment files and check the diff before each commit.

Before you start, confirm which Bruno edition you need for any Git push or branch operation you plan to do inside the app.

Questions teams ask before moving from Postman to Bruno

How much effort does moving from Postman to Bruno take?

The effort scales with the number of collections, the number of environments and how much of your test logic depends on Postman-specific scripts. Bruno imports each Postman collection exported as Collection v2 or v2.1 JSON through its Import Collections menu, and it translates common script APIs such as pm.test, pm.environment, pm.globals, pm.collectionVariables and pm.response during import. The work that remains is reviewing the imported requests, checking variables and rewriting any scripts that use Postman-specific packages. Ask for a count of collections and of scripts that call require() before you estimate the work internally.

What sets the timeline for a Postman to Bruno move?

The timeline depends on how many collections need to move, how many scripts need rewriting and how many people must review the results before the team stops using Postman. Collections that are simple request lists usually import with little change, while collections with custom npm packages need more time. Bruno flags Postman-specific packages such as postman-collection, postman-runtime, newman and @postman/* as not supported during import, so you can see that rework early. Plan a parallel period in which both tools run, and confirm the exact steps with Bruno's Migrating from Postman guide before you set dates.

What does the migration need from our team?

The migration needs someone who can export collections from Postman, someone who can review imported requests and environments, and an engineer who can rewrite scripts that depend on Postman-specific packages. Your team also needs to decide where the collection folders will live in Git and who maintains secrets outside the collection files. Bruno keeps collections as files in a local folder, so a repository owner and a review process for pull requests become part of the routine. Confirm the roles with your own engineers before the first export.

Can our own team migrate Postman collections to Bruno without outside help?

Yes, a small team with API experience can export and import simple collections on its own, because Bruno's import path is documented and the desktop app is available for macOS, Windows and Linux. Outside help usually becomes useful when collections are large, scripts depend on Postman packages, or the team needs a Git layout, CI runs with the bru CLI and documented controls for an audit. DeployOpen plans and implements these migrations under a written, fixed scope when a team wants that support. Ask for the scope in writing before any work starts.

Does bulk import from Postman require a paid Bruno edition?

Yes. Bruno can import one Postman collection at a time from a Collection v2 or v2.1 JSON export on the Open Source edition, but importing a Postman data dump of all collections and environments from the zip file that Postman emails is included only in Bruno Ultimate Edition. Bruno's pricing page lists Open Source at $0, Pro at $6 per user per month and Ultimate at $11 per user per month, both billed annually. Confirm the current edition terms with Bruno before you buy seats, because a per-collection export may be enough for a small library.

How does Git replace Postman's cloud sharing?

Git replaces Postman's cloud sharing by storing each Bruno collection as files in a folder that the team commits and reviews like source code. Bruno's README states that it is offline-only, that there are no plans to add cloud sync, and that teams can collaborate with Git or any other version control. Pull, commit and diffs are available on the Open Source edition, while push, branch operations, remote connections and merge conflict resolution in the app's Git UI are paid features. Git itself still works outside the app on any edition, so teams can push from the command line without buying a seat.

Should we keep secrets in the Bruno collection files?

No, keep API keys, tokens and passwords out of the collection folders that Git tracks. Store them in environment files or a secrets manager that stays outside the repository, and check the access rules before you share the repository. Bruno's secret manager integrations for HashiCorp Vault, AWS, Azure and Google Cloud are a separate topic, so confirm with Bruno which integration fits your environment and which edition includes it. Review the imported Postman environments before the first commit, because Postman exports can contain credentials that were saved in plain values.

How DeployOpen scopes and runs a Postman to Bruno migration

DeployOpen is a Chainscore Labs company that plans, implements, integrates and supports self-hosted open-source platforms inside the client's own infrastructure. For a Postman to Bruno move, that means the work happens in your environment, on the devices and Git repositories your teams already control, and the scope is set before anyone exports a collection. The first decision is which collections, environments and scripts are in scope, which teams own them, and whether Bruno's paid Git and import features are needed for the team's workflow. A written scope turns those choices into named deliverables instead of an open-ended project.

Engagements are fixed-scope. Before work starts, the scope, deliverables and timelines are agreed in writing, so the client knows exactly what is exported, which Postman scripts are translated, which require() packages are rewritten, and where the resulting collection folders are committed. DeployOpen does not publish a price list, so a quote follows from that written scope. Ask for the quote to separate one-time work (export, import, script rewrites, Git layout, documentation, and handover to staff) from any recurring items, and confirm whether a data dump import requires Bruno Ultimate Edition, which is a licensing cost on the client side rather than a DeployOpen fee.

Ongoing support, upgrades and continuous testing are available as a retainer, which suits teams that will keep adding collections or need help when Bruno releases a new version. Confirm with DeployOpen what the retainer covers, how changes to the scope are priced, and who on your side approves them. DeployOpen prepares systems, controls and documentation to support your compliance work, but it does not issue audit reports or certifications, so any assurance about how API credentials are handled should come from an independent auditor or certification body.

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.