Are you happy with your logging solution? Would you help us out by taking a 30-second survey? Click here

commander.js

node.js command-line interfaces made easy

Subscribe to updates I use commander.js


Statistics on commander.js

Number of watchers on Github 10382
Number of open issues 227
Average time to close an issue about 1 month
Main language JavaScript
Average time to merge a PR 5 days
Open pull requests 88+
Closed pull requests 33+
Last commit over 1 year ago
Repo Created about 8 years ago
Repo Last Updated over 1 year ago
Size 491 KB
Organization / Authortj
Latest Releasev2.15.0
Contributors67
Page Updated
Do you use commander.js? Leave a review!
View open issues (227)
View commander.js activity
View on github
Fresh, new opensource launches 🚀🚀🚀
Trendy new open source projects in your inbox! View examples

Subscribe to our mailing list

Evaluating commander.js for your project? Score Explanation
Commits Score (?)
Issues & PR Score (?)

Commander.js

Build Status NPM Version NPM Downloads Join the chat at https://gitter.im/tj/commander.js

The complete solution for node.js command-line interfaces, inspired by Ruby's commander.
API documentation

Installation

$ npm install commander --save

Option parsing

Options with commander are defined with the .option() method, also serving as documentation for the options. The example below parses args and options from process.argv, leaving remaining args as the program.args array which were not consumed by options.

#!/usr/bin/env node

/**
 * Module dependencies.
 */

var program = require('commander');

program
  .version('0.1.0')
  .option('-p, --peppers', 'Add peppers')
  .option('-P, --pineapple', 'Add pineapple')
  .option('-b, --bbq-sauce', 'Add bbq sauce')
  .option('-c, --cheese [type]', 'Add the specified type of cheese [marble]', 'marble')
  .parse(process.argv);

console.log('you ordered a pizza with:');
if (program.peppers) console.log('  - peppers');
if (program.pineapple) console.log('  - pineapple');
if (program.bbqSauce) console.log('  - bbq');
console.log('  - %s cheese', program.cheese);

Short flags may be passed as a single arg, for example -abc is equivalent to -a -b -c. Multi-word options such as --template-engine are camel-cased, becoming program.templateEngine etc.

Note that multi-word options starting with --no prefix negate the boolean value of the following word. For example, --no-sauce sets the value of program.sauce to false.

#!/usr/bin/env node

/**
 * Module dependencies.
 */

var program = require('commander');

program
  .option('--no-sauce', 'Remove sauce')
  .parse(process.argv);

console.log('you ordered a pizza');
if (program.sauce) console.log('  with sauce');
else console.log(' without sauce');

Version option

Calling the version implicitly adds the -V and --version options to the command. When either of these options is present, the command prints the version number and exits.

$ ./examples/pizza -V
0.0.1

If you want your program to respond to the -v option instead of the -V option, simply pass custom flags to the version method using the same syntax as the option method.

program
  .version('0.0.1', '-v, --version')

The version flags can be named anything, but the long option is required.

Command-specific options

You can attach options to a command.

#!/usr/bin/env node

var program = require('commander');

program
  .command('rm <dir>')
  .option('-r, --recursive', 'Remove recursively')
  .action(function (dir, cmd) {
    console.log('remove ' + dir + (cmd.recursive ? ' recursively' : ''))
  })

program.parse(process.argv)

A command's options are validated when the command is used. Any unknown options will be reported as an error. However, if an action-based command does not define an action, then the options are not validated.

Coercion

function range(val) {
  return val.split('..').map(Number);
}

function list(val) {
  return val.split(',');
}

function collect(val, memo) {
  memo.push(val);
  return memo;
}

function increaseVerbosity(v, total) {
  return total + 1;
}

program
  .version('0.1.0')
  .usage('[options] <file ...>')
  .option('-i, --integer <n>', 'An integer argument', parseInt)
  .option('-f, --float <n>', 'A float argument', parseFloat)
  .option('-r, --range <a>..<b>', 'A range', range)
  .option('-l, --list <items>', 'A list', list)
  .option('-o, --optional [value]', 'An optional value')
  .option('-c, --collect [value]', 'A repeatable value', collect, [])
  .option('-v, --verbose', 'A value that can be increased', increaseVerbosity, 0)
  .parse(process.argv);

