Youssef Ameachaq's Blog

Youssef Ameachaq

Commander Package Guide for Node.js


commander is a powerful library for building command-line interfaces (CLIs) in Node.js. It simplifies argument parsing, command definition, and option handling. This guide covers all the key concepts, examples, and how to exit a program gracefully.


Table of Contents


Installation

To use commander, install it via npm:

npm install commander

Basic Example

Here’s a simple example to get started:

const { Command } = require('commander');
const program = new Command();

program
  .version('1.0.0')
  .description('A simple CLI tool');

program
  .command('greet <name>')
  .description('Greet a user')
  .action((name) => {
    console.log(`Hello, ${name}!`);
  });

program.parse(process.argv);

Running the Example

node cli.js greet John

Output:

Hello, John!

Adding Options

You can add options to customize the behavior of a command:

program
  .command('greet <name>')
  .description('Greet a user')
  .option('-t, --title <title>', 'Add a title to the greeting')
  .action((name, options) => {
    const greeting = `Hello, ${options.title ? options.title + ' ' : ''}${name}!`;
    console.log(greeting);
  });

Running with Options

node cli.js greet John --title Mr

Output:

Hello, Mr John!

Nested Commands

You can create nested commands for better organization:

program
  .command('user')
  .description('Manage users')
  .command('add <name>')
  .description('Add a user')
  .action((name) => {
    console.log(`User ${name} added.`);
  });

program
  .command('user')
  .command('remove <name>')
  .description('Remove a user')
  .action((name) => {
    console.log(`User ${name} removed.`);
  });

Running Nested Commands

node cli.js user add John

Output:

User John added.

Handling Errors

commander automatically handles errors for missing required arguments or options:

node cli.js greet

Output:

error: missing required argument 'name'

Custom Help

You can customize the help message:

program
  .name('my-cli')
  .usage('[options] <command>')
  .on('--help', () => {
    console.log('');
    console.log('Examples:');
    console.log('  $ my-cli greet John');
    console.log('  $ my-cli greet John --title Mr');
  });

Running with Custom Help

node cli.js --help

Output:

Usage: my-cli [options] <command>

Options:
  -V, --version            output the version number
  -h, --help               display help for command

Commands:
  greet <name>             Greet a user
  user                     Manage users
  help [command]           display help for command

Examples:
  $ my-cli greet John
  $ my-cli greet John --title Mr

Exiting the Program

You can exit a Node.js program using process.exit(). This method terminates the process with an optional exit code. By convention:

Using process.exit()

program
  .command('exit')
  .description('Exit the program')
  .action(() => {
    console.log('Exiting the program...');
    process.exit(0); // Exit with code 0 (success)
  });

program
  .command('fail')
  .description('Exit the program with an error')
  .action(() => {
    console.log('Exiting the program with an error...');
    process.exit(1); // Exit with code 1 (error)
  });

Running the Example

  1. Normal Exit:

    node cli.js exit

    Output:

    Exiting the program...
  2. Error Exit:

    node cli.js fail

    Output:

    Exiting the program with an error...

Graceful Exit

For cleanup tasks before exiting, handle the SIGINT signal or use a try-catch block:

process.on('SIGINT', () => {
  console.log('\nProcess interrupted. Cleaning up...');
  // Perform cleanup tasks here
  process.exit(0); // Exit gracefully
});

program
  .command('cleanup')
  .description('Exit with cleanup')
  .action(() => {
    try {
      console.log('Performing cleanup tasks...');
      // Simulate cleanup
      throw new Error('Cleanup failed!');
    } catch (error) {
      console.error(error.message);
      process.exit(1); // Exit with error code
    }
  });

Running the Cleanup Example

node cli.js cleanup

Output:

Performing cleanup tasks...
Cleanup failed!

Conclusion

commander is a powerful and flexible library for building CLI applications in Node.js. It simplifies argument parsing, command definition, and option handling. With the examples provided, you can start building your own CLI tools using commander.

For more advanced features, refer to the official documentation.