caporal vs commander vs minimist vs yargs
Command-Line Argument Parsing Libraries
caporalcommanderminimistyargsSimilar Packages:

Command-Line Argument Parsing Libraries

Command-line argument parsing libraries are essential tools in Node.js development, enabling developers to easily handle user inputs from the command line. These libraries provide functionalities to define commands, options, and arguments, making it simpler to build command-line interfaces (CLIs) for applications. They help streamline the process of capturing user input, validating it, and providing helpful feedback, ultimately enhancing the user experience and making applications more interactive and user-friendly.

Npm Package Weekly Downloads Trend

3 Years

Github Stars Ranking

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
caporal03,453-286 years agoMIT
commander028,171209 kB133 months agoMIT
minimist066254.5 kB143 years agoMIT
yargs011,481231 kB321a year agoMIT

Feature Comparison: caporal vs commander vs minimist vs yargs

Complexity and Features

  • caporal:

    Caporal offers a rich set of features, including support for subcommands, automatic help generation, and validation of argument types. It allows for complex command structures, making it suitable for larger applications that require detailed command management.

  • commander:

    Commander is designed to be simple and intuitive, focusing on the essentials of command-line parsing. It provides basic features like command definitions and option parsing without overwhelming the developer with complexity.

  • minimist:

    Minimist is extremely lightweight and focuses solely on parsing command-line arguments. It does not include features like help generation or command definitions, making it ideal for quick and straightforward applications.

  • yargs:

    Yargs provides a robust feature set, including support for command chaining, interactive prompts, and argument validation. It strikes a balance between complexity and usability, making it suitable for applications that need more than just basic parsing.

Ease of Use

  • caporal:

    Caporal's API is designed to be user-friendly, allowing developers to define commands and options in a clear and concise manner. Its built-in help generation simplifies the user experience, making it easy to understand available commands.

  • commander:

    Commander is known for its straightforward syntax, making it easy to get started with. Developers can quickly define commands and options without extensive boilerplate code, which is beneficial for rapid development.

  • minimist:

    Minimist is incredibly easy to use, requiring minimal setup to start parsing arguments. Its simplicity makes it a go-to choice for developers who need quick and effective argument parsing without additional features.

  • yargs:

    Yargs offers a user-friendly API that simplifies the process of defining commands and options. Its extensive documentation and examples make it easy for developers to implement and understand.

Documentation and Community Support

  • caporal:

    Caporal has good documentation that covers its features and usage. However, its community is smaller compared to some other libraries, which may limit the availability of third-party resources and support.

  • commander:

    Commander has extensive documentation and a large community of users, making it easy to find examples and solutions to common issues. This strong community support can be invaluable for developers seeking help.

  • minimist:

    Minimist has basic documentation that covers its core functionality. While it is widely used, the community support is not as extensive as some of the larger libraries, which may affect finding solutions for complex use cases.

  • yargs:

    Yargs boasts comprehensive documentation and a vibrant community. Its extensive resources, including tutorials and examples, make it easier for developers to learn and troubleshoot.

Performance

  • caporal:

    Caporal is optimized for performance, but its rich feature set may introduce some overhead compared to simpler libraries. It is suitable for applications where performance is important, but complexity is also a factor.

  • commander:

    Commander is lightweight and performs well, making it suitable for applications that require quick command parsing without significant overhead. Its simplicity contributes to its efficiency.

  • minimist:

    Minimist is extremely fast and efficient, making it ideal for applications where performance is critical. Its minimalistic approach ensures that there is little to no overhead in parsing arguments.

  • yargs:

    Yargs is designed to be performant, but its extensive feature set may introduce some overhead. It is suitable for applications that require a balance between performance and functionality.

Extensibility

  • caporal:

    Caporal is highly extensible, allowing developers to create custom commands and options easily. This flexibility makes it suitable for applications that may need to evolve over time with new features.

  • commander:

    Commander provides a straightforward way to extend functionality through custom commands and options, but it may not offer as much flexibility as more complex libraries.

  • minimist:

    Minimist is not designed for extensibility; it focuses solely on parsing arguments. It is best suited for applications that do not require additional features or customization.

  • yargs:

    Yargs excels in extensibility, allowing developers to create complex command structures and integrate additional functionalities seamlessly. This makes it a great choice for applications that need to grow and adapt.

