Stop 02 · Node.js FundamentalsProjects · 1/3

CLI Tool

Part of the Backend Developer Roadmap

In short

Your first real Node project doesn't need a browser at all. A command-line tool teaches arguments, files, exit codes and packaging: the same basics every backend service relies on.

A command-line tool (e.g. a task manager or file renamer) — practice for `process.argv`, the `fs` module, and packaging a script as a runnable CLI.

The mascot presses a button on a tea vending machine as a paper cup fills with tea.

Think of it like this

The office tea vending machine

Press a button, maybe pick 'extra sugar', and you get the same tea every time. If it's out of milk, it flashes an error instead of pouring hot water. A good CLI tool is that machine: clear options in, predictable output out, honest errors.

Watch it happen

What happens when you run greet

Parse args
Validate
Do work
Print
Exit code

1/5Read flags like --name Asha --shout from process.argv using util.parseArgs.

The big ideas

What you need to know

A real --help

Show usage and every option with --help. It's the first thing people try.

stdout for results, stderr for errors

Keeping them apart lets users redirect results to a file without error messages mixed in.

Meaningful exit codes

0 means success, anything else means failure. Shell scripts and CI pipelines depend on it.

Installable with bin

A "bin" entry in package.json plus npm link turns your script into a command you can run anywhere.

See it in code

Walk through the code

js
1#!/usr/bin/env node2import { parseArgs } from "node:util";3 4const { values } = parseArgs({5  options: {6    name: { type: "string", short: "n" },7    shout: { type: "boolean", default: false },8    help: { type: "boolean", short: "h" },9  },10});11if (values.help || !values.name) {12  console.error("Usage: greet --name <name> [--shout]");13  process.exit(values.help ? 0 : 1);14}15const msg = `Namaste, ${values.name}!`;16console.log(values.shout ? msg.toUpperCase() : msg);

1/4The shebang tells the OS to run this file with node when you type greet.

Save as bin/greet.js in a package with "type": "module" and "bin": { "greet": "bin/greet.js" }. Run chmod +x on it, then npm link. parseArgs throws on unknown flags by default.

Save yourself the pain

Common mistakes

Oops

Printing errors with console.log, so they mix into the real output.

Do this instead

Send errors to stderr with console.error. Then greet -n A > out.txt keeps only real results in the file.

Oops

Always exiting with code 0, even when something failed.

Do this instead

Set process.exitCode = 1, or call process.exit(1), on errors so shell scripts and CI can detect them.

Your mission

First milestone: ship greet v1

~30 min

Quick check

Your CLI can't find the input file the user gave it. What should it do?

Go deeper

  1. 1Parse command-line arguments manually or with a library like `commander`.
  2. 2Add colored terminal output for better UX, e.g. with `chalk`.
  3. 3Package it with a `bin` field in `package.json` so it can be installed globally.

More projects at this stop

Stuck on this topic? Ask an Insider

Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.

Download
InsideEdge