Menu

Node.js process.argv: Read Command Line Arguments

process.argv is an array of the command line that started your program: the node executable, the script path, then every argument you typed. Use process.argv.slice(2) to get just your arguments.

This page includes runnable editors. Edit, run, and see output instantly.

process.argv is an array holding the command line that started your Node.js program. Index 0 is the path to the node executable, index 1 is the path to your script, and your own arguments start at index 2. So process.argv.slice(2) gives you exactly what the user typed after the file name, always as strings.

The first two entries are full paths, so this prints only their last part (node and index.js), then [ 'Ada', '42', '--verbose' ]. Edit the arguments row to Grace 7 and run again: the array follows.

What goes into process.argv

The shell splits the line after node on spaces and hands Node.js the pieces. Flags written before the file name belong to Node.js itself, not to your program:

node --max-old-space-size=4096 index.js --port=8080
# process.argv.slice(2) is [ '--port=8080' ]
# process.execArgv is      [ '--max-old-space-size=4096' ]

Quoting groups words into one argument ("Ada Lovelace" arrives as a single string), and the shell expands patterns like *.txt into file names before Node.js ever sees them.

Get the arguments with slice(2)

Most scripts destructure the arguments they expect and give each a default:

It printed Hello, Ada: one argument filled name, and greeting fell back to its default. Add Hi after Ada in the arguments row and it prints Hi, Ada; clear the row and you get Hello, world.

Numbers arrive as strings

The shell has no types. Every argument is a string, so arithmetic on them goes wrong until you convert:

a + b joined the strings into 75, and Number() gave 12. A word that is not a number becomes NaN, so check with Number.isNaN and print a usage message instead of carrying on with a broken value.

Parse --name=value flags by hand

For a couple of flags, a short loop is enough. This one turns --port=8080 into port: '8080', a bare --verbose into true, and keeps everything else as a positional argument:

It printed {"port":"8080","verbose":true} and [ 'build', 'src' ], with port still a string. This loop does not handle short flags like -p or a value in the next argument (--port 8080); for that, use the built-in parser below.

util.parseArgs, the built-in parser

Node.js 18.3 and later ship util.parseArgs, which handles long and short flags, values in the next argument, booleans and defaults:

const { parseArgs } = require('node:util');

// node index.js -p 8080 --verbose src
const { values, positionals } = parseArgs({
    options: {
        port: { type: 'string', short: 'p', default: '3000' },
        verbose: { type: 'boolean', short: 'v' },
    },
    allowPositionals: true,
});

console.log(values);      // [Object: null prototype] { port: '8080', verbose: true }
console.log(positionals); // [ 'src' ]

parseArgs reads process.argv.slice(2) by default. It throws on an option you did not declare, which catches typos like --prot; pass strict: false to accept unknown flags. Option types are only string and boolean, so numbers still need Number(). values is an object with no prototype, which is why it prints with [Object: null prototype]; read it like any object.

Common mistakes

Reading process.argv[0] as the first argument. It is the path to node. Your first argument is process.argv[2].

Forgetting that everything is a string. '10' > '9' is false, because strings compare letter by letter. Convert first.

Putting secrets in arguments. Command lines show up in shell history and in process lists that other users on the machine can read. Pass passwords and API keys through environment variables instead.

Frequently Asked Questions

How do I pass arguments to an npm script?

Put them after --: npm run start -- --port=4000. npm passes everything after the -- to your script, where it shows up in process.argv.slice(2).

Why is process.argv[2] undefined?

Because the program was started without that argument. Give it a default (process.argv[2] ?? 'guest'), or print a usage line and stop with process.exit(1).

Should I use yargs or commander instead of process.argv?

For a script with a few flags, util.parseArgs is built in and enough. Packages like commander and yargs add help text, subcommands and validation, which pays off once your tool has several commands.

Coddy programming languages illustration

Learn to code with Coddy

Get started