How to Choose: caporal vs commander vs minimist vs yargs

  • caporal:

    Choose Caporal if you need a powerful and feature-rich CLI framework that supports command definitions, subcommands, and built-in help generation. It is ideal for applications that require complex command structures and extensive options.

  • commander:

    Opt for Commander if you prefer a straightforward and minimalist approach to building command-line applications. It is well-suited for simpler applications where you want to quickly define commands and options without the overhead of additional features.

  • minimist:

    Select Minimist if you need a lightweight solution for parsing command-line arguments without the need for additional features like command definitions or help generation. It is perfect for quick scripts or applications that require basic argument parsing.

  • yargs:

    Choose Yargs if you want a comprehensive solution that combines ease of use with powerful features like command chaining, argument validation, and interactive prompts. It is suitable for applications that require a balance between simplicity and functionality.

README for caporal

Travis Codacy grade Codacy coverage npm npm David GitHub stars GitHub forks

Caporal

A full-featured framework for building command line applications (cli) with node.js, including help generation, colored output, verbosity control, custom logger, coercion and casting, typos suggestions, and auto-complete for bash/zsh/fish.

Install

Simply add Caporal as a dependency:

$ npm install caporal

# Or if you are using yarn (https://yarnpkg.com/lang/en/)
$ yarn add caporal

Glossary

  • Program: a cli app that you can build using Caporal
  • Command: a command within your program. A program may have multiple commands.
  • Argument: a command may have one or more arguments passed after the command.
  • Options: a command may have one or more options passed after (or before) arguments.

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

Examples

#!/usr/bin/env node
const prog = require('caporal');
prog
  .version('1.0.0')
  // you specify arguments using .argument()
  // 'app' is required, 'env' is optional
  .command('deploy', 'Deploy an application')
  .argument('<app>', 'App to deploy', /^myapp|their-app$/)
  .argument('[env]', 'Environment to deploy on', /^dev|staging|production$/, 'local')
  // you specify options using .option()
  // if --tail is passed, its value is required
  .option('--tail <lines>', 'Tail <lines> lines of logs after deploy', prog.INT)
  .action(function(args, options, logger) {
    // args and options are objects
    // args = {"app": "myapp", "env": "production"}
    // options = {"tail" : 100}
  });

prog.parse(process.argv);

// ./myprog deploy myapp production --tail 100

Or else if you prefer typescript

#!/usr/bin/env node
import * as prog from 'caporal';
prog
  .version('1.0.0')
  // you specify arguments using .argument()
  // 'app' is required, 'env' is optional
  .command('deploy', 'Deploy an application')
  .argument('<app>', 'App to deploy', /^myapp|their-app$/)
  .argument('[env]', 'Environment to deploy on', /^dev|staging|production$/, 'local')
  // you specify options using .option()
  // if --tail is passed, its value is required
  .option('--tail <lines>', 'Tail <lines> lines of logs after deploy', prog.INT)
  .action(function(args, options, logger) {
    // args and options are objects
    // args = {"app": "myapp", "env": "production"}
    // options = {"tail" : 100}
  });

prog.parse(process.argv);

// ./myprog deploy myapp production --tail 100

Variadic arguments

You can use ... to indicate variadic arguments. In that case, the resulted value will be an array. Note: Only the last argument of a command can be variadic !

#!/usr/bin/env node
const prog = require('caporal');
prog
  .version('1.0.0')
  .command('deploy', 'Our deploy command')
  // 'app' and 'env' are required
  // and you can pass additional environments
  .argument('<app>', 'App to deploy')
  .argument('<env>', 'Environment')
  .argument('[other-env...]', 'Other environments')
  .action(function(args, options, logger) {
    console.log(args);
    // {
    //   "app": "myapp",
    //   "env": "production",
    //   "otherEnv": ["google", "azure"]
    // }
  });

prog.parse(process.argv);

// ./myprog deploy myapp production aws google azure

Simple program (single command)

For a very simple program with just one command, you can omit the .command() call:

#!/usr/bin/env node
const prog = require('caporal');
prog
  .version('1.0.0')
  .description('A simple program that says "biiiip"')
  .action(function(args, options, logger) {
    logger.info("biiiip")
  });

prog.parse(process.argv);

Programmatic Caporal usage

You can pass arguments and options directly to Caporal API.

#!/usr/bin/env node
const prog = require('caporal');
prog
  .version('1.0.0')
  .command('deploy', 'Our deploy command')
  .argument('<app>', 'App to deploy')
  .argument('<env>', 'Environment')
  .option('--how-much <amount>', 'How much app to deploy', prog.INT, 1)
  .action(function(args, options, logger) {
    logger.info(args);
    logger.info(options);
    // {
    //   "app": "myapp",
    //   "env": "production"
    // }
    // {
    //   "howMuch": 2
    // }
  });
