burgee vs commander
A commander alternative that is drop-in compatible: change one import, keep your code and tests, and gain --json, --schema, --mcp and shell completions. Graded by commander's own test suite.
burgee is a commander alternative you adopt by changing one import. It is not a new
API to learn and not a wrapper around commander: burgee/commander implements commander's
API itself, and commander's own test suite is the grade.
Migrate from commander in one import
- import { Command } from 'commander';
+ import { Command } from 'burgee/commander';Your program and your tests stay as they are. On a larger codebase, npx burgee migrate --dry-run finds every commander import and prints the rewrite before it makes one; it
refuses, by file and line, anything it cannot rewrite mechanically, and leaves that file
untouched.
Is it really compatible with commander?
Compatibility is graded, not claimed. commander's own test suite — vendored, unmodified
apart from the import specifier — runs against burgee/commander in CI, beside a control
that runs the same suite against real commander:
| passing | rate | |
|---|---|---|
burgee/commander | 1360 / 1360 | 100.0% |
| commander itself (control) | 1360 / 1360 | 100.0% |
From Compatibility, which npm run compat:page generates from the
oracle's last run; this table is copied from it and that page is the authority. A façade
is never called "compatible" until its host's own suite passes 100%.
What you gain over commander
The same program, after the import swap, answers four things commander cannot:
--json— every command's result in one stable envelope,{ "ok": true, "data": … }, with errors in the same shape. No stdout scraping.--schema— the whole command tree as data: commands, arguments, options, choices, defaults and a JSON Schema per command. It runs no handler and reads no config, so it is safe for an agent to call first.--mcp— the same commands served as MCP tools over stdio. A command becomes a tool when it declares itseffects(.effects('read_only')on commander syntax), so nothing is exposed to an agent by accident.- Completions —
completion bash | zsh | fish | pwsh, generated from the same declaration; pressing TAB never runs your program.
And an exit-code contract an agent can act on: 2 means rewrite the command, any other
non-zero means the command was fine and the world was not. Details on
Your CLI is an agent tool.
Plugins, too: commander's plugin RFC (#2505) is unlanded, while a burgee plugin works on commander syntax, yargs syntax and native alike — see Plugins.
What commander still does better
Weight. From the root README's Measured table (2026-09-09, one machine, generated by
npm run bench — see Benchmarks and
burgee vs the alternatives):
| burgee | commander | |
|---|---|---|
| Runtime dependencies | 5, none outside the burgee family | 0 |
| Full CLI run over bare node | +14.0 ms | +15.3 ms |
| Installed size | 1154 KB | 203 KB |
The lighter-than-commander gate — burgee/commander lighter in a bundle than commander
alone — is not met (1.514×). Against commander plus what a commander user installs to
match burgee's config, shutdown and cursor handling, it is met (0.468×). Both rows are on
the README and neither is hidden. And commander has users; burgee is new.
When to switch
- You want your CLI usable by an AI agent without writing tool definitions by hand.
- You want
--jsonoutput and exit codes that mean something, on every command. - You want plugins shared across programs.
If none of that matters and bundle bytes do, commander is the lighter choice today.
Compatibility
Each host's own test suite, run against burgee in CI. A published pass rate that only goes up — never the word "compatible".
burgee vs yargs
A yargs alternative that is drop-in compatible: change one import, keep your code and tests, and gain --json, --schema, --mcp and shell completions — with no dependency outside the burgee family where yargs has six.