The complete solution for Node.js command-line interfaces
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Core command functionality for creating CLI applications with subcommands, nested command structures, action handlers, and comprehensive parsing capabilities.
Commander provides a pre-created Command instance for simple CLI programs.
/**
* Pre-created Command instance for simple CLI programs
*/
const program: Command;Usage Examples:
import { program } from 'commander';
program
.name('my-cli')
.description('A simple CLI application')
.version('1.0.0')
.option('-v, --verbose', 'verbose output')
.parse();Create new Command instances programmatically.
/**
* Creates a new Command instance
* @param name - Optional command name
* @returns New Command instance
*/
function createCommand(name?: string): Command;Usage Examples:
import { createCommand } from 'commander';
const myCommand = createCommand('deploy')
.description('Deploy the application')
.option('-e, --env <environment>', 'deployment environment')
.action((options) => {
console.log(`Deploying to ${options.env}`);
});The main class for creating CLI commands and subcommands.
/**
* Main class for creating CLI commands and subcommands
* Extends EventEmitter for lifecycle hooks
*/
class Command extends EventEmitter {
/**
* Initialize a new Command instance
* @param name - Optional command name
*/
constructor(name?: string);
// Properties
readonly commands: readonly Command[];
readonly options: readonly Option[];
readonly registeredArguments: readonly Argument[];
parent: Command | null;
args: string[];
processedArgs: any[];
}Configure basic command properties like name, description, and version.
interface Command {
/**
* Get the command name
*/
name(): string;
/**
* Set the command name
* @param str - Command name
* @returns this command for chaining
*/
name(str: string): this;
/**
* Get the command description
*/
description(): string;
/**
* Set the command description
* @param str - Command description
* @returns this command for chaining
*/
description(str: string): this;
/**
* Get the command summary (used in subcommand listings)
*/
summary(): string;
/**
* Set the command summary
* @param str - Command summary
* @returns this command for chaining
*/
summary(str: string): this;
/**
* Get the program version
*/
version(): string | undefined;
/**
* Set the program version and auto-register version option
* @param str - Version string
* @param flags - Version option flags (default: '-V, --version')
* @param description - Version option description
* @returns this command for chaining
*/
version(str: string, flags?: string, description?: string): this;
/**
* Get the command usage string
*/
usage(): string;
/**
* Set the command usage string
* @param str - Usage string
* @returns this command for chaining
*/
usage(str: string): this;
}Configure command aliases for shorter or alternative command names.
interface Command {
/**
* Get the first command alias
*/
alias(): string;
/**
* Add a command alias
* @param alias - Alias name
* @returns this command for chaining
*/
alias(alias: string): this;
/**
* Get all command aliases
*/
aliases(): string[];
/**
* Set command aliases
* @param aliases - Array of alias names
* @returns this command for chaining
*/
aliases(aliases: readonly string[]): this;
}Create and manage subcommands with action handlers or executable files.
interface Command {
/**
* Define a subcommand with action handler
* @param nameAndArgs - Command name and arguments (e.g., 'clone <source> [destination]')
* @param opts - Command options
* @returns New Command instance for the subcommand
*/
command(nameAndArgs: string, opts?: CommandOptions): Command;
/**
* Define an executable subcommand
* @param nameAndArgs - Command name and arguments
* @param description - Command description
* @param opts - Executable command options
* @returns this command for chaining
*/
command(nameAndArgs: string, description: string, opts?: ExecutableCommandOptions): this;
/**
* Add a prepared subcommand
* @param cmd - Command instance to add
* @param opts - Command options
* @returns this command for chaining
*/
addCommand(cmd: Command, opts?: CommandOptions): this;
/**
* Factory routine to create a new unattached command
* Override this to customize subcommands
* @param name - Optional command name
* @returns New Command instance
*/
createCommand(name?: string): Command;
}Usage Examples:
// Action handler subcommand
program
.command('serve <port>')
.description('Start the development server')
.option('-h, --host <host>', 'server host', 'localhost')
.action((port, options) => {
console.log(`Starting server on ${options.host}:${port}`);
});
// Executable subcommand
program
.command('deploy <environment>', 'Deploy to specified environment')
.command('test', 'Run test suite');
// Adding prepared command
const deployCommand = createCommand('deploy')
.description('Deploy application')
.action(() => console.log('Deploying...'));
program.addCommand(deployCommand);Register callback functions to execute when commands are invoked.
interface Command {
/**
* Register action handler for the command
* @param fn - Action function receiving parsed arguments and options
* @returns this command for chaining
*/
action(fn: (this: this, ...args: any[]) => void | Promise<void>): this;
}Usage Examples:
program
.command('greet <name>')
.option('-f, --formal', 'use formal greeting')
.action((name, options) => {
const greeting = options.formal ? `Good day, ${name}` : `Hey ${name}!`;
console.log(greeting);
});
// Async action
program
.command('fetch <url>')
.action(async (url) => {
const response = await fetch(url);
console.log(await response.text());
});Parse command-line arguments and execute appropriate commands.
interface Command {
/**
* Parse command-line arguments synchronously
* @param argv - Arguments to parse (defaults to process.argv)
* @param parseOptions - Parsing configuration
* @returns this command for chaining
*/
parse(argv?: readonly string[], parseOptions?: ParseOptions): this;
/**
* Parse command-line arguments asynchronously
* @param argv - Arguments to parse (defaults to process.argv)
* @param parseOptions - Parsing configuration
* @returns Promise resolving to this command
*/
parseAsync(argv?: readonly string[], parseOptions?: ParseOptions): Promise<this>;
/**
* Parse options from argv, returning operands and unknown arguments
* @param argv - Arguments to parse
* @returns Parsed results with operands and unknown arguments
*/
parseOptions(argv: string[]): ParseOptionsResult;
}
interface ParseOptions {
/** Where arguments originate from */
from: 'node' | 'electron' | 'user';
}
interface ParseOptionsResult {
operands: string[];
unknown: string[];
}Usage Examples:
// Parse process.argv automatically
program.parse();
// Parse custom arguments
program.parse(['node', 'script.js', 'command', '--option', 'value']);
// Parse user arguments only
program.parse(['command', '--option', 'value'], { from: 'user' });
// Async parsing
await program.parseAsync();Configure parsing behavior, option handling, and command execution.
interface Command {
/**
* Allow unknown options without error
* @param allowUnknown - Whether to allow unknown options
* @returns this command for chaining
*/
allowUnknownOption(allowUnknown?: boolean): this;
/**
* Allow excess command arguments without error
* @param allowExcess - Whether to allow excess arguments
* @returns this command for chaining
*/
allowExcessArguments(allowExcess?: boolean): this;
/**
* Enable positional options (global options before subcommands)
* @param positional - Whether to enable positional options
* @returns this command for chaining
*/
enablePositionalOptions(positional?: boolean): this;
/**
* Pass through options after command arguments
* @param passThrough - Whether to pass through options
* @returns this command for chaining
*/
passThroughOptions(passThrough?: boolean): this;
/**
* Configure short flag parsing with optional values
* @param combine - Whether to combine flags with optional values
* @returns this command for chaining
*/
combineFlagAndOptionalValue(combine?: boolean): this;
/**
* Store option values as properties on command object
* @returns this command for chaining
*/
storeOptionsAsProperties(): this;
}Add hooks for command lifecycle events.
interface Command {
/**
* Add lifecycle hook
* @param event - Hook event type
* @param listener - Hook callback function
* @returns this command for chaining
*/
hook(event: HookEvent, listener: (thisCommand: Command, actionCommand: Command) => void | Promise<void>): this;
}
type HookEvent = 'preSubcommand' | 'preAction' | 'postAction';Usage Examples:
program
.hook('preAction', (thisCommand, actionCommand) => {
console.log(`About to execute ${actionCommand.name()}`);
})
.hook('postAction', (thisCommand, actionCommand) => {
console.log(`Finished executing ${actionCommand.name()}`);
});Save and restore command state for multiple parsing operations.
interface Command {
/**
* Save state before parsing (called automatically)
*/
saveStateBeforeParse(): void;
/**
* Restore state before parsing (called automatically)
*/
restoreStateBeforeParse(): void;
}Configure executable subcommands and search directories.
interface Command {
/**
* Set executable search directory
* @param path - Directory path for executable subcommands
* @returns this command for chaining
*/
executableDir(path: string): this;
/**
* Get executable search directory
*/
executableDir(): string | null;
/**
* Set command name from filename
* @param filename - File path to extract name from
* @returns this command for chaining
*/
nameFromFilename(filename: string): this;
}Utility methods for command management and configuration.
interface Command {
/**
* Copy settings from source command (used internally)
* @param sourceCommand - Command to copy settings from
* @returns this command for chaining
*/
copyInheritedSettings(sourceCommand: Command): this;
/**
* Add event listener for command events
* @param event - Event name
* @param listener - Event callback
* @returns this command for chaining
*/
on(event: string | symbol, listener: (...args: any[]) => void): this;
}interface CommandOptions {
/** Hide command from help display */
hidden?: boolean;
/** Make this command the default when no command is specified */
isDefault?: boolean;
}
interface ExecutableCommandOptions extends CommandOptions {
/** Custom executable file name */
executableFile?: string;
}