Parse command line arguments in Node.js

There are many libraries to build CLI tools for Node.js like optimist, minimist, yargs, Caporal.js and commander to name just a few.

My favorite one is commander because it comes with TypeScript definitions:

commander-example.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/usr/bin/env node

import program from 'commander';

const pkg = require('../package.json');
const appName = Object.keys(pkg.bin)[0];

program
.description(pkg.description)
.name(appName)
.option('-c, --config <path>', 'set path to configuration file')
.version(pkg.version)
.parse(process.argv);

console.log('Configuration path', program.config);

Biggest lack on commander.js is that it does not fail if you have mandatory arguments but don’t supply any argument at all. For example it fails when calling node program.js -c because there is no value for c but it doesn’t fail when just calling node program.js. Tested with commander v2.19.0. GitHub issue.

Luckily, Caporal.js addresses this issue:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/usr/bin/env node

import program from 'caporal';

const pkg = require('../package.json');
const appName = Object.keys(pkg.bin)[0];

program
.version(pkg.version)
.description(pkg.description)
.name(appName)
.option('--config <config>', 'set path to configuration file', undefined, undefined, true)
.action((args, options, logger) => {
logger.info(`Configuration value: ${options.config}`);
});

program.parse(process.argv);

Error: Missing option –config

Should you just care about getting arguments in an easy way, you will be good with minimist:

1
2
3
4
import * as minimist from 'minimist';

const argv = minimist(process.argv.slice(1));
console.log(argv.mySpecialFlag);

Extras

If you want to equip your program with some kind of configuration file (à la webpack.config.js or .babelrc) I can recommend cosmiconfig to you. Cosmiconfig searches for and loads configuration files with the extensions .json, .yaml, .yml, or .js.

And if you need pattern matching you will probably fall in love with Globs which are implemened by minimatch.

If you need an interactive command line user interface with prompts, try Inquirer.js.

And for more colorful log messages on the terminal, there is chalk.