Building CLI Tools with Node.js

matt
Matthew Gros · Sep 22, 2025

TLDR

Use commander for arguments, inquirer for prompts, chalk for colors. Publish to npm for easy install.

Building CLI Tools with Node.js

Build Tools People Actually Use

Good CLI tools save time and reduce errors.

Project Setup

mkdir my-cli && cd my-cli
npm init -y
npm install commander inquirer chalk
// package.json
{
  "bin": {
    "my-cli": "./index.js"
  }
}

Basic Structure

#!/usr/bin/env node
const { program } = require('commander');

program
    .name('my-cli')
    .version('1.0.0')
    .description('My awesome CLI tool');

program
    .command('greet <name>')
    .description('Greet someone')
    .option('-l, --loud', 'Shout the greeting')
    .action((name, options) => {
        const greeting = `Hello, ${name}!`;
        console.log(options.loud ? greeting.toUpperCase() : greeting);
    });

program.parse();

Interactive Prompts

const inquirer = require('inquirer');

async function setup() {
    const answers = await inquirer.prompt([
        {
            type: 'input',
            name: 'projectName',
            message: 'Project name:',
            default: 'my-project'
        },
        {
            type: 'list',
            name: 'template',
            message: 'Choose a template:',
            choices: ['basic', 'advanced', 'minimal']
        },
        {
            type: 'confirm',
            name: 'typescript',
            message: 'Use TypeScript?',
            default: true
        }
    ]);

    console.log('Creating project:', answers);
}

Colorful Output

const chalk = require('chalk');

console.log(chalk.green('✓ Success!'));
console.log(chalk.red('✗ Error!'));
console.log(chalk.yellow('⚠ Warning'));
console.log(chalk.blue.bold('Info'));

Publishing

# Link for local testing
npm link

# Publish to npm
npm publish

Tips

  • Provide --help automatically (commander does this)
  • Use exit codes (0 success, 1 error)
  • Support --quiet and --verbose
  • Handle Ctrl+C gracefully

About the Author

matt

I build and ship automation-driven products using Laravel and modern frontend stacks (Vue/React), with a focus on scalability, measurable outcomes, and tight user experience. I’m based in Toronto, have 13+ years in PHP, and I also hold a pilot’s license. I enjoy working on new tech projects and generally exploring new technology.