Skip to content
All essays
CraftFebruary 12, 20258 min

CLI Development: Building Command-Line Tools

Learn to build powerful CLI tools. From basic scripts to full-featured applications.

Ü
Ümit Uz
Mobile & Full Stack Developer

Getting Started

Node.js CLI

javascript
// package.json
{
  "name": "my-cli",
  "version": "1.0.0",
  "bin": {
    "mycli": "./cli.js"
  }
}

// cli.js
#!/usr/bin/env node
console.log('Hello CLI!');

Commander.js

javascript
#!/usr/bin/env node
import { Command } from 'commander';

const program = new Command();

program
  .name('mycli')
  .description('My awesome CLI')
  .version('1.0.0');

program
  .command('greet <name>')
  .description('Greet someone')
  .option('-c, --caps', 'Use uppercase')
  .action((name, options) => {
    let message = `Hello, ${name}!`;
    if (options.caps) message = message.toUpperCase();
    console.log(message);
  });

program.parse();

Inquirer.js (Interactive Prompts)

javascript
import inquirer from 'inquirer';

inquirer
  .prompt([
    {
      type: 'input',
      name: 'name',
      message: 'What is your name?'
    },
    {
      type: 'list',
      name: 'color',
      message: 'Choose a color:',
      choices: ['red', 'green', 'blue']
    },
    {
      type: 'confirm',
      name: 'confirm',
      message: 'Confirm?',
      default: true
    }
  ])
  .then((answers) => {
    console.log(JSON.stringify(answers, null, 2));
  });

Chalk (Colors)

javascript
import chalk from 'chalk';

console.log(chalk.red('Error!'));
console.log(chalk.green('Success!'));
console.log(chalk.bold.yellow('Warning!'));
console.log(
  chalk.blue('Hello') + ' ' +
  chalk.red.bgWhite('World')
);

Ora (Spinners)

javascript
import ora from 'ora';

const spinner = ora('Loading...').start();

setTimeout(() => {
  spinner.succeed('Completed!');
}, 2000);

spinner.fail('Failed!');
spinner.warn('Warning');
spinner.info('Info');

Clui (Progress Bars)

javascript
import { multibar } from 'clui';

const progress1 = multibar.create(100, 0, 'Task 1');
const progress2 = multibar.create(100, 0, 'Task 2');

// Update progress
progress1.update(50);
progress2.update(75);

Best Practices

  1. 1Help text: Clear --help output
  2. 2Exit codes: Proper exit codes (0 = success, 1 = error)
  3. 3Error handling: Graceful error messages
  4. 4Config: Support config files
  5. 5Completions: Shell autocompletion

Publishing

bash
# Make executable
chmod +x cli.js

# Link globally
npm link

# Use CLI
mycli --help

# Publish to npm
npm publish

Build CLIs that developers love to use!

Related essays

Next essay
Database Fundamentals: SQL vs NoSQL Decision Guide