buy-vs-build
Buy-vs-build mode. Forces agents to check standard library, native platform, already-installed dependencies, open source, commercial options
Open source Open in the app JSON README (API)
About
Buy-vs-build mode. Forces agents to check standard library, native platform, already-installed dependencies, open source, commercial options, then build in-house only when warranted.
Details
- Kind
- Plugins
- Topic
- Developer tools
- Publisher
- stdin
- Origin
- gemini
- Category
- ferramentas
- Version
- 0.4.0
- Stars
- 3
- Last push
- 2026-06-28T22:15:44Z
- Repository state
- ativo
- Language
- JavaScript
- License
- MIT
- Added
- 2026-08-30 14:13:39
- Updated
- 2026-08-30 14:13:39
- Origin id
stdin/buy-vs-build
README
# Buy vs Build
<p align="center">
<a href="https://xkcd.com/3233/">
<img src="https://imgs.xkcd.com/comics/make_it_myself.png" width="300"
alt="It's not as big a loss as it looks, because now I have leftover supplies, which will help me talk myself into doing this all over again with a new project!" />
</a>
<br />
<sub><a href="https://xkcd.com/3233/">xkcd 3233: “Make It Myself”</a> · <a href="https://www.explainxkcd.com/wiki/index.php/3233:_Make_It_Myself">explained</a> · CC BY-NC 2.5</sub>
</p>
[](https://github.com/stdin/buy-vs-build/actions/workflows/ci.yml)
[](LICENSE)
**Stop your coding agent from reinventing the invoice.**
Buy vs Build is an always-on ruleset for AI coding agents. Before the agent writes code, it has to ask:
> Can this be solved with a built-in, platform feature, installed dependency, open source library, or commercial product before we own it forever?
That one pause catches a lot of expensive mistakes: custom date pickers, homemade auth, duplicate validators, tiny libraries that bring a dependency tree with them, and "temporary" infrastructure that somehow becomes a team.
Buy vs Build does not worship dependencies. It does not worship in-house code. It makes the agent choose deliberately.
## The problems it solves
AI agents are fast — and that speed runs straight into ownership cost. Left alone, an agent will happily:
- **Reinvent what already exists** — a custom date picker instead of a native input, a helper instead of the standard library, OAuth by hand because the prompt said "simple login."
- **Pick the impressive tool over the right one** — WebSockets for a one-way feed, NoSQL "for scale" on relational data, a message queue for a nightly cron job.
- **Adopt dependencies it never vetted** — an unmaintained, single-maintainer, or vulnerable package pulled in for three lines of code (the [left-pad story](https://en.wikipedia.org/wiki/Npm_left-pad_incident), on repeat).
- **Leave no trace of why** — six months later nobody knows why a service was chosen, or when to revisit it.
Each one is a bill that arrives later: a migration, an incident, an audit finding, a dependency you can't remove. Buy vs Build adds the missing engineering reflex — **reuse first, pick the option that fits, vet what you adopt, and write the call down — build only when the constraints justify owning it.**
## What you get
| It stops the agent from… | …by |
| --- | --- |
| Reinventing built-ins, platform features, and existing dependencies | Walking a reuse ladder before writing new code |
| **Picking the flashy tool over the right one** | Matching the option to the requirement (SSE vs WebSockets, SQL vs NoSQL, cron vs queue) |
| **Adopting a dependency it never researched** | Checking health, maintainers (bus factor), known vulnerabilities, license, and footprint — for **any language** |
| Ignoring your team's real constraints | Reading a per-project `.buyvsbuild.json` (weight security, ban or prefer dependencies, mark what's core) |
| Losing the reasoning behind a choice | Recording decisions as durable ADRs |
| Slipping risky dependencies through review | A PR check that flags new dependencies (npm, PyPI, Go, Maven, Cargo, NuGet, RubyGems) added without a decision note — and posts their health, security, and license-compatibility signals. In `strict` mode, missing dependency notes fail CI. |
| Carrying ownership risk in dependencies you already have | An audit (`npm run audit:deps`) that ranks every dependency by ownership risk and names the lower rung you could drop to |
| Forgetting to revisit a decision when its trigger fires | A revisit check (`npm run revisit`) that surfaces ADRs whose date- or version-based trigger has come due |
| Mistaking a good recommendation for a good result | A post-implementation reflex: confirm the choice actually cut code, failure modes, and operating burden — a sound option can still be integrated badly |
| Being unprovable marketing | A behavior benchmark (Codex + Claude, with an optional LLM judge) that measures the change |
The three that matter most: **it picks the right tool for the job, it researches dependencies before you own them, and it works across every agent you use** — the same rule ships to Codex, Claude Code, Gemini, Cursor, GitHub Copilot, and more.
## Quick Start
Install the agent rule and optional PR dependency check in any repository:
```bash
npx buy-vs-build init
```
That writes:
- `AGENTS.md` with the buy-before-build rule for agent hosts that read it.
- `.buyvsbuild.json` so the project can tune strictness and ownership priorities.
- `.github/workflows/buy-vs-build-review.yml`, which comments on new dependencies
that lack a decision note and fails CI when `.buyvsbuild.json` is `strict`.
For instruction-only setup without the GitHub Action:
```bash
npx buy-vs-build init --agents-only
```
## Decide First: Core vs Context
The ladder below tells you *how far to reach for reuse*. Two questions decide *whether to reuse at all*:
- **Core or context?** Core is the differentiation customers choose you for. Context is everything they expect but never reward — auth, email, parsing, config. Build core; reuse context.
- **Commodity or novel?** Commodity capabilities are standardized and stable. Novel ones are still changing or specific to you. Reuse commodities; build novelty.
| | Commodity | Novel |
| ----------- | --------------------------------------------------------------- | ------------------------------------------------ |
| **Core** | Reuse the substrate, build the thin layer that differentiates. | Build in-house — this is the moat. |
| **Context** | Reuse aggressively: built-in → platform → dependency → commercial. | Do the minimum: defer, stub, or simplest reuse. |
Then scale scrutiny to **reversibility**: a two-way-door choice (easy to swap or delete) decides fast; a one-way-door commitment (deep platform, data-format, or vendor lock-in) earns rigor and a written exit plan.
## The Rule
Once you know what you are choosing to own, walk the reuse ladder. Stop at the first rung that satisfies the requirement:
1. **Do nothing**: skip speculative requirements and scaffolding.
2. **Use built-ins**: prefer language built-ins and the standard library.
3. **Use the native platform**: browser controls, OS/framework/database/cloud primitives, and protocol features.
4. **Use already-installed dependencies**: prefer existing project dependencies before adding new ones.
5. **Use open source**: add a mature library only when it lowers total ownership cost.
6. **Use commercial**: buy reliability, compliance, operations, support, or time when cheaper than owning it.
7. **Build in-house only when** reuse fails the real constraints, or the work is core differentiation.
For non-obvious choices, the agent compares fit, total cost of ownership, security, licensing, maintenance, integration, maturity, reversibility, and exit risk. After implementing, it verifies the choice actually paid off — fewer lines, fewer failure modes, less to operate — because a sound option can still be integrated badly. The decision note records that tradeoff so a reviewer can check it later.
Example decision note:
```text
Decision: use native-platform: native date input.
Tradeoff: accessibility and browser behavior are good enough for a due-date field.
Rejected: open-source date picker because it adds styling, keyboard, and date-edge ownership.
Revisit if product needs range selection or non-Gregorian calendar support.
```
## Safety Boundaries
This is not "do less at any cost." Buy-vs-build thinking must never cut:
- Trust-boundary validation
- Security and privacy requirements
- Data-loss protection
- Accessibility
- Production observability
- Explicit user requirements
Cheap code that loses customer data is not cheap. It is just a delayed invoice.
## Tune It Per Project
Drop a `.buyvsbuild.json` at your repo root to adapt the rule to your real
constraints. The SessionStart hook injects it alongside the rule, so the agent
sees your policy on every turn.
```json
{
"strictness": "strict",
"priorities": ["security", "speed"],
"preferredDependencies": ["zod", "date-fns"],
"bannedDependencies": ["moment"],
"alwaysBuild": ["our deal-scoring formula"],
"alwaysReuse": ["auth", "email delivery", "payments"],
"notes": "We are SOC2; weight compliance and observability heavily."
}
```
Every field is optional. A regulated shop can weight security and force reuse of
auth; a startup can prioritize speed; a team can pin its standardized
dependencies and ban the ones it has been burned by. Malformed config is ignored,
never fatal.
## Supported Agent Surfaces
This repo ships the same rule through the files each host already knows how to read.
| Host | Files |
| --- | --- |
| Codex | `.codex-plugin/plugin.json`, `skills/buy-vs-build/`, `hooks/hooks.json`, `AGENTS.md` |
| Claude Code | `.claude-plugin/plugin.json`, `CLAUDE.md`, lifecycle hook config |
| Gemini CLI / Antigravity | `gemini-extension.json`, `GEMINI.md`, `AGENTS.md` |
| GitHub Copilot | `.github/copilot-instructions.md` |
| Cursor | `.cursor/rules/buy-vs-build.mdc` |
| Windsurf | `.windsurf/rules/buy-vs-build.md` |
| Cline | `.clinerules/buy-vs-build.md` |
| Kiro | `.kiro/steering/buy-vs-build.md` |
| OpenCode | `opencode.json`, `.opencode/plugins/buy-vs-build.mjs` |
| OpenClaw | `.openclaw/skills/buy-vs-build/` |
| Pi-style harnesses | `package.json` `pi.skills` |
| Generic agents | `AGENTS.md` |
The hook files are included for hosts that support lifecycle injection. Hosts that only read instruction files still get the rule, just without startup fanfare.
## Install
### GitHub Action
Add the dependency review check directly:
```yaml
name: Buy vs Build PR Review
on:
pull_request:
permissions:
contents: read
pull-requests: write
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 0
- uses: actions/setup-node@v5
with:
node-version: 22.x
- uses: stdin/buy-vs-build/.github/actions/dependency-review@main
env:
BASE_SHA: ${{ github.event.pull_request.base.sha }}
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
PR_BODY: ${{ github.event.pull_request.body }}
GITHUB_TOKEN: ${{ github.token }}
```
### Codex
```bash
codex plugin marketplace add stdin/buy-vs-build
```
Open `/plugins`, install Buy vs Build, and start a new session. If your Codex surface reads `AGENTS.md`, cloning the repo or copying `AGENTS.md` into a project is enough for instruction-only mode.
### Claude Code
Use the Claude plugin flow with this repository as the source, or copy `CLAUDE.md` into the target project for instruction-only mode.
### Gemini CLI
```bash
gemini extensions install https://github.com/stdin/buy-vs-build
```
### OpenCode
Run OpenCode from a checkout of this repo, or add this plugin path to your project `opencode.json`:
```json
{
"plugin": ["./.opencode/plugins/buy-vs-build.mjs"]
}
```
The OpenCode plugin injects the ruleset into the system prompt every turn and registers this repo's `skills/` path.
### Instruction-Only Hosts
Copy the matching file into your project:
- GitHub Copilot: `.github/copilot-instructions.md`
- Cursor: `.cursor/rules/buy-vs-build.mdc`
- Windsurf: `.windsurf/rules/buy-vs-build.md`
- Cline: `.clinerules/buy-vs-build.md`
- Kiro: `.kiro/steering/buy-vs-build.md`
- Generic: `AGENTS.md`
This is the lowest-tech install path, which is appropriate for a project about not overbuilding things.
## Commands / Skills
Skill-capable hosts can use:
| Skill | Use it when |
| --- | --- |
| `$buy-vs-build` | Apply the core rule while coding. |
| `$buy-vs-build-right-tool` | Pick the option that fits the requirement's shape, not the flashy default (SSE vs WebSockets, SQL vs NoSQL, cron vs queue). |
| `$buy-vs-build-review` | Review a diff for avoidable custom code, unnecessary dependencies, or a choice integrated badly. |
| `$buy-vs-build-audit` | Audit a repo or subsystem for ownership mistakes. |
| `$buy-vs-build-decision` | Draft a short decision memo. |
| `$buy-vs-build-gain` | Summarize benchmark cases and measured impact. |
| `$buy-vs-build-adr` | Record a non-obvious decision as a durable ADR in `docs/decisions/`. |
| `$buy-vs-build-dependency` | Research a package's health, security, license, and footprint before adopting it. |
## Benchmarks
Local overhead is intentionally tiny:
- Instruction generation: about `0.009ms` average.
- Hook process startup: about `28ms` average.
The 13 behavior cases in `benchmarks/behavior-cases.json` cover overbuild traps (date input, CSV export, validation, password-reset email, OIDC, proprietary scoring), right-tool traps (SSE vs WebSockets, REST vs GraphQL, SQL vs NoSQL, webhook vs polling, cron vs queue), and built-in-over-dependency (UUID, string padding).
Latest live validation:
- Run: [behavior-claude-2026-06-19T10-23-39-792Z.md](benchmarks/results/behavior-claude-2026-06-19T10-23-39-792Z.md)
- Agent: Claude Code `2.1.183`, model `claude-haiku-4-5`, Node `v24.12.0`, macOS arm64.
- 13 cases: baseline `33/65`, Buy vs Build enabled `55/65` (**+22**). Correct rung/option hits: `11/13 → 12/13`.
- Every case improved or held, and the biggest lifts are the traps the rule targets — built-in UUID `0→3`, relational store `2→5`, the right-tool cases `+2` each.
- Run on a small model on purpose: the rule's lift shows clearest there and runs stay cheap. For quality-aware scoring instead of keyword matching, add `--judge`.
Run it yourself:
```bash
npm run benchmark:behavior # Codex CLI
npm run benchmark:behavior:claude # Claude CLI (small model by default)
npm run benchmark:behavior:claude:judge # Claude CLI, rubric-based LLM judge
npm run benchmark:behavior:gate # Dry regression gate used by npm test
```
Important honesty note: this benchmark scores final recommendations, not code diffs, token spend, or incident reduction. It is still useful because it tests the thing this plugin promises first: does the agent make the buy-vs-build decision visible before it starts owning code? The reflex to check the *implemented* outcome — did it actually cut code, failure modes, and operating burden? — now lives in the rule and the review skill, but measuring that outcome directly is future work. Marketing is allowed to wear shoes; it is not allowed to fly.
## Development
Run the test suite:
```bash
npm test
```
`npm test` also runs a dry behavior benchmark gate so rule changes cannot silently
drop below the expected score threshold.
Run the local overhead benchmark:
```bash
npm run benchmark
```
Run the live behavior benchmark (Codex CLI or Claude CLI):
```bash
npm run benchmark:behavior
npm run benchmark:behavior:claude
```
Score recommendations with the rubric-based LLM judge instead of the keyword heuristic (more robust, calls the model once per response):
```bash
npm run benchmark:behavior:claude:judge
```
Check benchmark report generation without calling a model:
```bash
npm run benchmark:behavior:dry
npm run benchmark:behavior:claude:dry
npm run benchmark:behavior:gate
```
Audit the dependencies a repo already owns (ranks every direct dependency by ownership risk and names the rung it could drop to; reads `package.json`, `package-lock.json`, `requirements.txt`, `pyproject.toml`, `go.mod`, `Cargo.toml`, `Gemfile`, `pom.xml`, and NuGet project files):
```bash
npm run audit:deps # audit the current directory
node scripts/audit-deps.js path/to/repo
```
Surface decisions whose revisit trigger has come due (date- or dependency-version-based; the rest are flagged for a human look):
```bash
npm run revisit
```
Check copied rule files for drift:
```bash
node scripts/check-rule-copies.js
```
Validate the Codex skill and plugin (paths are relative to your Codex install):
```bash
python3 ~/.codex/skills/.system/skill-creator/scripts/quick_validate.py skills/buy-vs-build
python3 ~/.codex/skills/.system/plugin-creator/scripts/validate_plugin.py .
```
When changing the compact rules, edit `rules/buy-vs-build.md` first, then update the copied instruction files. The drift check will complain if they diverge, which is its one job and it takes that job very seriously.
## FAQ
**Is this anti-open-source?**
No. It is pro-ownership clarity. Use open source when it lowers total cost and risk. Avoid it when it turns three obvious lines into another thing to patch forever.
**Is this anti-commercial tools?**
No. A paid service can be the cheapest option when it buys reliability, compliance, support, or operations you do not want to own.
**When should we build in-house?**
When the behavior is core product differentiation, the code is smaller and clearer than a dependency, or reuse fails security, privacy, licensing, latency, offline, portability, data-residency, or integration constraints.
**Will this slow agents down?**
The local rule overhead is tiny. The decision may add a sentence. That sentence is cheaper than a migration.
## License
[MIT](LICENSE).