Vibecode Postman
track this build5 phases, 10 steps, beginner friendly0%A personal request runner with saved collections and environments is a weekend, and open-source clients like Bruno already are that. What Postman sells at $19 a seat is the team workspace, the cloud sync and governance, which a solo builder does not need and a team cannot vibecode in a weekend.
You are building a lean indie version of Postman.
Create the following project files first, then implement the application by following them. Keep the files updated as decisions change. Do not collapse this into a single README or prompt.
===== README.md =====
# Postman · indie build
A file-based API client for one developer: requests as YAML in git, environments with secrets from the shell, a runner with assertions that exits non-zero for CI, chaining a token from one call into the next, history with diffs, and an importer for Postman collections. Bruno is the open-source answer; this is the 500-line version you own.
Estimated effort: **weekend**. Work `BUILD_PLAN.md` top to bottom · every phase ends in a check that has to pass before the next one starts.
## Stack
| Part | Choice | Why |
| --- | --- | --- |
| Runtime | Node 22, a CLI | no GUI, no cloud, no sync problem |
| Storage | YAML files in git plus a SQLite history | diffs and history for free |
## Before you start
Have every one of these ready. The plan assumes them from step one.
- [ ] **Node.js 22 or newer** · free
- Why: Everything in this build runs on it: the server, the scripts, the tests.
- Get it: Download the LTS installer from nodejs.org, or install with your package manager (brew install node, or nvm install 22). Restart the terminal afterwards.
- Verify: node --version prints v22 or higher
- [ ] **A terminal and a code editor** · free
- Why: Every step below is a command you type or a file you edit.
- Get it: VS Code (code.visualstudio.com), Cursor or Zed. Open a folder for the project and use the editor's built-in terminal.
- Verify: You can open a folder and run a command in its terminal
- [ ] **Git** · free
- Why: History for your code, and the way most hosts deploy.
- Get it: Install from git-scm.com or with your package manager, then run git init in the project folder once it exists.
- Verify: git --version prints a version
- [ ] **Try Bruno first** · free
- Why: If it fits, use it and stop; it is free and file-based. This build is for wanting a version you can read in an afternoon.
- Get it: usebruno.com, open your collection folder.
- [ ] **A Postman collection export and an API to hit** · free
- Why: Phase 5 imports it; every phase needs a real API to test against.
- Get it: Postman > Collection > Export (v2.1). Any public API or your own local server for tests.
- [ ] **Where secrets live: the shell, never files** · free
- Why: Requests reference {{env.NAME}}; values come from environment variables.
- Get it: Export them in your shell profile or a .env you never commit.
## Quick start
```sh
mkdir api-cli && cd api-cli && git init && npm init -y && npm pkg set type=module && npm install yaml@2
mkdir -p requests environments && cp .env.example .env
```
Then copy `.env.example` to `.env` and fill in the values it documents.
## Honest limits
This build deliberately does not replace:
- Team sync, mock servers, monitors, the visual editor: the seat price.
- team workspaces and cloud sync
- the mock server and monitoring products
- the visual editor
- API governance and the public API network
If one of those is essential to you, that is the reason to keep paying for Postman, and the README should say so rather than pretend.
===== BRIEF.md =====
# Build brief · Postman
The one-shot brief this plan expands. `BUILD_PLAN.md` (or `MILESTONES.md`) is the same sequence broken into steps and checks; where the two disagree, the plan wins.
Build me a file-based API client to replace Postman for one developer. Build it in phases, in the order below. Do not write the whole thing in one pass. Finish a phase, run its "Done when" check, fix what fails, and only then start the next phase. Read Bruno first; if it fits, use it and stop. This prompt is for a 500-line version you own.
### Stack (fixed, do not substitute)
- Node 22, a CLI. Requests are YAML files in a folder committed to git. No GUI, no cloud.
### Data model (create this before Phase 1)
- requests/<name>.yaml: method, url, headers, query, body, auth (bearer | basic | none), asserts (status, jsonpath equals)
- environments/<name>.yaml: key-value pairs referenced as {name} in requests
- history.sqlite: one row per run with request name, environment, status, latency, response size
### Phase 1 · Run one request
Build: api run <file> --env <name> substitutes variables, sends with fetch, prints status, headers, pretty JSON and latency. Secrets come from environment variables referenced as {env.NAME}, never from files.
Done when: a GET and a JSON POST print correctly, a missing variable fails with its name, and a secret never appears in a committed file.
Do not build yet: assertions, history, collections.
### Phase 2 · Assertions
Build: asserts on status and on JSON paths; non-zero exit on failure so it works in CI.
Done when: a wrong status exits 1 with a readable diff and a passing request exits 0.
### Phase 3 · Collections and chaining
Build: api run <folder> runs every request in order; a request can capture a JSON path from a response into a variable for later requests.
Done when: a login request feeds its token to the next request and the folder run reports pass counts.
### Phase 4 · History and diff
Build: every run stored in SQLite; api history <name> lists runs; api diff compares the last two responses.
Done when: history shows latency trends and diff highlights a changed field.
### Phase 5 · Import
Build: import a Postman collection JSON export into the YAML layout, including environments.
Done when: an exported collection runs unchanged after import.
### Out of scope (and why)
- Team sync, mock servers, monitors, the visual editor. Postman's seat price is the team; a folder in git is the team for one.
### README must contain
- The secret-handling rule: values in files are never secrets.
- The Postman import path.
===== AGENTS.md =====
# Agent instructions · Postman indie build
- Read `README.md` and `BUILD_PLAN.md` before writing code. The stack is fixed: Node 22, a CLI, YAML files in git plus a SQLite history. Do not substitute.
- Work one phase at a time, in order. Do not start a phase until every "Done when" item of the previous one passes.
- Prefer the fewest moving parts that satisfy the step. No frameworks, services or dependencies the plan does not name.
- Secrets live in `.env`, never in source or logs. Keep `.env.example` current when a variable is introduced.
- Do not invent cryptography, security guarantees, APIs or compliance claims.
- Add a focused test for every destructive, security-sensitive or data-loss path the plan names.
- Run the project checks before declaring a phase complete, and record any deliberate shortcut in the README under "Tradeoffs".
===== BUILD_PLAN.md =====
# Build plan · Postman
A file-based API client for one developer: requests as YAML in git, environments with secrets from the shell, a runner with assertions that exits non-zero for CI, chaining a token from one call into the next, history with diffs, and an importer for Postman collections. Bruno is the open-source answer; this is the 500-line version you own.
Phases are in dependency order. Each ends in a "Done when" list; treat an unticked item as a blocker, not a note.
## Phase 1 · Run one request
YAML in, pretty response out, secrets only from the shell.
### Steps
1. Create the CLI project and the request and environment file formats
requests/<name>.yaml: method, url, headers, query, body, auth, asserts. environments/<name>.yaml: key-value pairs referenced as {{name}}.
```sh
mkdir api-cli && cd api-cli && git init && npm init -y && npm pkg set type=module && npm install yaml@2
mkdir -p requests environments && cp .env.example .env
```
2. Implement api run <file> --env <name> with variable substitution and {{env.NAME}} from process.env
### Done when
- [ ] A GET and a JSON POST print status, headers, pretty JSON and latency
- [ ] A missing variable fails naming itself
- [ ] No secret can be committed
## Phase 2 · Assertions
Status and JSON-path asserts with a non-zero exit.
### Steps
1. Implement asserts on status and JSON paths
2. Exit 1 with a readable diff on failure
### Done when
- [ ] A wrong status exits 1 with a diff
- [ ] A passing request exits 0
## Phase 3 · Collections and chaining
Run a folder in order; capture values between requests.
### Steps
1. api run <folder> in filename order with pass counts
2. capture: a JSON path into a variable for later requests
### Done when
- [ ] A login feeds its token to the next request
- [ ] The folder run reports pass counts
## Phase 4 · History and diff
Every run recorded; diff the last two responses.
### Steps
1. Record runs in SQLite: request, environment, status, latency, size, body hash
2. api history <name> and api diff <name>
### Done when
- [ ] History shows latency trends
- [ ] Diff highlights a changed field
## Phase 5 · Import
Postman collections become YAML.
### Steps
1. Parse Postman v2.1 JSON into requests and environments
2. Run an imported collection unchanged
### Done when
- [ ] An exported collection runs after import
## Not in this build
- Team sync, mock servers, monitors, the visual editor: the seat price.
## After v1, if you want it
- A local web UI over the same files
- OpenAPI import
===== .env.example =====
# Copy to .env and fill in. Never commit .env; this file documents it.
# Optional. Where runs are recorded.
API_HISTORY_DB=~/.api-cli/history.db
# Optional · secret. An example secret a request references as {{env.API_TOKEN}}.
API_TOKEN=...
You are building a lean indie version of Postman.
Create the following project files first, then implement the application by following them. Keep the files updated as decisions change. Do not collapse this into a single README or prompt.
===== README.md =====
# Postman · indie build
A file-based API client for one developer: requests as YAML in git, environments with secrets from the shell, a runner with assertions that exits non-zero for CI, chaining a token from one call into the next, history with diffs, and an importer for Postman collections. Bruno is the open-source answer; this is the 500-line version you own.
Estimated effort: **weekend**. Work `BUILD_PLAN.md` top to bottom · every phase ends in a check that has to pass before the next one starts.
## Stack
| Part | Choice | Why |
| --- | --- | --- |
| Runtime | Node 22, a CLI | no GUI, no cloud, no sync problem |
| Storage | YAML files in git plus a SQLite history | diffs and history for free |
## Before you start
Have every one of these ready. The plan assumes them from step one.
- [ ] **Node.js 22 or newer** · free
- Why: Everything in this build runs on it: the server, the scripts, the tests.
- Get it: Download the LTS installer from nodejs.org, or install with your package manager (brew install node, or nvm install 22). Restart the terminal afterwards.
- Verify: node --version prints v22 or higher
- [ ] **A terminal and a code editor** · free
- Why: Every step below is a command you type or a file you edit.
- Get it: VS Code (code.visualstudio.com), Cursor or Zed. Open a folder for the project and use the editor's built-in terminal.
- Verify: You can open a folder and run a command in its terminal
- [ ] **Git** · free
- Why: History for your code, and the way most hosts deploy.
- Get it: Install from git-scm.com or with your package manager, then run git init in the project folder once it exists.
- Verify: git --version prints a version
- [ ] **Try Bruno first** · free
- Why: If it fits, use it and stop; it is free and file-based. This build is for wanting a version you can read in an afternoon.
- Get it: usebruno.com, open your collection folder.
- [ ] **A Postman collection export and an API to hit** · free
- Why: Phase 5 imports it; every phase needs a real API to test against.
- Get it: Postman > Collection > Export (v2.1). Any public API or your own local server for tests.
- [ ] **Where secrets live: the shell, never files** · free
- Why: Requests reference {{env.NAME}}; values come from environment variables.
- Get it: Export them in your shell profile or a .env you never commit.
## Quick start
```sh
mkdir api-cli && cd api-cli && git init && npm init -y && npm pkg set type=module && npm install yaml@2
mkdir -p requests environments && cp .env.example .env
```
Then copy `.env.example` to `.env` and fill in the values it documents.
## Honest limits
This build deliberately does not replace:
- Team sync, mock servers, monitors, the visual editor: the seat price.
- team workspaces and cloud sync
- the mock server and monitoring products
- the visual editor
- API governance and the public API network
If one of those is essential to you, that is the reason to keep paying for Postman, and the README should say so rather than pretend.
===== BRIEF.md =====
# Build brief · Postman
The one-shot brief this plan expands. `BUILD_PLAN.md` (or `MILESTONES.md`) is the same sequence broken into steps and checks; where the two disagree, the plan wins.
Build me a file-based API client to replace Postman for one developer. Build it in phases, in the order below. Do not write the whole thing in one pass. Finish a phase, run its "Done when" check, fix what fails, and only then start the next phase. Read Bruno first; if it fits, use it and stop. This prompt is for a 500-line version you own.
### Stack (fixed, do not substitute)
- Node 22, a CLI. Requests are YAML files in a folder committed to git. No GUI, no cloud.
### Data model (create this before Phase 1)
- requests/<name>.yaml: method, url, headers, query, body, auth (bearer | basic | none), asserts (status, jsonpath equals)
- environments/<name>.yaml: key-value pairs referenced as {name} in requests
- history.sqlite: one row per run with request name, environment, status, latency, response size
### Phase 1 · Run one request
Build: api run <file> --env <name> substitutes variables, sends with fetch, prints status, headers, pretty JSON and latency. Secrets come from environment variables referenced as {env.NAME}, never from files.
Done when: a GET and a JSON POST print correctly, a missing variable fails with its name, and a secret never appears in a committed file.
Do not build yet: assertions, history, collections.
### Phase 2 · Assertions
Build: asserts on status and on JSON paths; non-zero exit on failure so it works in CI.
Done when: a wrong status exits 1 with a readable diff and a passing request exits 0.
### Phase 3 · Collections and chaining
Build: api run <folder> runs every request in order; a request can capture a JSON path from a response into a variable for later requests.
Done when: a login request feeds its token to the next request and the folder run reports pass counts.
### Phase 4 · History and diff
Build: every run stored in SQLite; api history <name> lists runs; api diff compares the last two responses.
Done when: history shows latency trends and diff highlights a changed field.
### Phase 5 · Import
Build: import a Postman collection JSON export into the YAML layout, including environments.
Done when: an exported collection runs unchanged after import.
### Out of scope (and why)
- Team sync, mock servers, monitors, the visual editor. Postman's seat price is the team; a folder in git is the team for one.
### README must contain
- The secret-handling rule: values in files are never secrets.
- The Postman import path.
===== AGENTS.md =====
# Agent instructions · Postman indie build
- Read `README.md` and `BUILD_PLAN.md` before writing code. The stack is fixed: Node 22, a CLI, YAML files in git plus a SQLite history. Do not substitute.
- Work one phase at a time, in order. Do not start a phase until every "Done when" item of the previous one passes.
- Prefer the fewest moving parts that satisfy the step. No frameworks, services or dependencies the plan does not name.
- Secrets live in `.env`, never in source or logs. Keep `.env.example` current when a variable is introduced.
- Do not invent cryptography, security guarantees, APIs or compliance claims.
- Add a focused test for every destructive, security-sensitive or data-loss path the plan names.
- Run the project checks before declaring a phase complete, and record any deliberate shortcut in the README under "Tradeoffs".
===== BUILD_PLAN.md =====
# Build plan · Postman
A file-based API client for one developer: requests as YAML in git, environments with secrets from the shell, a runner with assertions that exits non-zero for CI, chaining a token from one call into the next, history with diffs, and an importer for Postman collections. Bruno is the open-source answer; this is the 500-line version you own.
Phases are in dependency order. Each ends in a "Done when" list; treat an unticked item as a blocker, not a note.
## Phase 1 · Run one request
YAML in, pretty response out, secrets only from the shell.
### Steps
1. Create the CLI project and the request and environment file formats
requests/<name>.yaml: method, url, headers, query, body, auth, asserts. environments/<name>.yaml: key-value pairs referenced as {{name}}.
```sh
mkdir api-cli && cd api-cli && git init && npm init -y && npm pkg set type=module && npm install yaml@2
mkdir -p requests environments && cp .env.example .env
```
2. Implement api run <file> --env <name> with variable substitution and {{env.NAME}} from process.env
### Done when
- [ ] A GET and a JSON POST print status, headers, pretty JSON and latency
- [ ] A missing variable fails naming itself
- [ ] No secret can be committed
## Phase 2 · Assertions
Status and JSON-path asserts with a non-zero exit.
### Steps
1. Implement asserts on status and JSON paths
2. Exit 1 with a readable diff on failure
### Done when
- [ ] A wrong status exits 1 with a diff
- [ ] A passing request exits 0
## Phase 3 · Collections and chaining
Run a folder in order; capture values between requests.
### Steps
1. api run <folder> in filename order with pass counts
2. capture: a JSON path into a variable for later requests
### Done when
- [ ] A login feeds its token to the next request
- [ ] The folder run reports pass counts
## Phase 4 · History and diff
Every run recorded; diff the last two responses.
### Steps
1. Record runs in SQLite: request, environment, status, latency, size, body hash
2. api history <name> and api diff <name>
### Done when
- [ ] History shows latency trends
- [ ] Diff highlights a changed field
## Phase 5 · Import
Postman collections become YAML.
### Steps
1. Parse Postman v2.1 JSON into requests and environments
2. Run an imported collection unchanged
### Done when
- [ ] An exported collection runs after import
## Not in this build
- Team sync, mock servers, monitors, the visual editor: the seat price.
## After v1, if you want it
- A local web UI over the same files
- OpenAPI import
===== .env.example =====
# Copy to .env and fill in. Never commit .env; this file documents it.
# Optional. Where runs are recorded.
API_HISTORY_DB=~/.api-cli/history.db
# Optional · secret. An example secret a request references as {{env.API_TOKEN}}.
API_TOKEN=...
You are building a production product version of Postman.
Create the following project files first, then implement the application by following them. Keep the files updated as decisions change. Do not collapse this into a single README or prompt.
===== PRODUCT.md =====
# Postman · product brief
## Problem
A personal request runner with saved collections and environments is a weekend, and open-source clients like Bruno already are that. What Postman sells at $19 a seat is the team workspace, the cloud sync and governance, which a solo builder does not need and a team cannot vibecode in a weekend.
## Product outcome
API tests that live with the code, run in CI, and never leak a secret through a synced workspace.
## Target user
A builder who needs a maintainable product foundation, not a one-off demo.
## Required capabilities
- nothing beyond Node or Go
## Explicit non-goals for v1
- Team sync, mock servers, monitors, the visual editor: the seat price.
- team workspaces and cloud sync
- the mock server and monitoring products
- the visual editor
- API governance and the public API network
## Success criteria
- Secrets verified absent from every file
- CI run passes on a real collection
===== BRIEF.md =====
# Build brief · Postman
The one-shot brief this plan expands. `BUILD_PLAN.md` (or `MILESTONES.md`) is the same sequence broken into steps and checks; where the two disagree, the plan wins.
Build me a file-based API client to replace Postman for one developer. Build it in phases, in the order below. Do not write the whole thing in one pass. Finish a phase, run its "Done when" check, fix what fails, and only then start the next phase. Read Bruno first; if it fits, use it and stop. This prompt is for a 500-line version you own.
### Stack (fixed, do not substitute)
- Node 22, a CLI. Requests are YAML files in a folder committed to git. No GUI, no cloud.
### Data model (create this before Phase 1)
- requests/<name>.yaml: method, url, headers, query, body, auth (bearer | basic | none), asserts (status, jsonpath equals)
- environments/<name>.yaml: key-value pairs referenced as {name} in requests
- history.sqlite: one row per run with request name, environment, status, latency, response size
### Phase 1 · Run one request
Build: api run <file> --env <name> substitutes variables, sends with fetch, prints status, headers, pretty JSON and latency. Secrets come from environment variables referenced as {env.NAME}, never from files.
Done when: a GET and a JSON POST print correctly, a missing variable fails with its name, and a secret never appears in a committed file.
Do not build yet: assertions, history, collections.
### Phase 2 · Assertions
Build: asserts on status and on JSON paths; non-zero exit on failure so it works in CI.
Done when: a wrong status exits 1 with a readable diff and a passing request exits 0.
### Phase 3 · Collections and chaining
Build: api run <folder> runs every request in order; a request can capture a JSON path from a response into a variable for later requests.
Done when: a login request feeds its token to the next request and the folder run reports pass counts.
### Phase 4 · History and diff
Build: every run stored in SQLite; api history <name> lists runs; api diff compares the last two responses.
Done when: history shows latency trends and diff highlights a changed field.
### Phase 5 · Import
Build: import a Postman collection JSON export into the YAML layout, including environments.
Done when: an exported collection runs unchanged after import.
### Out of scope (and why)
- Team sync, mock servers, monitors, the visual editor. Postman's seat price is the team; a folder in git is the team for one.
### README must contain
- The secret-handling rule: values in files are never secrets.
- The Postman import path.
===== ARCHITECTURE.md =====
# Architecture · Postman
## Stack
| Part | Choice | Why |
| --- | --- | --- |
| Runtime | Node 22, a CLI | no GUI, no cloud, no sync problem |
| Storage | YAML files in git plus a SQLite history | diffs and history for free |
## Modules
Each module has one owner concern and a documented way to replace it.
| Module | Owns | How to replace it |
| --- | --- | --- |
| Runner | substitution, fetch, output | The core |
| Asserts | status and JSON-path checks | Add schema validation |
| History | SQLite runs and diff | Optional |
| Import | Postman v2.1 | Add Insomnia v4 |
## Configuration
Every runtime setting is an environment variable documented in `.env.example`, validated at startup, with a safe local default wherever one exists.
- `API_HISTORY_DB` · optional · Where runs are recorded.
- `API_TOKEN` · optional, secret · An example secret a request references as {{env.API_TOKEN}}.
## Production baseline
- Security: least privilege, input validation at every boundary, secret redaction in logs, rate limits on abuse-prone paths, no invented security primitives.
- Data: explicit schema and migrations, transactional writes where integrity matters, backup and restore procedures that have been exercised.
- Integrations: adapters around third-party providers, idempotent webhook or job processing, bounded retries, timeouts.
- Observability: structured logs with request or operation ids, an error-tracking hook, and health and readiness checks where a server exists.
- Quality: unit tests for domain rules, integration tests at module boundaries, one end-to-end test of the critical path.
## Decision records
For each dependency in the stack table, keep a short note: why it was chosen, its failure mode, and how it is replaced. Do not add infrastructure until a requirement in `PRODUCT.md` justifies it.
===== AGENTS.md =====
# Agent instructions · Postman product build
- Read `PRODUCT.md` and `ARCHITECTURE.md` before changing code. The stack is fixed: Node 22, a CLI, YAML files in git plus a SQLite history.
- Implement milestone by milestone from `MILESTONES.md`; keep each change reviewable and leave the application runnable at every commit.
- Treat authentication, payments, encryption, imports, webhooks and destructive actions as high-risk boundaries when present.
- Never invent cryptography or silently weaken a requirement to make a check pass.
- Put every external service behind an interface with a deterministic fake for tests.
- Add migrations and rollback or recovery notes for every persistent data change.
- Log useful operational context without credentials, tokens, passwords or personal data.
- Update documentation and run every check before completing a milestone.
===== MILESTONES.md =====
# Delivery milestones · Postman
Estimated effort: **weekend** for the indie phases; the production-only milestones add the trust and operability layer.
## M1 · Run one request
YAML in, pretty response out, secrets only from the shell.
### Steps
1. Create the CLI project and the request and environment file formats
requests/<name>.yaml: method, url, headers, query, body, auth, asserts. environments/<name>.yaml: key-value pairs referenced as {{name}}.
```sh
mkdir api-cli && cd api-cli && git init && npm init -y && npm pkg set type=module && npm install yaml@2
mkdir -p requests environments && cp .env.example .env
```
2. Implement api run <file> --env <name> with variable substitution and {{env.NAME}} from process.env
### Done when
- [ ] A GET and a JSON POST print status, headers, pretty JSON and latency
- [ ] A missing variable fails naming itself
- [ ] No secret can be committed
## M2 · Assertions
Status and JSON-path asserts with a non-zero exit.
### Steps
1. Implement asserts on status and JSON paths
2. Exit 1 with a readable diff on failure
### Done when
- [ ] A wrong status exits 1 with a diff
- [ ] A passing request exits 0
## M3 · Collections and chaining
Run a folder in order; capture values between requests.
### Steps
1. api run <folder> in filename order with pass counts
2. capture: a JSON path into a variable for later requests
### Done when
- [ ] A login feeds its token to the next request
- [ ] The folder run reports pass counts
## M4 · History and diff
Every run recorded; diff the last two responses.
### Steps
1. Record runs in SQLite: request, environment, status, latency, size, body hash
2. api history <name> and api diff <name>
### Done when
- [ ] History shows latency trends
- [ ] Diff highlights a changed field
## M5 · Import
Postman collections become YAML.
### Steps
1. Parse Postman v2.1 JSON into requests and environments
2. Run an imported collection unchanged
### Done when
- [ ] An exported collection runs after import
## M6 · Share with a team (production only)
Only if others use it: publish the CLI and enforce it in CI.
### Steps
1. Publish to a private npm registry or as a git dependency
2. Run the collection in CI on every deploy with secrets from the CI store
### Done when
- [ ] A teammate installs and runs the collection
- [ ] CI fails when an assertion fails
===== OPERATIONS.md =====
# Operations · Postman
## Backup
The repo; history is disposable.
## Restore
Clone.
Do a restore drill before the first real user, and write the date here when it passes.
## Monitoring
CI status.
## Incident checklist
A leaked secret is rotated at its source; files never held it.
1. Contain the issue without destroying evidence or user data.
2. Record the timeline and affected scope.
3. Rotate exposed secrets and revoke compromised sessions or credentials.
4. Restore from a verified backup when needed.
5. Document the root cause, the remediation and the regression test.
## Release gate
- [ ] Secrets verified absent from every file
- [ ] CI run passes on a real collection
## Launch constraint
Do not market omitted Postman capabilities as implemented. The non-goals in `PRODUCT.md` remain user-visible limitations until they are deliberately delivered.
===== .env.example =====
# Copy to .env and fill in. Never commit .env; this file documents it.
# Optional. Where runs are recorded.
API_HISTORY_DB=~/.api-cli/history.db
# Optional · secret. An example secret a request references as {{env.API_TOKEN}}.
API_TOKEN=...
# Postman · indie build
A file-based API client for one developer: requests as YAML in git, environments with secrets from the shell, a runner with assertions that exits non-zero for CI, chaining a token from one call into the next, history with diffs, and an importer for Postman collections. Bruno is the open-source answer; this is the 500-line version you own.
Estimated effort: **weekend**. Work `BUILD_PLAN.md` top to bottom · every phase ends in a check that has to pass before the next one starts.
## Stack
| Part | Choice | Why |
| --- | --- | --- |
| Runtime | Node 22, a CLI | no GUI, no cloud, no sync problem |
| Storage | YAML files in git plus a SQLite history | diffs and history for free |
## Before you start
Have every one of these ready. The plan assumes them from step one.
- [ ] **Node.js 22 or newer** · free
- Why: Everything in this build runs on it: the server, the scripts, the tests.
- Get it: Download the LTS installer from nodejs.org, or install with your package manager (brew install node, or nvm install 22). Restart the terminal afterwards.
- Verify: node --version prints v22 or higher
- [ ] **A terminal and a code editor** · free
- Why: Every step below is a command you type or a file you edit.
- Get it: VS Code (code.visualstudio.com), Cursor or Zed. Open a folder for the project and use the editor's built-in terminal.
- Verify: You can open a folder and run a command in its terminal
- [ ] **Git** · free
- Why: History for your code, and the way most hosts deploy.
- Get it: Install from git-scm.com or with your package manager, then run git init in the project folder once it exists.
- Verify: git --version prints a version
- [ ] **Try Bruno first** · free
- Why: If it fits, use it and stop; it is free and file-based. This build is for wanting a version you can read in an afternoon.
- Get it: usebruno.com, open your collection folder.
- [ ] **A Postman collection export and an API to hit** · free
- Why: Phase 5 imports it; every phase needs a real API to test against.
- Get it: Postman > Collection > Export (v2.1). Any public API or your own local server for tests.
- [ ] **Where secrets live: the shell, never files** · free
- Why: Requests reference {{env.NAME}}; values come from environment variables.
- Get it: Export them in your shell profile or a .env you never commit.
## Quick start
```sh
mkdir api-cli && cd api-cli && git init && npm init -y && npm pkg set type=module && npm install yaml@2
mkdir -p requests environments && cp .env.example .env
```
Then copy `.env.example` to `.env` and fill in the values it documents.
## Honest limits
This build deliberately does not replace:
- Team sync, mock servers, monitors, the visual editor: the seat price.
- team workspaces and cloud sync
- the mock server and monitoring products
- the visual editor
- API governance and the public API network
If one of those is essential to you, that is the reason to keep paying for Postman, and the README should say so rather than pretend.# Build brief · Postman
The one-shot brief this plan expands. `BUILD_PLAN.md` (or `MILESTONES.md`) is the same sequence broken into steps and checks; where the two disagree, the plan wins.
Build me a file-based API client to replace Postman for one developer. Build it in phases, in the order below. Do not write the whole thing in one pass. Finish a phase, run its "Done when" check, fix what fails, and only then start the next phase. Read Bruno first; if it fits, use it and stop. This prompt is for a 500-line version you own.
### Stack (fixed, do not substitute)
- Node 22, a CLI. Requests are YAML files in a folder committed to git. No GUI, no cloud.
### Data model (create this before Phase 1)
- requests/<name>.yaml: method, url, headers, query, body, auth (bearer | basic | none), asserts (status, jsonpath equals)
- environments/<name>.yaml: key-value pairs referenced as {name} in requests
- history.sqlite: one row per run with request name, environment, status, latency, response size
### Phase 1 · Run one request
Build: api run <file> --env <name> substitutes variables, sends with fetch, prints status, headers, pretty JSON and latency. Secrets come from environment variables referenced as {env.NAME}, never from files.
Done when: a GET and a JSON POST print correctly, a missing variable fails with its name, and a secret never appears in a committed file.
Do not build yet: assertions, history, collections.
### Phase 2 · Assertions
Build: asserts on status and on JSON paths; non-zero exit on failure so it works in CI.
Done when: a wrong status exits 1 with a readable diff and a passing request exits 0.
### Phase 3 · Collections and chaining
Build: api run <folder> runs every request in order; a request can capture a JSON path from a response into a variable for later requests.
Done when: a login request feeds its token to the next request and the folder run reports pass counts.
### Phase 4 · History and diff
Build: every run stored in SQLite; api history <name> lists runs; api diff compares the last two responses.
Done when: history shows latency trends and diff highlights a changed field.
### Phase 5 · Import
Build: import a Postman collection JSON export into the YAML layout, including environments.
Done when: an exported collection runs unchanged after import.
### Out of scope (and why)
- Team sync, mock servers, monitors, the visual editor. Postman's seat price is the team; a folder in git is the team for one.
### README must contain
- The secret-handling rule: values in files are never secrets.
- The Postman import path.# Agent instructions · Postman indie build - Read `README.md` and `BUILD_PLAN.md` before writing code. The stack is fixed: Node 22, a CLI, YAML files in git plus a SQLite history. Do not substitute. - Work one phase at a time, in order. Do not start a phase until every "Done when" item of the previous one passes. - Prefer the fewest moving parts that satisfy the step. No frameworks, services or dependencies the plan does not name. - Secrets live in `.env`, never in source or logs. Keep `.env.example` current when a variable is introduced. - Do not invent cryptography, security guarantees, APIs or compliance claims. - Add a focused test for every destructive, security-sensitive or data-loss path the plan names. - Run the project checks before declaring a phase complete, and record any deliberate shortcut in the README under "Tradeoffs".
# Build plan · Postman
A file-based API client for one developer: requests as YAML in git, environments with secrets from the shell, a runner with assertions that exits non-zero for CI, chaining a token from one call into the next, history with diffs, and an importer for Postman collections. Bruno is the open-source answer; this is the 500-line version you own.
Phases are in dependency order. Each ends in a "Done when" list; treat an unticked item as a blocker, not a note.
## Phase 1 · Run one request
YAML in, pretty response out, secrets only from the shell.
### Steps
1. Create the CLI project and the request and environment file formats
requests/<name>.yaml: method, url, headers, query, body, auth, asserts. environments/<name>.yaml: key-value pairs referenced as {{name}}.
```sh
mkdir api-cli && cd api-cli && git init && npm init -y && npm pkg set type=module && npm install yaml@2
mkdir -p requests environments && cp .env.example .env
```
2. Implement api run <file> --env <name> with variable substitution and {{env.NAME}} from process.env
### Done when
- [ ] A GET and a JSON POST print status, headers, pretty JSON and latency
- [ ] A missing variable fails naming itself
- [ ] No secret can be committed
## Phase 2 · Assertions
Status and JSON-path asserts with a non-zero exit.
### Steps
1. Implement asserts on status and JSON paths
2. Exit 1 with a readable diff on failure
### Done when
- [ ] A wrong status exits 1 with a diff
- [ ] A passing request exits 0
## Phase 3 · Collections and chaining
Run a folder in order; capture values between requests.
### Steps
1. api run <folder> in filename order with pass counts
2. capture: a JSON path into a variable for later requests
### Done when
- [ ] A login feeds its token to the next request
- [ ] The folder run reports pass counts
## Phase 4 · History and diff
Every run recorded; diff the last two responses.
### Steps
1. Record runs in SQLite: request, environment, status, latency, size, body hash
2. api history <name> and api diff <name>
### Done when
- [ ] History shows latency trends
- [ ] Diff highlights a changed field
## Phase 5 · Import
Postman collections become YAML.
### Steps
1. Parse Postman v2.1 JSON into requests and environments
2. Run an imported collection unchanged
### Done when
- [ ] An exported collection runs after import
## Not in this build
- Team sync, mock servers, monitors, the visual editor: the seat price.
## After v1, if you want it
- A local web UI over the same files
- OpenAPI import# Copy to .env and fill in. Never commit .env; this file documents it.
# Optional. Where runs are recorded.
API_HISTORY_DB=~/.api-cli/history.db
# Optional · secret. An example secret a request references as {{env.API_TOKEN}}.
API_TOKEN=...
# Postman · product brief ## Problem A personal request runner with saved collections and environments is a weekend, and open-source clients like Bruno already are that. What Postman sells at $19 a seat is the team workspace, the cloud sync and governance, which a solo builder does not need and a team cannot vibecode in a weekend. ## Product outcome API tests that live with the code, run in CI, and never leak a secret through a synced workspace. ## Target user A builder who needs a maintainable product foundation, not a one-off demo. ## Required capabilities - nothing beyond Node or Go ## Explicit non-goals for v1 - Team sync, mock servers, monitors, the visual editor: the seat price. - team workspaces and cloud sync - the mock server and monitoring products - the visual editor - API governance and the public API network ## Success criteria - Secrets verified absent from every file - CI run passes on a real collection
# Build brief · Postman
The one-shot brief this plan expands. `BUILD_PLAN.md` (or `MILESTONES.md`) is the same sequence broken into steps and checks; where the two disagree, the plan wins.
Build me a file-based API client to replace Postman for one developer. Build it in phases, in the order below. Do not write the whole thing in one pass. Finish a phase, run its "Done when" check, fix what fails, and only then start the next phase. Read Bruno first; if it fits, use it and stop. This prompt is for a 500-line version you own.
### Stack (fixed, do not substitute)
- Node 22, a CLI. Requests are YAML files in a folder committed to git. No GUI, no cloud.
### Data model (create this before Phase 1)
- requests/<name>.yaml: method, url, headers, query, body, auth (bearer | basic | none), asserts (status, jsonpath equals)
- environments/<name>.yaml: key-value pairs referenced as {name} in requests
- history.sqlite: one row per run with request name, environment, status, latency, response size
### Phase 1 · Run one request
Build: api run <file> --env <name> substitutes variables, sends with fetch, prints status, headers, pretty JSON and latency. Secrets come from environment variables referenced as {env.NAME}, never from files.
Done when: a GET and a JSON POST print correctly, a missing variable fails with its name, and a secret never appears in a committed file.
Do not build yet: assertions, history, collections.
### Phase 2 · Assertions
Build: asserts on status and on JSON paths; non-zero exit on failure so it works in CI.
Done when: a wrong status exits 1 with a readable diff and a passing request exits 0.
### Phase 3 · Collections and chaining
Build: api run <folder> runs every request in order; a request can capture a JSON path from a response into a variable for later requests.
Done when: a login request feeds its token to the next request and the folder run reports pass counts.
### Phase 4 · History and diff
Build: every run stored in SQLite; api history <name> lists runs; api diff compares the last two responses.
Done when: history shows latency trends and diff highlights a changed field.
### Phase 5 · Import
Build: import a Postman collection JSON export into the YAML layout, including environments.
Done when: an exported collection runs unchanged after import.
### Out of scope (and why)
- Team sync, mock servers, monitors, the visual editor. Postman's seat price is the team; a folder in git is the team for one.
### README must contain
- The secret-handling rule: values in files are never secrets.
- The Postman import path.# Architecture · Postman
## Stack
| Part | Choice | Why |
| --- | --- | --- |
| Runtime | Node 22, a CLI | no GUI, no cloud, no sync problem |
| Storage | YAML files in git plus a SQLite history | diffs and history for free |
## Modules
Each module has one owner concern and a documented way to replace it.
| Module | Owns | How to replace it |
| --- | --- | --- |
| Runner | substitution, fetch, output | The core |
| Asserts | status and JSON-path checks | Add schema validation |
| History | SQLite runs and diff | Optional |
| Import | Postman v2.1 | Add Insomnia v4 |
## Configuration
Every runtime setting is an environment variable documented in `.env.example`, validated at startup, with a safe local default wherever one exists.
- `API_HISTORY_DB` · optional · Where runs are recorded.
- `API_TOKEN` · optional, secret · An example secret a request references as {{env.API_TOKEN}}.
## Production baseline
- Security: least privilege, input validation at every boundary, secret redaction in logs, rate limits on abuse-prone paths, no invented security primitives.
- Data: explicit schema and migrations, transactional writes where integrity matters, backup and restore procedures that have been exercised.
- Integrations: adapters around third-party providers, idempotent webhook or job processing, bounded retries, timeouts.
- Observability: structured logs with request or operation ids, an error-tracking hook, and health and readiness checks where a server exists.
- Quality: unit tests for domain rules, integration tests at module boundaries, one end-to-end test of the critical path.
## Decision records
For each dependency in the stack table, keep a short note: why it was chosen, its failure mode, and how it is replaced. Do not add infrastructure until a requirement in `PRODUCT.md` justifies it.# Agent instructions · Postman product build - Read `PRODUCT.md` and `ARCHITECTURE.md` before changing code. The stack is fixed: Node 22, a CLI, YAML files in git plus a SQLite history. - Implement milestone by milestone from `MILESTONES.md`; keep each change reviewable and leave the application runnable at every commit. - Treat authentication, payments, encryption, imports, webhooks and destructive actions as high-risk boundaries when present. - Never invent cryptography or silently weaken a requirement to make a check pass. - Put every external service behind an interface with a deterministic fake for tests. - Add migrations and rollback or recovery notes for every persistent data change. - Log useful operational context without credentials, tokens, passwords or personal data. - Update documentation and run every check before completing a milestone.
# Delivery milestones · Postman
Estimated effort: **weekend** for the indie phases; the production-only milestones add the trust and operability layer.
## M1 · Run one request
YAML in, pretty response out, secrets only from the shell.
### Steps
1. Create the CLI project and the request and environment file formats
requests/<name>.yaml: method, url, headers, query, body, auth, asserts. environments/<name>.yaml: key-value pairs referenced as {{name}}.
```sh
mkdir api-cli && cd api-cli && git init && npm init -y && npm pkg set type=module && npm install yaml@2
mkdir -p requests environments && cp .env.example .env
```
2. Implement api run <file> --env <name> with variable substitution and {{env.NAME}} from process.env
### Done when
- [ ] A GET and a JSON POST print status, headers, pretty JSON and latency
- [ ] A missing variable fails naming itself
- [ ] No secret can be committed
## M2 · Assertions
Status and JSON-path asserts with a non-zero exit.
### Steps
1. Implement asserts on status and JSON paths
2. Exit 1 with a readable diff on failure
### Done when
- [ ] A wrong status exits 1 with a diff
- [ ] A passing request exits 0
## M3 · Collections and chaining
Run a folder in order; capture values between requests.
### Steps
1. api run <folder> in filename order with pass counts
2. capture: a JSON path into a variable for later requests
### Done when
- [ ] A login feeds its token to the next request
- [ ] The folder run reports pass counts
## M4 · History and diff
Every run recorded; diff the last two responses.
### Steps
1. Record runs in SQLite: request, environment, status, latency, size, body hash
2. api history <name> and api diff <name>
### Done when
- [ ] History shows latency trends
- [ ] Diff highlights a changed field
## M5 · Import
Postman collections become YAML.
### Steps
1. Parse Postman v2.1 JSON into requests and environments
2. Run an imported collection unchanged
### Done when
- [ ] An exported collection runs after import
## M6 · Share with a team (production only)
Only if others use it: publish the CLI and enforce it in CI.
### Steps
1. Publish to a private npm registry or as a git dependency
2. Run the collection in CI on every deploy with secrets from the CI store
### Done when
- [ ] A teammate installs and runs the collection
- [ ] CI fails when an assertion fails# Operations · Postman ## Backup The repo; history is disposable. ## Restore Clone. Do a restore drill before the first real user, and write the date here when it passes. ## Monitoring CI status. ## Incident checklist A leaked secret is rotated at its source; files never held it. 1. Contain the issue without destroying evidence or user data. 2. Record the timeline and affected scope. 3. Rotate exposed secrets and revoke compromised sessions or credentials. 4. Restore from a verified backup when needed. 5. Document the root cause, the remediation and the regression test. ## Release gate - [ ] Secrets verified absent from every file - [ ] CI run passes on a real collection ## Launch constraint Do not market omitted Postman capabilities as implemented. The non-goals in `PRODUCT.md` remain user-visible limitations until they are deliberately delivered.
# Copy to .env and fill in. Never commit .env; this file documents it.
# Optional. Where runs are recorded.
API_HISTORY_DB=~/.api-cli/history.db
# Optional · secret. An example secret a request references as {{env.API_TOKEN}}.
API_TOKEN=...
$ choose a build depth, inspect the files, then open the complete pack in your agent
Teams pay so the collection everyone runs is the same collection. Solo, the free tier or a file-based client covers it.
xteam workspaces and cloud sync
xthe mock server and monitoring products
xthe visual editor
xAPI governance and the public API network
Postman pricing
solo$9/mo · monthly, billed annually · $108/yr
free tierThe free plan includes the API client, unlimited collection runs and mock servers with limited monitoring and AI credits.
verified 2026-09-04 · source ↗
Is Postman free?
The free plan includes the API client, unlimited collection runs and mock servers with limited monitoring and AI credits. Paid is Solo at $9/mo (checked 2026-09-04).
Vibecode Postman
Kinda. The core of Postman is buildable in a weekend with the prompt on this page, but there are real gaps: team workspaces and cloud sync, the mock server and monitoring products. Read the honest list above before committing.
How much does Postman cost?
Postman costs about $9/month (Solo, checked 2026-09-04), which is $108 per year.
What do I lose by replacing Postman?
Honestly: team workspaces and cloud sync; the mock server and monitoring products; the visual editor; API governance and the public API network. If any of those are load-bearing for you, keep paying.
Is there an open-source alternative to Postman?
Yes: Bruno (open-source, git-friendly API client), Hoppscotch (open-source API development platform). Using prior art is also vibecoding; the prompt is for when you want it exactly your way.