Commandpost CLI Parser
Commandpost is a command-line option parser library for Node.js, designed with a strong emphasis on TypeScript developer experience while remaining fully compatible with JavaScript projects. It provides a structured, chainable API for defining root commands, sub-commands, various types of options (e.g., flags, parameters), and arguments (required, optional, variadic). Inspired by the popular `commander` library, Commandpost differentiates itself by addressing `commander`'s limitations regarding robust TypeScript type inference and usage, offering a more type-safe approach to CLI development. The current stable version is 1.4.0, with releases historically following an irregular cadence based on community contributions and author availability, rather than fixed schedules. Key features include automatic help message generation, versioning, and descriptive capabilities for commands and options. Its core strength lies in enabling developers to build type-safe CLI applications with a familiar, fluid API.
Common errors
-
error: unknown option '--foo'
cause An unrecognized command-line option was passed that was not explicitly defined using `.option()` on the current command or its ancestors.fixDefine the option using `.option('-f, --foo', 'Description')` on your command, or explicitly allow unknown options by calling `.allowUnknownOption()` on the command definition. -
error: missing required argument <argument_name>
cause A command was invoked without providing a required argument that was defined in its signature (e.g., `commandpost.create('cmd <arg>')`).fixEnsure all required arguments are provided on the command line when executing. For example, if `<food>` is required, invoke as `cli.js <food_value>`. -
TypeError: commandpost.create is not a function
cause The `commandpost` library was imported incorrectly, leading to the `create` function not being accessible on the imported object. This commonly occurs with incorrect named imports or using `require` when `import * as` is expected.fixFor TypeScript and ESM, use `import * as commandpost from 'commandpost';`. If strictly using CommonJS, ensure `const commandpost = require('commandpost');` is used, and functions are called as `commandpost.create()`.
Warnings
- gotcha Options defined with a parameter (e.g., `-s, --spice <name>`) are typed as a string array (`string[]`) by default, even if only a single value is expected. This is due to how variadic parameters are handled.
- gotcha Users migrating from `commander` may encounter subtle API differences or different type inference behaviors, as `commandpost` prioritizes TypeScript-friendliness over strict API parity with `commander`.
- gotcha Unhandled errors during command execution can lead to abrupt process termination. The `exec` method returns a Promise, which should be caught to handle parsing errors or exceptions thrown within your command actions gracefully.
Install
-
npm install commandpost -
yarn add commandpost -
pnpm add commandpost
Imports
- create
import { create } from 'commandpost'; // Incorrect: 'create' is not a named exportimport * as commandpost from 'commandpost'; commandpost.create(...)
- exec
import { exec } from 'commandpost'; // Incorrect: 'exec' is not a named exportimport * as commandpost from 'commandpost'; commandpost.exec(root, process.argv)
- commandpost
const commandpost = require('commandpost'); // CommonJS importimport * as commandpost from 'commandpost';
Quickstart
import * as commandpost from 'commandpost';
let root = commandpost
.create<{ spice: string[]; }, { food: string; }>( "dinner <food>")
.version("1.0.0", "-v, --version")
.description("today's dinner!")
.option("-s, --spice <name>", "What spice do you want? default: pepper")
.action((opts, args) => {
console.log(`Your dinner is ${args.food} with ${opts.spice[0] || "pepper"}!`);
});
commandpost
.exec(root, process.argv)
.catch(err => {
if (err instanceof Error) {
console.error(err.stack);
} else {
console.error(err);
}
process.exit(1);
});