Automated summary
Provides Commander.js patterns, templates, and examples for building Node.js CLI applications in TypeScript, covering commands, options, arguments, and nested subcommands.
Strengths
- Covers common cases: options with defaults and choices, required, optional, and variadic arguments
- Demonstrates advanced Option class usage such as choices, argParser, and makeOptionMandatory
- Shows command hierarchies through nested subcommands
- TypeScript snippets are directly copy-pasteable into a project
Limitations
- The supplied content is truncated, so some examples (custom argument parsing, error handling) are incomplete
- Focused solely on Commander.js with no comparison to other CLI frameworks
- Does not address npm publishing or full project scaffolding
Use it when writing or modifying a Node.js or TypeScript CLI built on Commander.js, especially to add options, arguments, or subcommands.
Skip it if the project relies on a different CLI framework (yargs, oclif, cac) or is a shell script with no Node.js dependency.
Security analysis
CautionThe skill is a Commander.js documentation/reference guide with no destructive, exfiltration, or obfuscated instructions. It does allow powerful file-writing and shell tools for legitimate CLI development tasks, and it references shell scripts whose contents are not shown, so it warrants caution rather than a fully safe rating.
- •Declares Bash, Write, and Edit tools, allowing an agent to execute shell commands and modify workspace files; this is legitimate for CLI scaffolding/testing but is a meaningful execution surface.
- •References helper scripts such as validate-commander-structure.sh and generate-command.sh, but their contents are not included in SKILL.md, so their behavior cannot be audited from the provided material.
Examples
Using Commander.js in TypeScript, create a CLI named mycli with a 'deploy' command that takes an <environment> argument and options --env (default 'dev'), --force, and --verbose.Add a 'config' command group to my Commander.js CLI with 'get <key>', 'set <key> <value>', and 'list' subcommands.Use Commander.js's Option class to add a --mode option restricted to 'fast', 'safe', and 'rollback' with a default of 'safe' and make it mandatory.name: Commander.js Patterns description: Commander.js CLI framework patterns including Command class, options, arguments, nested subcommands, and Option class usage. Use when building Node.js CLIs, implementing Commander.js commands, creating TypeScript CLI tools, adding command options/arguments, or when user mentions Commander.js, CLI commands, command options, or nested subcommands. allowed-tools: Read, Write, Bash, Edit
Commander.js Patterns Skill
Provides comprehensive Commander.js patterns, templates, and examples for building robust Node.js CLI applications with TypeScript support.
Overview
Commander.js is the complete solution for Node.js command-line interfaces. This skill provides battle-tested patterns for:
- Command class instantiation and configuration
- Options with flags, choices, and defaults
- Arguments (required, optional, variadic)
- Nested subcommands and command hierarchies
- Option class with advanced validation
- Action handlers and middleware
- Error handling and validation
Instructions
Basic Command Setup
-
Create program instance:
import { Command } from 'commander'; const program = new Command(); program .name('mycli') .description('CLI description') .version('1.0.0'); -
Add simple command:
program .command('init') .description('Initialize project') .action(() => { // Command logic }); -
Parse arguments:
program.parse();
Command with Options
Use options for named flags with values:
program
.command('deploy')
.description('Deploy application')
.option('-e, --env <environment>', 'target environment', 'dev')
.option('-f, --force', 'force deployment', false)
.option('-v, --verbose', 'verbose output')
.action((options) => {
console.log('Environment:', options.env);
console.log('Force:', options.force);
console.log('Verbose:', options.verbose);
});
Command with Arguments
Use arguments for positional parameters:
program
.command('deploy <environment>')
.description('Deploy to environment')
.argument('<environment>', 'target environment')
.argument('[region]', 'optional region', 'us-east-1')
.action((environment, region, options) => {
console.log(`Deploying to ${environment} in ${region}`);
});
Option Class Usage
For advanced option configuration:
import { Command, Option } from 'commander';
program
.command('deploy')
.addOption(
new Option('-m, --mode <mode>', 'deployment mode')
.choices(['fast', 'safe', 'rollback'])
.default('safe')
.makeOptionMandatory()
)
.addOption(
new Option('-r, --replicas <count>', 'replica count')
.argParser(parseInt)
.default(3)
)
.action((options) => {
console.log(`Mode: ${options.mode}, Replicas: ${options.replicas}`);
});
Nested Subcommands
Create command hierarchies:
const config = program
.command('config')
.description('Manage configuration');
config
.command('get <key>')
.description('Get config value')
.action((key) => {
console.log(`Config ${key}:`, getConfig(key));
});
config
.command('set <key> <value>')
.description('Set config value')
.action((key, value) => {
setConfig(key, value);
console.log(`✓ Set ${key} = ${value}`);
});
config
.command('list')
.description('List all config')
.action(() => {
console.log(getAllConfig());
});
Variadic Arguments
Accept multiple values:
program
.command('add <items...>')
.description('Add multiple items')
.action((items) => {
console.log('Adding items:', items);
});
// Usage: mycli add item1 item2 item3
Custom Argument Parsing
Transform argument values:
program
.command('wait <delay>')
.description('Wait for specified time')
.argument('<delay>', 'delay in seconds', parseFloat)
.action((delay) => {
console.log(`Waiting ${delay} seconds...`);
});
Global Options
Options available to all commands:
program
.option('-c, --config <path>', 'config file path')
.option('-v, --verbose', 'verbose output')
.option('--no-color', 'disable colors');
program
.command('deploy')
.action((options, command) => {
const globalOpts = command.parent?.opts();
console.log('Config:', globalOpts?.config);
console.log('Verbose:', globalOpts?.verbose);
});
Error Handling
program
.command('deploy <environment>')
.action((environment) => {
if (!['dev', 'staging', 'prod'].includes(environment)) {
throw new Error(`Invalid environment: ${environment}`);
}
// Deploy logic
});
program.exitOverride();
try {
program.parse();
} catch (err) {
console.error('Error:', err.message);
process.exit(1);
}
Available Scripts
- validate-commander-structure.sh: Validates Commander.js CLI structure and patterns
- generate-command.sh: Scaffolds new command with options and arguments
- generate-subcommand.sh: Creates nested subcommand structure
- test-commander-cli.sh: Tests CLI commands with various inputs
- extract-command-help.sh: Extracts help text from CLI for documentation
Templates
TypeScript Templates
- basic-commander.ts: Minimal Commander.js setup
- command-with-options.ts: Command with various option types
- command-with-arguments.ts: Command with required/optional arguments
- nested-subcommands.ts: Multi-level command hierarchy
- option-class-advanced.ts: Advanced Option class usage
- full-cli-example.ts: Complete CLI with all patterns
- commander-with-inquirer.ts: Interactive prompts integration
- commander-with-validation.ts: Input validation patterns
JavaScript Templates
- basic-commander.js: ES modules Commander.js setup
- commonjs-commander.js: CommonJS Commander.js setup
Configuration Templates
- tsconfig.commander.json: TypeScript config for Commander.js projects
- package.json.template: Package.json with Commander.js dependencies
Examples
- basic-usage.md: Simple CLI with 2-3 commands
- options-arguments-demo.md: Comprehensive options and arguments examples
- nested-commands-demo.md: Building command hierarchies
- advanced-option-class.md: Option class validation and parsing
- interactive-cli.md: Combining Commander.js with Inquirer.js
- error-handling-patterns.md: Robust error handling strategies
- testing-commander-cli.md: Unit and integration testing patterns
Commander.js Key Concepts
Command Class
new Command()
.name('cli-name')
.description('CLI description')
.version('1.0.0')
.command('subcommand')
Option Types
- Flag option:
-v, --verbose(boolean) - Value option:
-p, --port <port>(required value) - Optional value:
-p, --port [port](optional value) - Negatable:
--no-color(inverse boolean) - Variadic:
--files <files...>(multiple values)
Argument Types
- Required:
<name> - Optional:
[name] - Variadic:
<items...>or[items...]
Option Class Methods
.choices(['a', 'b', 'c']): Restrict to specific values.default(value): Set default value.argParser(fn): Custom parsing function.makeOptionMandatory(): Require option.conflicts(option): Mutually exclusive options.implies(option): Implies another option.env(name): Read from environment variable
Action Handler Signatures
// No arguments
.action(() => {})
// With options only
.action((options) => {})
// With arguments
.action((arg1, arg2, options) => {})
// With command reference
.action((options, command) => {})
Pattern Recipes
Pattern 1: Simple CLI with Subcommands
Use template: templates/basic-commander.ts
Pattern 2: CLI with Rich Options
Use template: templates/option-class-advanced.ts
Pattern 3: Interactive CLI
Use template: templates/commander-with-inquirer.ts
Pattern 4: CLI with Validation
Use template: templates/commander-with-validation.ts
Pattern 5: Multi-level Commands
Use template: templates/nested-subcommands.ts
Integration with Other Tools
With Inquirer.js (Interactive Prompts)
import inquirer from 'inquirer';
program
.command('setup')
.action(async () => {
const answers = await inquirer.prompt([
{ type: 'input', name: 'name', message: 'Project name:' },
{ type: 'list', name: 'template', message: 'Template:', choices: ['basic', 'advanced'] }
]);
// Use answers
});
With Chalk (Colored Output)
import chalk from 'chalk';
program
.command('deploy')
.action(() => {
console.log(chalk.green('✓ Deployment successful'));
console.log(chalk.red('✗ Deployment failed'));
});
With Ora (Spinners)
import ora from 'ora';
program
.command('build')
.action(async () => {
const spinner = ora('Building...').start();
await build();
spinner.succeed('Build complete');
});
Best Practices
- Use Option class for complex options: Provides better validation and type safety
- Keep action handlers thin: Delegate to separate functions
- Provide clear descriptions: Help users understand commands
- Set sensible defaults: Reduce required options
- Validate early: Check inputs before processing
- Handle errors gracefully: Provide helpful error messages
- Use TypeScript: Better type safety and IDE support
- Test thoroughly: Unit test commands and options
- Document examples: Show common usage patterns
- Version your CLI: Use semantic versioning
Common Patterns
Pattern: Config Command Group
const config = program.command('config');
config.command('get <key>').action(getConfig);
config.command('set <key> <value>').action(setConfig);
config.command('list').action(listConfig);
config.command('delete <key>').action(deleteConfig);
Pattern: CRUD Commands
program.command('create <name>').action(create);
program.command('read <id>').action(read);
program.command('update <id>').action(update);
program.command('delete <id>').action(deleteItem);
program.command('list').action(list);
Pattern: Deploy with Environments
program
.command('deploy')
.addOption(new Option('-e, --env <env>').choices(['dev', 'staging', 'prod']))
.option('-f, --force', 'force deployment')
.action(deploy);
Troubleshooting
Issue: Options not parsed
Solution: Ensure program.parse() is called
Issue: Arguments not received
Solution: Check action handler signature matches argument count
Issue: Subcommands not working
Solution: Verify subcommand is attached before parse()
Issue: TypeScript errors
Solution: Install @types/node and configure tsconfig
Issue: Help not showing
Solution: Commander.js auto-generates help from descriptions
Success Criteria
✅ Command structure follows Commander.js conventions ✅ Options and arguments properly typed ✅ Help text is clear and descriptive ✅ Error handling covers edge cases ✅ CLI tested with various inputs ✅ TypeScript compiles without errors ✅ Commands execute as expected
Related Skills
click-patterns- Python Click framework patternstyper-patterns- Python Typer framework patternsclap-patterns- Rust Clap framework patterns
Skill Type: Framework Patterns + Code Templates Language: TypeScript/JavaScript (Node.js) Framework: Commander.js v12+ Auto-invocation: Yes (via description matching)
From the file to a first result
The download contains exactly the content displayed on this page. This copy may differ from the latest version in the source repository.
View the source and supporting filesThis download contains SKILL.md only. Any scripts, references, templates and dependencies are not included. Get the required files from the source, preserving their directory structure, before continuing.
1. Download the file
Download SKILL.mdFrom the root of a test project, save the file as .skill-downloads/commander-js-patterns-mmlj2oj8/SKILL.md, or use the command below. This folder is for inspecting the skill before installation.
Command for macOS/Linux or WSL: requires a POSIX shell and curl. On Windows without WSL, use the download button and create the folder manually.
mkdir -p '.skill-downloads/commander-js-patterns-mmlj2oj8' && curl --fail --show-error --location 'https://skills-guides.com/api/skills/commander-js-patterns-mmlj2oj8/download' --output '.skill-downloads/commander-js-patterns-mmlj2oj8/SKILL.md.part' && mv '.skill-downloads/commander-js-patterns-mmlj2oj8/SKILL.md.part' '.skill-downloads/commander-js-patterns-mmlj2oj8/SKILL.md'2. Check prerequisites
Read SKILL.md before using it. If it references scripts or external services, inspect them and prepare the required access in your test environment.
Tools declared by the author (check availability in your agent): Read, Write, Bash, Edit
No recognized prerequisites section in this file. This does not mean it is self-contained: libraries, tools and access requirements may be mentioned elsewhere in the content or source repository.
The platforms on this page are catalog indications. The paths below follow tool documentation; they do not prove this skill has been run in those tools. No minimum tool version is confirmed for this listing.
3. Load the skill
This file does not provide a usable name/description header for this native procedure. It remains available to download and inspect; use the manual method below.
Manual method or another tool: attach SKILL.md to a conversation, or open it in an agent that can read files. Include any required supporting resources. No universal folder is recognized by every tool.
4. Try a first task
Use a short, synthetic input: an API endpoint, a small document or an interface brief. In a new conversation, attach the file or give the agent its path, then adapt this request:
Read .skill-downloads/commander-js-patterns-mmlj2oj8/SKILL.md and apply its instructions to this example: [describe a test input]. Identify any missing files, dependencies or access. Produce the result requested by the skill without inventing data or running unreviewed scripts.Expected result: output matching the skill instructions, or a precise list of missing prerequisites. A read confirmation alone does not validate a first use. If an external resource is unavailable, that path remains untested.
React Hook Form Best Practices
Development
Master React Hook Form: avoid anti-patterns, manage subscriptions, and handle reset, dirty state, and controlled inputs correctly.
Emotion to Mantine Migration
Development
Migrate Emotion styled-components to Mantine components with style props and CSS modules. Use when converting .styled.tsx files or removing @emotion imports.
Scope Creep Detector
Development
Analyzes git diffs against a stated intent to detect scope creep, unrelated files, broad PRs, and oversized changes, then suggests keep, split, or justify actions.