DEV Community

Alex Spinov
Alex Spinov

Posted on

Commander.js Has a Free API — Here's How to Build Professional CLI Tools in Node.js

Commander.js is the most popular library for building command-line interfaces in Node.js. It handles argument parsing, subcommands, help generation, and option validation.

Installation

npm install commander
Enter fullscreen mode Exit fullscreen mode

Basic CLI

import { program } from "commander";

program
  .name("my-cli")
  .description("A CLI tool for managing projects")
  .version("1.0.0");

program
  .command("greet")
  .description("Greet a user")
  .argument("<name>", "Name to greet")
  .option("-l, --loud", "Greet loudly")
  .action((name, options) => {
    const msg = `Hello, ${name}!`;
    console.log(options.loud ? msg.toUpperCase() : msg);
  });

program.parse();
Enter fullscreen mode Exit fullscreen mode
my-cli greet World           # Hello, World!
my-cli greet World --loud    # HELLO, WORLD!
my-cli --help                # Auto-generated help
Enter fullscreen mode Exit fullscreen mode

Options and Arguments

program
  .command("deploy")
  .description("Deploy application")
  .requiredOption("-e, --env <environment>", "Target environment")
  .option("-p, --port <number>", "Port number", "3000")
  .option("-d, --debug", "Enable debug mode", false)
  .option("--no-cache", "Disable caching")
  .option("-t, --tags <items...>", "Deployment tags")
  .action((options) => {
    console.log(`Deploying to ${options.env}:${options.port}`);
    console.log(`Debug: ${options.debug}, Cache: ${options.cache}`);
    console.log(`Tags: ${options.tags?.join(", ")}`);
  });
Enter fullscreen mode Exit fullscreen mode

Subcommands

const db = program.command("db").description("Database operations");

db.command("migrate")
  .description("Run database migrations")
  .option("--dry-run", "Preview without executing")
  .action((options) => {
    console.log(options.dryRun ? "Dry run..." : "Migrating...");
  });

db.command("seed")
  .description("Seed database with sample data")
  .argument("[count]", "Number of records", "100")
  .action((count) => {
    console.log(`Seeding ${count} records...`);
  });
Enter fullscreen mode Exit fullscreen mode

Hook and Error Handling

program
  .hook("preAction", (thisCommand) => {
    console.log(`Running: ${thisCommand.name()}`);
  });

program.exitOverride();
try {
  program.parse();
} catch (err) {
  console.error(`Error: ${err.message}`);
}
Enter fullscreen mode Exit fullscreen mode

Need to extract or automate web content at scale? Check out my web scraping tools on Apify — no coding required. Or email me at spinov001@gmail.com for custom solutions.

Top comments (0)