Complete solution for Node.js command-line interfaces
- npm: https://www.npmjs.com/package/commander
- GitHub: https://github.com/tj/commander.js
- Downloads: 200M+ weekly
- Battle-tested since 2011
bun add commanderCurrent version in commando: 14.0.2
import { Command } from 'commander';
const program = new Command();
program
.name('cmdo')
.description('Modern CLI framework')
.version('2.0.0');
program.parse();program
.option('-d, --debug', 'Output extra debugging')
.option('-s, --small', 'Small pizza size')
.option('-p, --pizza-type <type>', 'Flavour of pizza');
program.parse();
const options = program.opts();
if (options.debug) console.log(options);program
.command('deploy')
.description('Deploy to environment')
.argument('<environment>', 'Environment name')
.option('-s, --skip-tests', 'Skip tests')
.action((environment, options) => {
console.log(`Deploying to ${environment}`);
if (options.skipTests) {
console.log('Skipping tests');
}
});Commando uses Commander to build commands from config:
// lib/core.ts
export function buildCommanderCommand(
name: string,
cmdoCmd: CommandoCommand,
context: CommandoContext
): Command {
const cmd = new Command(name);
cmd.description(cmdoCmd.description);
// Let command customize if needed
if (cmdoCmd.defineCommand) {
cmdoCmd.defineCommand(cmd);
}
// Install action handler
cmd.action(async (...args) => {
const options = args[args.length - 2];
const positionalArgs = args.slice(0, -2);
await cmdoCmd.execute(options, positionalArgs, context);
});
return cmd;
}export const version: CommandoCommand = {
description: 'Show version',
execute: async (options, args) => {
console.log('v2.0.0');
}
};export const build: CommandoCommand = {
description: 'Build website',
defineCommand: (cmd) => {
cmd
.option('-c, --clean', 'Clean build directory first')
.option('--no-optimize', 'Skip optimization');
},
execute: async (options, args) => {
if (options.clean) {
await $`rm -rf dist`;
}
// options.optimize is boolean (auto-negated from --no-optimize)
}
};export const deploy: CommandoCommand = {
description: 'Deploy to environment',
defineCommand: (cmd) => {
cmd
.argument('<environment>', 'Target environment')
.option('-s, --skip-tests', 'Skip tests');
},
execute: async (options, args) => {
const environment = args[0]; // Required positional arg
console.log(`Deploying to ${environment}`);
}
};Commander generates help automatically:
$ cmdo deploy --help
Usage: cmdo deploy [options] <environment>
Deploy to environment
Arguments:
environment Target environment
Options:
-s, --skip-tests Skip tests
-h, --help display help for commandprogram
.command('deploy')
.argument('<environment>', 'Environment', (value) => {
const valid = ['staging', 'production'];
if (!valid.includes(value)) {
throw new Error(`Invalid environment. Use: ${valid.join(', ')}`);
}
return value;
});cmd
.option('-b, --bucket <name>', 'S3 bucket', 'default-bucket')
.option('--region <region>', 'AWS region', 'us-east-1');import { Option } from 'commander';
cmd.addOption(
new Option('-r, --region <region>', 'AWS region')
.choices(['us-east-1', 'us-west-2', 'eu-west-1'])
);// --no-optimize sets options.optimize = false
cmd.option('--no-optimize', 'Skip optimization');
// --no-color sets options.color = false
cmd.option('--no-color', 'Disable colors');cmd
.argument('<files...>', 'Files to process')
.action((files) => {
console.log(`Processing: ${files.join(', ')}`);
});
// Usage: cmdo process file1.txt file2.txt file3.txtconst cache = program
.command('cache')
.description('Cache operations');
cache
.command('clear')
.description('Clear cache')
.action(() => {
console.log('Clearing cache...');
});
cache
.command('show')
.description('Show cache status')
.action(() => {
console.log('Cache status...');
});
// Usage: cmdo cache clearprogram.exitOverride(); // Throw instead of process.exit()
try {
program.parse();
} catch (error) {
console.error('Command failed:', error.message);
process.exit(1);
}import { Command } from 'commander';
// Get typed options
interface DeployOptions {
skipTests?: boolean;
dryRun?: boolean;
}
const options = program.opts<DeployOptions>();- Documentation: https://github.com/tj/commander.js#readme
- Examples: https://github.com/tj/commander.js/tree/master/examples