Getting started
Welcome aboard!
Caporal is a full-featured framework for building awesome command-line applications with Node.js. This getting started guide will help you learn the basics in a few minutes.
For Caporal 1.x users, be sure to checkout the migration guide.
Install
Simply add @caporal/core
as a dependency.
npm install @caporal/core
Glossary
We will refer to the following expressions within this guide:
- Program: a program/app built with Caporal.
- Command: a command within your program. A program can have multiple commands.
- Action: each command has an associated action run when executing the command.
- Argument: a command can have one or more arguments passed after the command.
- Options: Short and long options like
-f
or--file
can be specified.
Writing a program
Hello world
Let's build the simplest program with Caporal: Hello world.
#!/usr/bin/env node
// Caporal provides you with a program instance
const { program } = require("@caporal/core")
// Simplest program ever: this program does only one thing
program.action(({ logger }) => {
logger.info("Hello, world!")
})
// always run the program at the end
program.run()
/*
# Now, in your terminal:
$ ./hello-world.js
Hello, world!
*/
This program contains only one action. An action is a function executed when the program, or one of its commands, is run.
Arguments
Let's get things more personal. by adding an argument name
and making our program displaying Hello, ${name}!
when run.
#!/usr/bin/env node
const { program } = require("@caporal/core")
program
.argument("<name>", "Name to greet")
.action(({ logger, args }) => {
logger.info("Hello, %s!", args.name)
})
program.run()
/*
$ ./hello.js Matt
Hello, Matt!
*/
Angled brackets vs square brackets
angled brackets (e.g. <item>
) indicate required input while square brackets (e.g. [env]
) indicate optional input. In the above example the <name>
argument is mandatory.
Of course you can add multiple arguments just by chaining them:
#!/usr/bin/env node
const { program } = require("@caporal/core")
program
.argument("<name>", "Name to greet")
.argument("<other-name>", "Another argument")
.argument("[third-arg]", "This argument is optional")
.action(({ logger, args }) =>
// Notice that args are camel-cased, so <other-name> becomes otherName
logger.info("Hello, %s and %s!", args.name, args.otherName),
)
program.run()
Options
Let's add a way to modify the greeting by adding a --greeting
option to our program.
#!/usr/bin/env node
const program = require("@caporal/core")
program
.argument("<name>", "Name to greet")
.option("--greeting <word>", "Greeting to use", {
default: "Hello",
})
.action(({ logger, args, options }) => {
logger.info("%s, %s!", options.greeting, args.name)
})
program.run()
/*
$ ./hello.js Matt --greeting Hi
Hi, Matt!
$ ./hello.js Matt
Hello, Matt!
*/
Note that our --greeting
option has a default value of Hello
. We specified what we called a long option, prefixed with a double dash. We can also specify an alternative short notation like this:
#!/usr/bin/env node
const { program } = require("@caporal/core")
program
.argument("<name>", "Name to greet")
// we will be able to use either `-g` or `--greeting` in the command line
.option("-g, --greeting <word>", "Greeting to use", {
default: "Hello",
})
.action(({ logger, args, options }) =>
logger.info("%s, %s!", options.greeting, args.name),
)
program.run()
/*
$ ./hello.js Matt -g Hi
Hi, Matt!
*/
Commands
So far, our program only manage one possible action. Let's build something a little more complex to illustrate commands.
#!/usr/bin/env ts-node
// file: pizza-hit.ts
import program from "@caporal/core"
program
// First possible command: "order"
.command("order", "Order a pizza")
.argument("<type>", "Type of pizza")
.option("-e, --extra-ingredients <ingredients>", "Extra ingredients")
.action(({ logger, args, options }) => {
logger.info("Order received: %s", args.type)
if (options.extraIngredients) {
logger.info("Extra: %s", options.extraIngredients)
}
})
// Another command: "cancel"
.command("cancel", "Cancel an order")
.argument("<order-id>", "Order id")
.action(({ logger, args }) => {
logger.info("Order canceled: %s", args.orderId)
})
program.run()
Now our program contains 2 commands: order
and cancel
, which can be called this way:
# order a margherita with pepperoni on top
./pizza-hit.js order margherita -e pepperoni
# cancel an order
./pizza-hit.js cancel 12345
Note that in the previous Hello world examples, even if there was no explicit Command specified, Caporal still created an unnamed Command under the hood (called a program-command), directly attached to the program. Learn more about Commands.
Help generation
Caporal automatically generates a help command for you so you don't have to!
prog --help
andprog help
will display global help.prog help ${command}
prog --help ${command}
and will display command-related help.
Checkout the help section of this guide to learn how to customize it.
Publishing your CLI
Publishing your CLI is easy with npm. Simply specify the bin
property inside your package.json
:
{
"bin": {
"pizza-hit": "src/pizza-hit.js"
}
}
- When installing your package globally, as in
npm install -g my-package
, npm will installsrc/pizza-hit.js
as a global executable namedpizza-hit
. - When installing your package locally, as in
npm install my-package
, npm will installsrc/pizza-hit.js
as an executable namedpizza-hit
insidenode_modules/.bin
.
Learn more about publishing your executable in the npm documentation.