prog.exec(['deploy', 'myapp', 'env'], {
  howMuch: 2
});

Logging

Inside your action(), use the logger argument (third one) to log informations.

#!/usr/bin/env node
const prog = require('caporal');
prog
  .version('1.0.0')
  .command('deploy', 'The deploy command')
  .action((args, options, logger) => {
    // Available methods:
    // - logger.debug('message')
    // - logger.info('message') or logger.log('level', 'message')
    // - logger.warn('message')
    // - logger.error('message')
    logger.info("Application deployed !");
  });

prog.parse(process.argv);

Logging levels

The default logging level is 'info'. The predefined options can be used to change the logging level:

  • -v, --verbose: Set the logging level to 'debug' so debug() logs will be output.
  • --quiet, --silent: Set the logging level to 'warn' so only warn() and error() logs will be output.

Custom logger

Caporal uses winston for logging. You can provide your own winston-compatible logger using .logger() the following way:

#!/usr/bin/env node
const prog = require('caporal');
const myLogger = require('/path/to/my/logger.js');
prog
  .version('1.0.0')
  .logger(myLogger)
  .command('foo', 'Foo command description')
  .action((args, options, logger) => {
    logger.info("Foo !!");
  });

prog.parse(process.argv);
  • -v, --verbose: Set the logging level to 'debug' so debug() logs will be output.
  • --quiet, --silent: Set the logging level to 'warn' so only warn() and error() logs will be output.

Coercion and casting using validators

You can apply coercion and casting using various validators:

Flag validator

  • INT (or INTEGER): Check option looks like an int and cast it with parseInt()
  • FLOAT: Will Check option looks like a float and cast it with parseFloat()
  • BOOL (or BOOLEAN): Check for string like 0, 1, true, false, on, off and cast it
  • LIST (or ARRAY): Transform input to array by splitting it on comma
  • REPEATABLE: Make the option repeatable, eg ./mycli -f foo -f bar -f joe
#!/usr/bin/env node
const prog = require('caporal');
prog
  .version('1.0.0')
  .command('order pizza')
  .option('--number <num>', 'Number of pizza', prog.INT, 1)
  .option('--kind <kind>', 'Kind of pizza', /^margherita|hawaiian$/)
  .option('--discount <amount>', 'Discount offer', prog.FLOAT)
  .option('--add-ingredients <ingredients>', 'Ingredients', prog.LIST)
  .action(function(args, options) {
    // options.kind = 'margherita'
    // options.number = 1
    // options.addIngredients = ['pepperoni', 'onion']
    // options.discount = 1.25
  });

prog.parse(process.argv);

// ./myprog order pizza --kind margherita --discount=1.25 --add-ingredients=pepperoni,onion
#!/usr/bin/env node
const prog = require('caporal');
prog
  .version('1.0.0')
  .command('concat') // concat files
  .option('-f <file>', 'File to concat', prog.REPEATABLE)
  .action(function(args, options) {

  });

prog.parse(process.argv);

// Usage:
// ./myprog concat -f file1.txt -f file2.txt -f file3.txt

Function validator

Using this method, you can check and cast user input. Make the check fail by throwing an Error, and cast input by returning a new value from your function.

#!/usr/bin/env node
const prog = require('caporal');
prog
  .version('1.0.0')
  .command('order pizza')
  .option('--kind <kind>', 'Kind of pizza', function(opt) {
    if (['margherita', 'hawaiian'].includes(opt) === false) {
      throw new Error("You can only order margherita or hawaiian pizza!");
    }
    return opt.toUpperCase();
  })
  .action(function(args, options) {
    // options = { "kind" : "MARGHERITA" }
  });

prog.parse(process.argv);

// ./myprog order pizza --kind margherita

Array validator

Using an Array, Caporal will check that it contains the argument/option passed.

Note: It is not possible to cast user input with this method, only checking it, so it's basically only interesting for strings, but a major advantage is that this method will allow autocompletion of arguments and option values.

#!/usr/bin/env node
const prog = require('caporal');
prog
  .version('1.0.0')
  .command('order pizza')
  .option('--kind <kind>', 'Kind of pizza', ["margherita", "hawaiian"])
  .action(function(args, options) {

  });

prog.parse(process.argv);

// ./myprog order pizza --kind margherita

RegExp validator

Simply pass a RegExp object to test against it. Note: It is not possible to cast user input with this method, only checking it, so it's basically only interesting for strings.