console.log(' int: %j', program.integer);
console.log(' float: %j', program.float);
console.log(' optional: %j', program.optional);
program.range = program.range || [];
console.log(' range: %j..%j', program.range[0], program.range[1]);
console.log(' list: %j', program.list);
console.log(' collect: %j', program.collect);
console.log(' verbosity: %j', program.verbose);
console.log(' args: %j', program.args);

Regular Expression

program
  .version('0.1.0')
  .option('-s --size <size>', 'Pizza size', /^(large|medium|small)$/i, 'medium')
  .option('-d --drink [drink]', 'Drink', /^(coke|pepsi|izze)$/i)
  .parse(process.argv);

console.log(' size: %j', program.size);
console.log(' drink: %j', program.drink);

Variadic arguments

The last argument of a command can be variadic, and only the last argument. To make an argument variadic you have to append ... to the argument name. Here is an example:

#!/usr/bin/env node

/**
 * Module dependencies.
 */

var program = require('commander');

program
  .version('0.1.0')
  .command('rmdir <dir> [otherDirs...]')
  .action(function (dir, otherDirs) {
    console.log('rmdir %s', dir);
    if (otherDirs) {
      otherDirs.forEach(function (oDir) {
        console.log('rmdir %s', oDir);
      });
    }
  });

program.parse(process.argv);

An Array is used for the value of a variadic argument. This applies to program.args as well as the argument passed to your action as demonstrated above.

Specify the argument syntax

#!/usr/bin/env node

var program = require('commander');

program
  .version('0.1.0')
  .arguments('<cmd> [env]')
  .action(function (cmd, env) {
     cmdValue = cmd;
     envValue = env;
  });

program.parse(process.argv);

if (typeof cmdValue === 'undefined') {
   console.error('no command given!');
   process.exit(1);
}
console.log('command:', cmdValue);
console.log('environment:', envValue || "no environment given");

Angled brackets (e.g. <cmd>) indicate required input. Square brackets (e.g. [env]) indicate optional input.

Git-style sub-commands

// file: ./examples/pm
var program = require('commander');

program
  .version('0.1.0')
  .command('install [name]', 'install one or more packages')
  .command('search [query]', 'search with optional query')
  .command('list', 'list packages installed', {isDefault: true})
  .parse(process.argv);

When .command() is invoked with a description argument, no .action(callback) should be called to handle sub-commands, otherwise there will be an error. This tells commander that you're going to use separate executables for sub-commands, much like git(1) and other popular tools.
The commander will try to search the executables in the directory of the entry script (like ./examples/pm) with the name program-command, like pm-install, pm-search.

Options can be passed with the call to .command(). Specifying true for opts.noHelp will remove the option from the generated help output. Specifying true for opts.isDefault will run the subcommand if no other subcommand is specified.

If the program is designed to be installed globally, make sure the executables have proper modes, like 755.

--harmony

You can enable --harmony option in two ways:

  • Use #! /usr/bin/env node --harmony in the sub-commands scripts. Note some os version dont support this pattern.
  • Use the --harmony option when call the command, like node --harmony examples/pm publish. The --harmony option will be preserved when spawning sub-command process.

Automated --help

The help information is auto-generated based on the information commander already knows about your program, so the following --help info is for free:

 $ ./examples/pizza --help

   Usage: pizza [options]

   An application for pizzas ordering

   Options:

     -h, --help           output usage information
     -V, --version        output the version number
     -p, --peppers        Add peppers
     -P, --pineapple      Add pineapple
     -b, --bbq            Add bbq sauce
     -c, --cheese <type>  Add the specified type of cheese [marble]
     -C, --no-cheese      You do not want any cheese

Custom help

You can display arbitrary -h, --help information by listening for --help. Commander will automatically exit once you are done so that the remainder of your program does not execute causing undesired behaviours, for example in the following executable stuff will not output when --help is used.

#!/usr/bin/env node

/**
 * Module dependencies.
 */

var program = require('commander');

program
  .version('0.1.0')
  .option('-f, --foo', 'enable some foo')
  .option('-b, --bar', 'enable some bar')
  .option('-B, --baz', 'enable some baz');

// must be before .parse() since
// node's emit() is immediate

program.on('--help', function(){
  console.log('  Examples:');
  console.log('');
  console.log('    $ custom-help --help');
  console.log('    $ custom-help -h');
  console.log('');
});

