Node.js7 min read

Building CLI Tools

Create command-line tools with Node.js. Learn argument parsing and colors.

Sarah Chen
December 19, 2025
0.0k0

Building CLI Tools

Node.js is perfect for creating command-line tools.

Basic CLI Script

#!/usr/bin/env node

console.log('Hello from CLI!');
chmod +x cli.js
./cli.js

Parsing Arguments with Commander

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

program
  .name('my-tool')
  .description('A useful CLI tool')
  .version('1.0.0');

program
  .command('create <name>')
  .description('Create a new project')
  .option('-t, --template <type>', 'Template type', 'basic')
  .action((name, options) => {
    console.log(`Creating project: ${name}`);
    console.log(`Template: ${options.template}`);
  });

program
  .command('list')
  .description('List all projects')
  .action(() => {
    console.log('Listing projects...');
  });

program.parse();

Usage:

my-tool create my-app --template react
my-tool list

Adding Colors

npm install chalk
const chalk = require('chalk');

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

Interactive Prompts

npm install inquirer
const inquirer = require('inquirer');

async function getUserInput() {
  const answers = await inquirer.prompt([
    {
      type: 'input',
      name: 'projectName',
      message: 'Project name:',
      default: 'my-app'
    },
    {
      type: 'list',
      name: 'template',
      message: 'Choose template:',
      choices: ['React', 'Vue', 'Express']
    },
    {
      type: 'confirm',
      name: 'installDeps',
      message: 'Install dependencies?',
      default: true
    }
  ]);
  
  return answers;
}

const config = await getUserInput();
console.log(config);

Progress Indicators

npm install ora
const ora = require('ora');

const spinner = ora('Installing packages...').start();

setTimeout(() => {
  spinner.succeed('Packages installed!');
}, 3000);

Real Example: Project Generator

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

program
  .command('create <name>')
  .action(async (name) => {
    const answers = await inquirer.prompt([
      {
        type: 'list',
        name: 'template',
        message: 'Choose template:',
        choices: ['React', 'Vue', 'Express']
      }
    ]);
    
    const spinner = ora('Creating project...').start();
    
    fs.mkdirSync(name);
    fs.writeFileSync(`${name}/package.json`, JSON.stringify({
      name,
      version: '1.0.0',
      template: answers.template
    }, null, 2));
    
    spinner.succeed(chalk.green(`Project ${name} created!`));
  });

program.parse();

Publishing to npm

{
  "name": "my-cli-tool",
  "version": "1.0.0",
  "bin": {
    "my-tool": "./cli.js"
  },
  "dependencies": {
    "commander": "^11.0.0",
    "chalk": "^5.3.0"
  }
}
npm publish

npm install -g my-cli-tool

my-tool create my-app

Key Takeaway

Use commander for arguments, chalk for colors, inquirer for prompts, ora for spinners. Add shebang and bin field in package.json. Publish to npm for global installation.

#Node.js#CLI#Tools#Commander