CAC CLI Framework
CAC (Command And Conquer) is a lightweight, dependency-free JavaScript library for building robust command-line interface (CLI) applications. The current stable version, 7.0.0, released in 2024, marks a significant transition to being ESM-only and requires Node.js 20.19.0 or newer. CAC differentiates itself by providing a minimal API surface (four core methods for basic CLIs) while offering powerful features such as default commands, Git-like subcommands, argument and option validation, variadic arguments, and automated help message generation. Its development is TypeScript-first, ensuring type safety and an enhanced developer experience. Release cadence is typically feature-driven, with breaking changes carefully documented in major version bumps and minor/patch releases focusing on stability and compatibility.
Common errors
-
Error [ERR_REQUIRE_ESM]: require() of ES Module .../node_modules/cac/dist/index.mjs from .../your-script.js not supported.
cause Attempting to use `require('cac')` in a CommonJS context after v7.0.0 when CAC is an ESM-only package.fixConvert your script to an ES module by using `import cac from 'cac'` and ensuring your project's `package.json` has `"type": "module"` or your file has a `.mjs` extension. -
TypeError: cli.on is not a function
cause Using the deprecated `cli.on()` method after upgrading to CAC v7.0.0 or later.fixRename `cli.on()` to `cli.addEventListener()` everywhere in your code. Similarly, replace `cli.once()` with `cli.addOnceListener()` and `cli.off()` with `cli.removeEventListener()`. -
Error: Node.js version 18.x.x is not supported by CAC. Minimum required version is 20.19.0.
cause Running a CAC v7.0.0+ application on an unsupported Node.js version.fixUpdate your Node.js environment to version 20.19.0 or higher. You can use tools like `nvm use 20` or `volta install node@20`.
Warnings
- breaking CAC v7.0.0 and above now requires Node.js 20.19.0 or a higher version. Running on older Node.js versions will result in runtime errors.
- breaking CAC is now an ESM-only package since v7.0.0. The CommonJS (CJS) build has been removed, meaning `require()` statements will no longer work directly for importing `cac`.
- breaking The event listener methods `cli.on()`, `cli.once()`, and `cli.off()` have been renamed to `cli.addEventListener()`, `cli.addOnceListener()`, and `cli.removeEventListener()`, respectively, to align with the standard `EventTarget` API.
- gotcha CAC automatically converts kebab-case option names (e.g., `--clear-screen`) to camelCase (e.g., `options.clearScreen`) in the parsed options object. Be consistent in how you access these options.
- gotcha Command-specific options are validated only if an `action` function is defined for that command. If a command has options but no `action`, unknown options will not trigger a validation error unless `command.allowUnknownOptions()` is explicitly set.
Install
-
npm install cac -
yarn add cac -
pnpm add cac
Imports
- cac
const cac = require('cac')import cac from 'cac'
- CAC
import type { CAC } from 'cac' - cli.addEventListener
cli.on('command:name', () => {})cli.addEventListener('command:name', () => {})
Quickstart
import cac from 'cac'
const cli = cac()
cli.option('--type [type]', 'Choose a project type', {
default: 'node',
})
cli.option('--name <name>', 'Provide your name')
cli.command('lint [...files]', 'Lint files').action((files, options) => {
console.log(`Linting files: ${files.join(', ')} with options: ${JSON.stringify(options)}`)
})
// Display help message when `-h` or `--help` appears
cli.help()
// Display version number when `-v` or `--version` appears
cli.version('1.0.0') // Set your CLI's version
try {
cli.parse()
} catch (error) {
// Handle errors like unknown commands or options
console.error(`CLI Error: ${error.message}`)
process.exit(1)
}
// To run this: save as e.g. cli.mjs and execute with `node cli.mjs --help` or `node cli.mjs lint src/*.js`