program.parse(process.argv);

console.log('stuff');

Yields the following help output when node script-name.js -h or node script-name.js --help are run:


Usage: custom-help [options]

Options:

  -h, --help     output usage information
  -V, --version  output the version number
  -f, --foo      enable some foo
  -b, --bar      enable some bar
  -B, --baz      enable some baz

Examples:

  $ custom-help --help
  $ custom-help -h

.outputHelp(cb)

Output help information without exiting. Optional callback cb allows post-processing of help text before it is displayed.

If you want to display help by default (e.g. if no command was provided), you can use something like:

var program = require('commander');
var colors = require('colors');

program
  .version('0.1.0')
  .command('getstream [url]', 'get stream URL')
  .parse(process.argv);

if (!process.argv.slice(2).length) {
  program.outputHelp(make_red);
}

function make_red(txt) {
  return colors.red(txt); //display the help text in red on the console
}

.help(cb)

Output help information and exit immediately. Optional callback cb allows post-processing of help text before it is displayed.

Examples

var program = require('commander');

program
  .version('0.1.0')
  .option('-C, --chdir <path>', 'change the working directory')
  .option('-c, --config <path>', 'set config path. defaults to ./deploy.conf')
  .option('-T, --no-tests', 'ignore test hook');

program
  .command('setup [env]')
  .description('run setup commands for all envs')
  .option("-s, --setup_mode [mode]", "Which setup mode to use")
  .action(function(env, options){
    var mode = options.setup_mode || "normal";
    env = env || 'all';
    console.log('setup for %s env(s) with %s mode', env, mode);
  });

program
  .command('exec <cmd>')
  .alias('ex')
  .description('execute the given remote cmd')
  .option("-e, --exec_mode <mode>", "Which exec mode to use")
  .action(function(cmd, options){
    console.log('exec "%s" using %s mode', cmd, options.exec_mode);
  }).on('--help', function() {
    console.log('  Examples:');
    console.log();
    console.log('    $ deploy exec sequential');
    console.log('    $ deploy exec async');
    console.log();
  });

program
  .command('*')
  .action(function(env){
    console.log('deploying "%s"', env);
  });

program.parse(process.argv);

More Demos can be found in the examples directory.

License

MIT

commander.js open issues Ask a question     (View All Issues)
  • almost 3 years customFds option for child_process.spawn is deprecated
  • almost 3 years program.opts() can be overridden by an option
  • almost 3 years Literal args have unexpected results when using commands (with args)
  • almost 3 years Possible EventEmitter memory leak detected
  • almost 3 years Examples not working
  • almost 3 years Format help descriptions that are too long
  • almost 3 years Option to prefix help with text
  • almost 3 years Make calls to process.exit() overridable
  • almost 3 years Defining boolean options via Command#option() defaults to undefined, not false.
  • almost 3 years Add support for variadic args on options
  • almost 3 years Reason about using tilde operator in Option constructor?
  • almost 3 years new npm release?
  • almost 3 years How do I parse arguments in subcommands?
  • almost 3 years Is it possible to avoid to prefix the name of the file in the usage of the subcommand ?
  • about 3 years How to get options from sub command exes
  • about 3 years When arguments() argument is provided, unrecognized flags are silently deleted (no error prints)
  • about 3 years Add support for -v to get the version
  • about 3 years Node flags not passed spawned process on win32
  • about 3 years Problem with version option
  • about 3 years Is there a way to get the string value rather than bool value without specifying <type>?
  • about 3 years Command log + option log
  • about 3 years Cannot pass more than 4 arguments in literal mode
  • about 3 years How to get prompt working...
  • about 3 years Command#version() is not in the API documentation
  • about 3 years Show help if mandatory arguments not used
  • about 3 years program.args swallowed if no options
  • about 3 years Crappy Benchmark for fun
  • about 3 years Hiding auto generated help options?
  • about 3 years My options seem to be undefined
  • over 3 years Max length of help output?
