How do I pass command line arguments to a Node.js program?
Solution 1
Standard Method (no library)
The arguments are stored in process.argv
Here are the node docs on handling command line args:
process.argv
is an array containing the command line arguments. The first element will be 'node', the second element will be the name of the JavaScript file. The next elements will be any additional command line arguments.
// print process.argv
process.argv.forEach(function (val, index, array) {
console.log(index + ': ' + val);
});
This will generate:
$ node process-2.js one two=three four
0: node
1: /Users/mjr/work/node/process-2.js
2: one
3: two=three
4: four
Solution 2
To normalize the arguments like a regular javascript function would receive, I do this in my node.js shell scripts:
var args = process.argv.slice(2);
Note that the first arg is usually the path to nodejs, and the second arg is the location of the script you're executing.
Solution 3
The up-to-date right answer for this it to use the minimist library. We used to use node-optimist but it has since been deprecated.
Here is an example of how to use it taken straight from the minimist documentation:
var argv = require('minimist')(process.argv.slice(2));
console.dir(argv);
-
$ node example/parse.js -a beep -b boop
{ _: [], a: 'beep', b: 'boop' }
-
$ node example/parse.js -x 3 -y 4 -n5 -abc --beep=boop foo bar baz
{ _: [ 'foo', 'bar', 'baz' ],
x: 3,
y: 4,
n: 5,
a: true,
b: true,
c: true,
beep: 'boop' }
Solution 4
2018 answer based on current trends in the wild:
Vanilla javascript argument parsing:
const args = process.argv;
console.log(args);
This returns:
$ node server.js one two=three four
['node', '/home/server.js', 'one', 'two=three', 'four']
Most used NPM packages for argument parsing:
Minimist: For minimal argument parsing.
Commander.js: Most adopted module for argument parsing.
Meow: Lighter alternative to Commander.js
Yargs: More sophisticated argument parsing (heavy).
Vorpal.js: Mature / interactive command-line applications with argument parsing.
Solution 5
Optimist (node-optimist)
Check out optimist library, it is much better than parsing command line options by hand.
Update
Optimist is deprecated. Try yargs which is an active fork of optimist.
milkplus
Updated on July 08, 2022Comments
-
milkplus almost 2 years
I have a web server written in Node.js and I would like to launch with a specific folder. I'm not sure how to access arguments in JavaScript. I'm running node like this:
$ node server.js folder
here
server.js
is my server code. Node.js help says this is possible:$ node -h Usage: node [options] script.js [arguments]
How would I access those arguments in JavaScript? Somehow I was not able to find this information on the web.
-
250R about 12 yearsIt's probably a good idea to manage your configuration in a centralized manner using something like nconf github.com/flatiron/nconf It helps you work with configuration files, environment variables, command-line arguments.
-
Joel Purra over 10 yearsAnd here's configvention, my own, minimal, readonly interface for nconf.
-
-
hansvb almost 13 years+1 for the link. There is quite a long list of command line option parsers at github.com/joyent/node/wiki/modules#wiki-parsers-commandline
-
balupton over 10 years@Evan Carroll please don't edit my answer to promote a library I don't use stackoverflow.com/posts/7483600/revisions especially because of a missing feature you're after, such opinions should be saved for comments or pull requests to the module authors, not edits to other people's answers.
-
JK ABC over 9 yearsActually, this solution is more helpful for developing command line tool with more flags and arguments, and should be upvoted more IMHO.
-
Mauvis Ledford over 9 yearsJust a note that I wrote this answer 4 years ago and the code I am running is still running 100% fine today. Still keeping up to date with the latest versions of node and still zero problems: It's just a simple shell script guys. Not part of a big global object full of JS libraries. I still stand behind my answer today. I will give another update in 4 more years.
-
cuixiping over 8 yearsthe 2nd element (process.argv[1]) may be or may be not js file. node command syntax is
node [options] [ -e script | script.js ] [arguments]
ornode debug script.js [arguments]
. for example:node --harmony script.js balala
ornode --no-deprecation --enable-ssl2 script.js balala
, we can use process.execArgv with process.argv -
joonas.fi over 7 years"$ npm install -g yargs" yielded 1.9 MB of JavaScript code. When is this madness going to end when an argv parser library needs two megabytes of code? Increased attack surface, wasted RAM etc...
-
Joseph Merdrignac over 6 yearsi agree, but it could be shorter no ?
let args = process.argv.slice(2).reduce((acc, arg) => { let [k, v] = arg.split('=') acc[k] = v return acc }, {})
-
barwnikk over 6 yearsWhy do you use require('fs')?
-
user3285954 over 4 yearsYargs doesn't affect how arguments are passed on command line, it only helps in reading them in code.
-
Endless over 3 yearswriting too much es6 like this can make the code feel unreadable at first glance
-
Nuno almost 3 yearsIt's been over 6 years. Any update?
-
Kr1 over 2 yearsYour solution is very stylish. Thanks!
-
hastrb over 2 years
.slice(2, process.argv.length)
isn't the second arg redundant?.slice()
goes to the end of string by default. -
Subramanya Rao over 2 yearssimple way to select custom arg: const list_arg = process.argv.filter((arg) => (['-list', '-l'].includes(arg))).toString();
-
Sridhar Sarnobat over 2 yearsStrange, I get
requires 1 arguments
for an argument that I've setrequired: false
. I even tried this with version 2 of the library. -
Steam gamer over 2 yearsIf you're going to use this answer, consider using the more active fork, minimist-lite as the former is abandoned. The "up-to-date right answer" would be to use
process.argv.slice(2)
which is the answer for the actual question... -
Mauvis Ledford over 2 years@Nuno I just tested my original answer on Node v16.13.2 (2022-01-11) and yep, it still works perfectly fine 11 years after posting. :)
-
Timo over 2 yearsLet's go for the next five years to see the
process.argv
working;) -
CherryDT over 2 yearsThese aren't "named parameters" as such, they are environment variables.
-
Preston L. Bannister over 2 yearsThey are parameters, and they are named. That they are environment variables is incidental. Or perhaps you have some other definition? :)
-
CherryDT over 2 yearsA named parameter would be
--myvalue=abc
. Environment variables have entirely different semantics such as being passed to all child processes as well (which is a problem both ways - you may have something passed that you didn't expect, and you may forward something you didn't intend) and not being passed across WSL interop boundaries unless separately specified in WSLENV. Those different semantics are why they have environment in the name. -
Preston L. Bannister over 2 yearsOnce more, then I am dropping this thread. We are passing named parameters to a program. Yes, the semantics are slightly different, but only that. Ever read the library code that calls "C" main()? Both command line and environment are just pointers to character buffers. For the most/many (small) tools that I write, the slightly more global nature of parameters passed in the environment is of no practical concern. For larger works I construct the environment for child processes. (Good practice to limit risks.) At this point I assume we will not agree.
-
CherryDT over 2 yearsYet, inventing new names for things that already have a name, especially if that new name conflicts with the name of other similar things, is utterly confusing. Named command line arguments already exist and they have the form
--arg=xyz
or--arg xyz
. Yes you can use environment variables to pass string values identified by some name to a process, but that doesn't make them named arguments because that term already has another meaning. It would be equally wrong and confusing to call a spritz (wine with soda) sparkling wine, even though it tastes like wine and is sparkling, wouldn't it? -
CherryDT over 2 yearsPlus, while you do seem to be aware of the differences in behavior and how to avoid problems with them, the people learning about this from your post for the first time won't be. You advertise environment variables as named command line arguments, implying they would behave as one would expect from command line arguments without warning that they don't, and you never refer to them even once in your post by their actual googleable name. So you are just laying out traps for novice programmers who will be stumped why using a "named argument"
PATH
breaks in multiple mysterious ways for instance. -
temporary_user_name about 2 yearsIs
if ( process.argv.includes( `--${ key }` ) )
nottrue
for--foo=bar
? I'm confused how it ever gets past that first conditional. -
Andrew Odri about 2 years@temporary_user_name Ahh great question...
includes
is testing matching values in the argv array, not substrings in each argv entry. So the value must be an exact match: i.e. Testing argv with includes for the--foo
element would not match--foo=bar
, which would be separate value in the array. The next line,process.argv.find
shows what the substring search looks like. -
temporary_user_name about 2 yearsOh that's so obvious now that you say it. I totally knew that and wasn't thinking. Thank you for the reminder.
-
Andrew Odri about 2 years@temporary_user_name All good... It's kind of good for readers to see the tradeoff with ES6 syntactic sugar and features... Short and concise does not always equal readable :P