Back to Blog
Lesson 12 of the Node.js: Build Your First Server & CLI course
Node.jsJuly 30, 20264 min read

Handling CLI Arguments in Node.js: A Beginner's Guide

Learn how to pass and handle CLI arguments in Node.js using process.argv. Build your own argument parser to create flexible, interactive command-line tools.

Node.jsCLIprocess.argvprogrammingbackend
Scrabble tiles spelling 'Improve Your Argument' on a green background with leaves.

Previously in this course, we explored The OS and Process Modules to understand how Node.js interacts with your operating system. Now that you know how to access environment variables, we are going to take it a step further by learning how to pass custom input into your scripts via the command line.

Being able to pass CLI arguments is the first step toward building professional, configurable utilities rather than static scripts.

Understanding process.argv

When you run a script, Node.js provides a global object called process. One of its most useful properties for CLI development is argv (short for "argument vector"). This is an array containing the entire command used to invoke your script.

Create a file named args.js and add this code:

JAVASCRIPT
console.log(process.argv);

Now, run it in your terminal: node args.js --name=John --age=30

You will see an output similar to this:

JSON
[
  '/usr/local/bin/node',
  '/path/to/your/args.js',
  '--name=John',
  '--age=30'
]

The first two elements are always the same: the path to the Node executable and the path to your file. Your actual data begins at index 2.

Parsing Simple Command-Line Flags

Red Turkish flags flutter on a line against a clear blue sky, symbolizing national pride and freedom.

Since process.argv gives you a raw array of strings, you need to write logic to turn them into a usable format. A common pattern is to split strings by the = character to create key-value pairs.

Let’s build a basic parser that converts those strings into a JavaScript object:

JAVASCRIPT
const args = process.argv.slice(2);
const parsedArgs = {};

args.forEach(arg => {
  if (arg.startsWith(CE9178">'--')) {
    const [key, value] = arg.slice(2).split(CE9178">'=');
    parsedArgs[key] = value || true; // Set to true if no value provided
  }
});

console.log(parsedArgs);

If you run node args.js --env=production --debug, the output will be: { env: 'production', debug: true }

By slicing the array at index 2, we ignore the system paths. We then iterate through the remaining items, stripping the -- prefix and splitting the key from the value.

Building a Basic Argument Parser

As your projects grow, manual parsing becomes brittle. While many developers eventually use packages like yargs or commander, building your own simple parser is an essential exercise to understand how these tools work under the hood.

Here is a more robust way to handle flags and positional arguments:

JAVASCRIPT
function parseArgs(args) {
  const result = { flags: {}, positional: [] };
  
  args.forEach(arg => {
    if (arg.startsWith(CE9178">'--')) {
      const [key, value] = arg.slice(2).split(CE9178">'=');
      result.flags[key] = value ?? true;
    } else {
      result.positional.push(arg);
    }
  });
  
  return result;
}

const { flags, positional } = parseArgs(process.argv.slice(2));
console.log(CE9178">'Flags:', flags);
console.log(CE9178">'Commands:', positional);

Practice Exercise

Modify the script above to handle "short" flags (e.g., -n for --name). Hint: You will need to check if the argument starts with a single hyphen and map it to your desired key.

Common Pitfalls

Close-up of a rusty sewer manhole cover in a grassy Boston park.

  1. Index Off-by-One Errors: Always remember that process.argv[0] and [1] are system paths. Many beginners accidentally try to process these as user input, leading to unexpected bugs.
  2. Type Coercion: All arguments come in as strings. If you pass --port=3000, it will be the string "3000", not the number 3000. You must explicitly cast them using Number() or parseInt() when necessary.
  3. Complex Patterns: Don't try to build a custom parser for complex applications with nested subcommands or nested flags. That is the point where you should switch to a library.

FAQ

Why not just use environment variables? Environment variables are great for configuration (like API keys), while CLI arguments are best for transient, task-specific input (like specifying a filename to process).

Can I use spaces in my arguments? Yes, if you wrap the argument in quotes: node script.js --message="Hello World".

Is process.argv available in browsers? No, process is a Node.js-specific global object.

Recap

Team members presenting a project in a modern office setting with a focus on collaboration.

In this lesson, we demystified the command line by learning to access process.argv. We moved from raw data to structured objects, giving you the ability to turn static scripts into dynamic tools. You now have the foundation to build complex CLI utilities that accept user input, which is a core skill for any backend engineer.

Up next: We will learn to polish your scripts by adding a shebang and making them directly executable, moving closer to true Command Line Tools with Artisan: Automating Laravel Workflows-style productivity.

Similar Posts