commander.js open pull requests (View All Pulls)
  • For a required option, when even option flag is not given throw error.
  • Add public `reset` method to enable multiple calls to `parse`.
  • Add 'Other modules' section to Readme.md
  • Prefix events to prevent conflicts between commands and options
  • support multi-alias, and seperator in help information
  • Support option aliases
  • Fail when using same command and alias
  • colors, l10n, args details
  • Make return of the `parse` api consistent.
  • Automatically check for missing required options
  • Use fork for explicit js.
  • Fixed #37, --help should not display first
  • Explicitly return from error methods
  • Add support for exit codes.
  • Default value not set on function options
  • Executable Arguments on win32
  • add optional callback parameter in parse method
  • killing the subcommand if the main command is terminated
  • Parse arguments even without 'action'.
  • Issue #255: don't append padding arguments to the end of the list
  • Add support for coffeescript subcommands using explicit .coffee extension
  • Completed nested command support.
  • Add fallback to local git-style subcommand
  • add largestCommandLength method
  • if the action not exist, do not emit the action event
  • Clean up help screen
  • Fix for passing ssh private key to argument
  • Commands now work with files ending in .js, and usage information is more pretty
  • Chaining in a loop
  • Adds an option's default value to the help output
  • Add API-Doc to http://doclets.io
  • #330 make .option defaultValue and fn and .version flag optional
  • added fix for issue 483 to parseOptions
  • Data overload
  • The unknownOption method is now called with the array of unknown options...
  • Allow literal '--' to be passed-through as an argument
  • Fix help section order and padding
  • link build badge to master branch
  • link build badge to master branch
  • added .js extension to the command file path if it doesn't have already
  • Support the alias of Git style sub-command
  • Add a prefix to the event name of OptionClass
  • use current node
  • Update Readme_zh-CN.md
  • possible bug: first literal after '--' is eaten
  • allow to customize default version desc
  • Make process.exit() injectable.
  • #540 fix with sync write in stdout
  • Fix translation errors.
  • implement ability to use negative numbers as option values
  • Add missing semi colon in readme
  • node v6 travis test
  • Adding support for required arguments.
  • #395 fix, short options do not understand adjacent values
  • Resolve symlinks recursively; Fix #588
  • Add save param to npm install
  • Sorted by name in commandHelp
  • Added color output of main command
  • On SemVer you do not start from 0.0.1
  • Inherit arguments to default subcommand
  • Pass un-normalized unknown options to sub-commands
  • add executable arguments to spawn in win32
  • Fix require arguments in README.md
  • Chainable name setter
  • Fixing git style subcommands on Windows & allowing subcommands to come from dependency modules
  • feature: support for signals to subcommands
  • Fix Coercion for Repeated Options
  • WIP resolves #649 switch to a modern test infrastructure
  • resolves #560 respect custom name for version option
  • resolves #749 pass extra args as final argument of action callback
  • resolves #741 make indentation configurable
  • resolves #739 add parent command as prefix of subcommand
  • Restore arguments order to pass to subcommands
  • Fix for #561 Issue
  • Fixes issue #727: Passing empty string for option on command is set to undefined
  • In help display sort commands alphabetically
  • Arguments description
  • allow "-" hyphen as an option argument with subcommand
  • Fix option parsing with sub-commands.
  • WIP: Support for multiple option arguments.
  • Fix options key name conflict with commander object's' key
  • Properly handle subcommands with no args
  • [WIP] Modernize codebase to ES6
  • fix help option text for user-defined -h short flags
  • Pass unknown also as a second argument to the command:* event
  • Fix to emit the action even without command
  • added ability to translate help output
  • resolves #766 suggest to users run --help command
commander.js questions on Stackoverflow (View All Questions)
  • Commander.js collect multiple options always include default
  • Cannot pass an option to a command in commander.js
  • commander.js : how to specify required cli argument
  • commander.js - .prompt removed, now what?
  • commander.js not parsing input
  • commander.js integration test for CLI
  • Unnamed parameter with commander.js
  • using commander.js in node for command line apps?
  • Commander.js : script not waiting for user input
commander.js list of languages used
commander.js latest release notes
v2.15.0 v2.15.0
  • Update downloads badge to point to graph of downloads over time instead of duplicating link to npm
  • Arguments description
v2.14.1 v2.14.1
  • Fix typing of help function
v2.14.0 v2.14.0
  • only register the option:version event once
  • Fixes issue #727: Passing empty string for option on command is set to undefined
  • enable eqeqeq rule
  • resolves #754 add linter configuration to project
  • resolves #560 respect custom name for version option
  • document how to override the version flag
  • document using options per command
Other projects in JavaScript