#!/usr/bin/env node
const prog = require('caporal');
prog
  .version('1.0.0')
  .command('order pizza')
  .option('--kind <kind>', 'Kind of pizza', /^margherita|hawaiian$/)
  .action(function(args, options) {

  });

prog.parse(process.argv);

// ./myprog order pizza --kind margherita

Colors

By default, Caporal will output colors for help and errors. This behaviour can be disabled by passing --no-color.

Auto-generated help

Caporal automatically generates help/usage instructions for you. Help can be displayed using -h or --help options, or with the default help command.

Custom help

You can add some custom help to the whole program or to specific commands using .help(text, options?). The text, even if multi-line, will be, optionally, automatically indented.

Multiple help sections, with custom names, are supported.

Custom help for the whole program

#!/usr/bin/env node
const prog = require('caporal');
prog
  .version('1.0.0')
  .help('my global help') // here our custom help for the whole program
  .command('order pizza')
  .action(function(args, options) {

  });

prog.parse(process.argv);

Custom help for specific commands

#!/usr/bin/env node
const prog = require('caporal');
prog
  .version('1.0.0')
  // first command
  .command('order')
  .help('my help for the order command') // here our custom help for the `order` command
  .action(function(args, options) {

  })
  // second command
  .command('cancel')
  .help('my help for the cancel command') // here our custom help for the `cancel` command
  .action(function(args, options) {

  })

prog.parse(process.argv);

Typo suggestions

Caporal will automatically make suggestions for option typos.

Shell auto-completion

Caporal comes with an auto-completion feature out of the box for bash, zsh, and fish, thanks to tabtab.

For this feature to work, you will have to:

  • Put your cli app in your $PATH (this is the case if your app is installed globally using npm install -g <myapp>)
  • Setup auto-completion for your shell, like bellow.

If you are using bash

# For bash
source <(myapp completion bash)

# or add it to your .bashrc to make it persist
echo "source <(myapp completion bash)" >> ~/.bashrc \
&& source ~/.bashrc

If you are using zsh

# For zsh
source <(myapp completion zsh)

# or add it to your .zshrc to make it persist
echo "source <(myapp completion zsh)" >> ~/.zshrc \
&& source ~/.zshrc

If you are using fish

# For fish
source <(myapp completion fish)

# or add it to your config.fish to make it persist
echo "source <(myapp completion fish)" >> ~/.config/fish/config.fish \
&& source ~/.config/fish/config.fish

Basic auto-completion

By default, it will autocomplete commands and option names. Also, options having an Array validator will be autocompleted.

Auto-completion setup example

#!/usr/bin/env node

const prog = require('caporal');

prog
  .version('1.0.0')
  // the "order" command
  .command('order', 'Order a pizza')
  .alias('give-it-to-me')
  // <kind> will be auto-magicaly autocompleted by providing the user with 3 choices
  .argument('<kind>', 'Kind of pizza', ["margherita", "hawaiian", "fredo"])
  .argument('<from-store>', 'Which store to order from')
  // enable auto-completion for <from-store> argument using a sync function returning an array
  .complete(function() {
    return ['store-1', 'store-2', 'store-3', 'store-4', 'store-5'];
  })

  .argument('<account>', 'Which account id to use')
  // enable auto-completion for <account> argument using a Promise
  .complete(function() {
    return Promise.resolve(['account-1', 'account-2']);
  })

  .option('-n, --number <num>', 'Number of pizza', prog.INT, 1)
  .option('-d, --discount <amount>', 'Discount offer', prog.FLOAT)
  .option('-p, --pay-by <mean>', 'Pay by option')
  // enable auto-completion for -p | --pay-by option using a Promise
  .complete(function() {
    return Promise.resolve(['cash', 'credit-card']);
  })

  // -e | --extra will be auto-magicaly autocompleted by providing the user with 3 choices
  .option('-e, --extra <ingredients>', 'Add extra ingredients', ['pepperoni', 'onion', 'cheese'])
  .action(function(args, options, logger) {
    logger.info("Command 'order' called with:");
    logger.info("arguments: %j", args);
    logger.info("options: %j", options);
  })

  // the "return" command
  .command('return', 'Return an order')
  .argument('<order-id>', 'Order id')
  // enable auto-completion for <order-id> argument using a Promise
  .complete(function() {
    return Promise.resolve(['#82792', '#71727', '#526Z52']);
  })
  .argument('<to-store>', 'Store id')
  .option('--ask-change <other-kind-pizza>', 'Ask for other kind of pizza')
  // enable auto-completion for --ask-change option using a Promise
  .complete(function() {
    return Promise.resolve(["margherita", "hawaiian", "fredo"]);
  })
  .option('--say-something <something>', 'Say something to the manager')
  .action(function(args, options, logger) {
    logger.info("Command 'return' called with:");
    logger.info("arguments: %j", args);
    logger.info("options: %j", options);
  });

