How do I pass command line arguments to a Node.js program?

1,493,319

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']

Official docs


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.

Share:
1,493,319
milkplus
Author by

milkplus

Updated on July 08, 2022

Comments

  • milkplus
    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
      250R about 12 years
      It'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
      Joel Purra over 10 years
      And here's configvention, my own, minimal, readonly interface for nconf.
  • hansvb
    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
    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
    JK ABC over 9 years
    Actually, this solution is more helpful for developing command line tool with more flags and arguments, and should be upvoted more IMHO.
  • Mauvis Ledford
    Mauvis Ledford over 9 years
    Just 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
    cuixiping over 8 years
    the 2nd element (process.argv[1]) may be or may be not js file. node command syntax is node [options] [ -e script | script.js ] [arguments] or node debug script.js [arguments]. for example: node --harmony script.js balala or node --no-deprecation --enable-ssl2 script.js balala , we can use process.execArgv with process.argv
  • joonas.fi
    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
    Joseph Merdrignac over 6 years
    i 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
    barwnikk over 6 years
    Why do you use require('fs')?
  • user3285954
    user3285954 over 4 years
    Yargs doesn't affect how arguments are passed on command line, it only helps in reading them in code.
  • Endless
    Endless over 3 years
    writing too much es6 like this can make the code feel unreadable at first glance
  • Nuno
    Nuno almost 3 years
    It's been over 6 years. Any update?
  • Kr1
    Kr1 over 2 years
    Your solution is very stylish. Thanks!
  • hastrb
    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
    Subramanya Rao over 2 years
    simple way to select custom arg: const list_arg = process.argv.filter((arg) => (['-list', '-l'].includes(arg))).toString();
  • Sridhar Sarnobat
    Sridhar Sarnobat over 2 years
    Strange, I get requires 1 arguments for an argument that I've set required: false. I even tried this with version 2 of the library.
  • Steam gamer
    Steam gamer over 2 years
    If 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
    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
    Timo over 2 years
    Let's go for the next five years to see the process.argv working;)
  • CherryDT
    CherryDT over 2 years
    These aren't "named parameters" as such, they are environment variables.
  • Preston L. Bannister
    Preston L. Bannister over 2 years
    They are parameters, and they are named. That they are environment variables is incidental. Or perhaps you have some other definition? :)
  • CherryDT
    CherryDT over 2 years
    A 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
    Preston L. Bannister over 2 years
    Once 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
    CherryDT over 2 years
    Yet, 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
    CherryDT over 2 years
    Plus, 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
    temporary_user_name about 2 years
    Is if ( process.argv.includes( `--${ key }` ) ) not true for --foo=bar? I'm confused how it ever gets past that first conditional.
  • Andrew Odri
    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
    temporary_user_name about 2 years
    Oh that's so obvious now that you say it. I totally knew that and wasn't thinking. Thank you for the reminder.
  • Andrew Odri
    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