Command-line queen.
Last updated 8 days ago by rem .
MIT · Repository · Original npm · Tarball
$ cnpm install cac 
SYNC missed versions from official npm registry.
2017-07-26 9 27 05

NPM version NPM downloads CircleCI donate chat


Command And Conquer, the queen living in your command line, is a minimalistic but pluggable CLI framework.


yarn add cac

Table of contents


Use ./examples/simple.js as example:

const cac = require('cac')

const cli = cac()

// Add a default command
const defaultCommand = cli.command('*', {
  desc: 'The default command'
}, (input, flags) => {
  if (flags.age) {
    console.log(`${input[0]} is ${flags.age} years old`)

defaultCommand.option('age', {
  desc: 'tell me the age'

// Add a sub command
cli.command('bob', {
  desc: 'Command for bob'
}, () => {
  console.log('This is a command dedicated to bob!')

// Bootstrap the CLI app

Then run it:

2017-07-26 2 29 46

And the Help Documentation is ready out of the box:

2017-07-26 4 29 36


Projects that use CAC:

  • SAO: ⚔️ Futuristic scaffolding tool.
  • Poi: ⚡️ Delightful web development.
  • bili: ???? Schweizer Armeemesser for bundling JavaScript libraries.
  • lass: ???????? Scaffold a modern package boilerplate for Node.js.
  • Feel free to add yours here...


cli.option(name, [option])

Register an option globally, i.e. for all commands

  • name: string option name
  • option: object string
    • desc: string description
    • alias: string Array<string> option name alias
    • type: string option type, valid values: boolean string
    • default: any option default value
    • required: boolean mark option as required
    • choices: Array<any> limit valid values for the option

cli.command(name, [option], [handler])

  • name: string
  • option: object string (string is used as desc)
    • desc: string description
    • alias: string Array<string> command name alias
    • examples: Array<string> command examples
    • match: (name: string) => boolean A custom command matcher
  • handler: function command handler
    • input: Array<string> cli arguments
    • flags: object cli flags
const command = cli.command('init', 'init a new project', (input, flags) => {
  const folderName = input[0]
  console.log(`init project in folder ${folderName}`)

cli.command returns a command instance.


command.option(name, [option])

Same as cli.option but it adds options for specified command.

cli.parse([argv], [option])

  • argv: Array<string> Defaults to process.argv.slice(2)
  • option
    • run: boolean Defaults to true Run command after parsed argv.


Display cli helps, must be called after cli.parse()


  • plugin: Plugin Array<Plugin>

Apply a plugin to cli instance:


function plugin(options) {
  return cli => {
    // do something...


Type: string

The filename of executed file.

e.g. It's cli.js when you run node ./cli.js.


A getter which simply returns cli.parse(null, { run: false })


Add extra help messages to the bottom of help.


Type: string object

The help could be a string or in { title, body } format.



Error handler for errors in your command handler:

cli.on('error', err => {
  console.error('command failed:', err)


Emit after CAC parsed cli arguments:

cli.on('parsed', (command, input, flags) => {
  // command might be undefined


Emit after CAC executed commands or outputed help / version number:

cli.on('executed', (command, input, flags) => {
  // command might be undefined


Why not commander.js yargs caporal.js or meow ?

CAC is simpler and less opinionated comparing to commander.js yargs caporal.js.

Commander.js does not support chaining option which is a feature I like a lot. It's not really actively maintained at the time of writing either.

Yargs has a powerful API, but it's so massive that my brain trembles. Meow is simple and elegant but I have to manully construct the help message, which will be annoying. And I want it to support sub-command too.

And none of them are pluggable.

So why creating a new thing instead of pull request?

I would ask me myself why there's preact instead of PR to react, and why yarn instead of PR to npm? It's obvious.

CAC is kind of like a combination of the simplicity of Meow and the powerful features of the rest. And our help log is inspired by Caporal.js, I guess it might be the most elegant one out there?


How is the name written and pronounced?

CAC, not Cac or cac, pronounced C-A-C.

And this project is dedicated to our lovely C.C. sama. Maybe CAC stands for C&C as well :P


  1. Fork it!
  2. Create your feature branch: git checkout -b my-new-feature
  3. Commit your changes: git commit -am 'Add some feature'
  4. Push to the branch: git push origin my-new-feature
  5. Submit a pull request :D


cac © egoist, Released under the MIT License.
Authored and maintained by egoist with help from contributors (list). · GitHub @egoist · Twitter @_egoistlily

Copyright 2014 - 2017 © |