prog.parse(process.argv);

API

require('caporal')

Returns a Program instance.

Program API

.version(version) : Program

Set the version of your program. You may want to use your package.json version to fill it:

const myProgVersion = require('./package.json').version;
const prog = require('caporal');
prog
  .version(myProgVersion)
// [...]

prog.parse(process.argv);

Your program will then automaticaly handle -V and --version options:

matt@mb:~$ ./my-program --version
1.0.0

.help(text, options?) : Program

Add a program-level help section.

By default the optional options parameter is:

{
    indent: true, // If `true` the text will be automatically indented
    name: "MORE INFO" // The name of the section
}

.command(name, description) -> Command

Set up a new command with name and description. Multiple commands can be added to one program. Returns a {Command}.

const prog = require('caporal');
prog
  .version('1.0.0')
  // one command
  .command('walk', 'Make the player walk')
  .action((args, options, logger) => { logger.log("I'm walking !")}) // you must attach an action for your command
  // a second command
  .command('run', 'Make the player run')
  .action((args, options, logger) => { logger.log("I'm running !")})
  // a command may have multiple words
  .command('cook pizza', 'Make the player cook a pizza')
  .argument('<kind>', 'Kind of pizza')
  .action((args, options, logger) => { logger.log("I'm cooking a pizza !")})
// [...]

prog.parse(process.argv);

.logger([logger]) -> Program | winston

Get or set the logger instance. Without argument, it returns the logger instance (winston by default). With the logger argument, it sets a new logger.

Command API

.argument(synopsis, description, [validator, [defaultValue]]) -> Command

Add an argument to the command. Can be called multiple times to add several arguments.

  • synopsis (String): something like <my-required-arg> or [my-optional-arg]
  • description (String): argument description
  • validator (Caporal Flag | Function | Array | RegExp): optional validator, see Coercion and casting
  • defaultValue (*): optional default value

.option(synopsis, description, [validator, [defaultValue, [required]]) -> Command

Add an option to the command. Can be called multiple times to add several options.

  • synopsis (String): You can pass short or long notation here, or both. See examples.
  • description (String): option description
  • validator (Caporal Flag | Function | Array | RegExp): optional validator, see Coercion and casting
  • defaultValue (*): optional default value
  • required (Bool): Is the option itself required ? Default to false

.help(text, options?) -> Command

Add a command-level help section.

By default the optional options parameter is:

{
    indent: true, // If `true` the text will be automatically indented
    name: "" // The name of the section, by default this line won't be displayed
}

.action(action) -> Command

Define the action, e.g a Function, for the current command.

The action callback will be called with 3 arguments:

  • args (Object): Passed arguments
  • options (Object): Passed options
  • logger (winston): Winston logger instance
// sync action
const prog = require('caporal');
prog
  .version('1.0.0')
  .command('walk', 'Make the player walk')
  .action((args, options, logger) => {
    logger.log("I'm walking !")
  });

You can make your actions async by using Promises:

// async action
const prog = require('caporal');
prog
  .version('1.0.0')
  .command('walk', 'Make the player walk')
  .action((args, options, logger) => {
    return new Promise(/* ... */);
  });

.alias(alias) -> Command

Define an alias for the current command. A command can only have one alias.

const prog = require('caporal');
prog
  .version('1.0.0')
  // one command
  .command('walk', 'Make the player walk')
  .alias('w')
  .action((args, options, logger) => { logger.log("I'm walking !")});

prog.parse(process.argv);

// ./myapp w
// same as
// ./myapp walk

.complete(completer) -> Command

Define an auto-completion handler for the latest argument or option added to the command.

  • completer (Function): The completer function has to return either an Array or a Promise which resolves to an Array.

.visible(visibility?) -> Boolean | Command

Get or set the visibility value of this command. By default it's true, if you set it to false it will be omitted from the help message.

const prog = require('caporal');
prog
  .version('1.0.0')
  // one command
  .command('walk', 'Make the player walk')
  .visible ( false )

prog.parse(process.argv);

Credits

Caporal is strongly inspired by commander.js and Symfony Console. Caporal makes use of the following npm packages:

License

Copyright © Matthias ETIENNE

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

The Software is provided “as is”, without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the software or the use or other dealings in the Software.