Complete Commander.js CLI framework guidance covering command structure, options, arguments, subcommands, action handlers, version management, and TypeScript integration. Use when: building CLI tools, parsing command-line arguments, implementing subcommands, handling options/flags, creating interactive CLIs, or migrating from other CLI frameworks. Keywords: Commander.js, CLI, command-line, arguments, options, flags, subcommands, action handlers, version, help text, TypeScript, yargs, meow, program, parseAsync, opts, args, variadic, required options, default values, custom help, error handling
Overall
score
99%
Does it follow best practices?
Validation for skill structure
Complete guide to defining and handling options in Commander.js.
program
.option('-d, --debug', 'Enable debug mode')
.option('-v, --verbose', 'Verbose output');Options are accessed as camelCase:
.action((options) => {
if (options.debug) { /* ... */ }
if (options.verbose) { /* ... */ }
});program
.option('-p, --port <number>', 'Port number')
.option('-o, --output <path>', 'Output file');
// Usage: my-cli --port 3000 --output dist/program
.option('-c, --config [path]', 'Config file (optional)');
// Usage: my-cli --config
// or: my-cli --config custom.jsonprogram
.option('-p, --port <number>', 'Port', '3000')
.option('-h, --host <address>', 'Host', 'localhost');program
.option('-n, --name <value>', 'Name');import { Option } from 'commander';
program
.addOption(
new Option('-p, --port <number>', 'Port')
.argParser(parseInt)
);Or with validation:
program
.option('-p, --port <number>', 'Port', (value) => {
const port = parseInt(value, 10);
if (isNaN(port) || port < 0 || port > 65535) {
throw new Error('Invalid port number');
}
return port;
});program
.option('-f, --force', 'Force overwrite')
.option('--no-color', 'Disable colors'); // Negative booleanprogram
.option('-i, --include <paths...>', 'Files to include');
// Usage: my-cli --include file1.js file2.js file3.jsprogram
.option('-v, --verbose', 'Verbose (repeatable)', (_, prev) => prev + 1, 0);
// Usage: my-cli -vvv
// Result: options.verbose === 3Or collecting values:
program
.option('-e, --exclude <pattern>', 'Exclude pattern',
(value, prev) => prev.concat([value]), []);
// Usage: my-cli -e "*.test.js" -e "*.spec.js"
// Result: options.exclude === ['*.test.js', '*.spec.js']program
.requiredOption('-c, --config <path>', 'Config file (required)');
// Throws error if not providedprogram
.option('-b, --build', 'Build project')
.option('-w, --watch', 'Watch mode')
.conflictsWith('watch'); // --build and --watch cannot be used togetherprogram
.option('--production', 'Production mode')
.option('--minify', 'Minify output')
.addOption(
new Option('--production')
.implies({ minify: true })
);program
.option('-p, --port <number>', 'Port', process.env.PORT || '3000')
.option('--api-key <key>', 'API Key', process.env.API_KEY);program
.option('-d, --date <date>', 'Date', (value) => {
const date = new Date(value);
if (isNaN(date.getTime())) {
throw new Error('Invalid date format');
}
return date;
});import { Option } from 'commander';
program
.addOption(
new Option('-l, --log-level <level>', 'Log level')
.choices(['debug', 'info', 'warn', 'error'])
.default('info')
);program
.addOption(
new Option('--internal', 'Internal use only')
.hideHelp()
);import { Option } from 'commander';
program
.addOption(
new Option('-e, --env <name>', 'Environment')
.choices(['dev', 'staging', 'production'])
.default('dev')
.env('NODE_ENV')
);import { Command, Option } from 'commander';
const program = new Command();
program
.name('build')
.description('Build project')
.requiredOption('-i, --input <path>', 'Input directory')
.option('-o, --output <path>', 'Output directory', 'dist')
.option('-f, --format <type>', 'Output format', (value) => {
const valid = ['esm', 'cjs', 'umd'];
if (!valid.includes(value)) {
throw new Error(`Format must be one of: ${valid.join(', ')}`);
}
return value;
}, 'esm')
.option('-m, --minify', 'Minify output')
.option('-s, --sourcemap', 'Generate sourcemaps')
.option('-w, --watch', 'Watch mode')
.addOption(
new Option('-l, --log-level <level>', 'Log level')
.choices(['debug', 'info', 'warn', 'error'])
.default('info')
)
.option('-e, --exclude <patterns...>', 'Exclude patterns')
.action(async (options) => {
console.log('Building with options:', options);
// Validate combinations
if (options.watch && options.minify) {
console.warn('Warning: minify is slow in watch mode');
}
// Implementation
});
await program.parseAsync(process.argv);--output-dir not --outputDirrequiredOption instead of validating in action handlerschoices() for enum valuesInstall with Tessl CLI
npx tessl i pantheon-ai/commanderjs@0.1.1