burgee
Comparisons

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:

passingrate
burgee/commander1360 / 1360100.0%
commander itself (control)1360 / 1360100.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 its effects (.effects('read_only') on commander syntax), so nothing is exposed to an agent by accident.
  • Completionscompletion 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):

burgeecommander
Runtime dependencies5, none outside the burgee family0
Full CLI run over bare node+14.0 ms+15.3 ms
Installed size1154 KB203 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 --json output 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.

On this page