3000

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.

starball
  • 20,030
  • 7
  • 43
  • 238
milkplus
  • 33,007
  • 7
  • 30
  • 31
  • It's probably a good idea to manage your configuration in a centralized manner using something like **nconf** https://github.com/flatiron/nconf It helps you work with configuration files, environment variables, command-line arguments. – 250R May 26 '12 at 00:10
  • And here's [configvention](http://joelpurra.github.com/nodejs-configvention), my own, minimal, readonly interface for nconf. – Joel Purra Jan 26 '14 at 12:02

41 Answers41

3620

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
zypA13510
  • 1,092
  • 1
  • 10
  • 28
MooGoo
  • 46,796
  • 4
  • 39
  • 32
  • 31
    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**](https://nodejs.org/docs/latest/api/process.html#process_process_execargv) with [process.argv](https://nodejs.org/docs/latest/api/process.html#process_process_argv) – cuixiping Jan 07 '16 at 12:43
  • https://nodejs.org/docs/latest/api/process.html#processexecargv – Kid Oct 11 '22 at 12:21
  • 3
    Per node.js document, process.argv doesn't return those node.js-specific flags. like `--harmony` in your example – Kid Oct 11 '22 at 12:22
  • For some reason that code did not output anything in TypeScript with tsx. The arguments are there though in `process.argv`. – Slion Jun 28 '23 at 07:41
  • 2023, new to the node runtime, have to walk through these answers, many claiming to be 'the new way', in 2016,2018.. The TLDR from 2023 looks like: this answer has always been right, there's just 2 gotchas in that you have two args you need to ignore; and it doesn't capture args entered into/before the node.exe, like --harmony node.exe - but it's okay, you can get those somewhere else. The other notable answers are libraries that parse the input args more nicely and extractable. And minimist was one, that stopped being supported, but now it seems is alive again, in a different repo. – zola25 Aug 16 '23 at 04:30
958

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.

bjb568
  • 11,089
  • 11
  • 50
  • 71
Mauvis Ledford
  • 40,827
  • 17
  • 81
  • 86
489

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' }
real_ate
  • 10,861
  • 3
  • 27
  • 48
  • 54
    Actually, this solution is more helpful for developing command line tool with more flags and arguments, and should be upvoted more IMHO. – JK ABC Feb 06 '15 at 03:15
  • 7
    If you're going to use this answer, consider using the more active fork, [minimist-lite](https://github.com/meszaros-lajos-gyorgy/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... – Steam gamer Jan 24 '22 at 21:32
421

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.

Daniel Witurna
  • 750
  • 6
  • 13
dthree
  • 19,847
  • 14
  • 77
  • 106
  • 139
    "$ 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... – joonas.fi Oct 13 '16 at 17:21
  • simple way to select custom arg: const list_arg = process.argv.filter((arg) => (['-list', '-l'].includes(arg))).toString(); – Subramanya Rao Nov 23 '21 at 15:40
136

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.

Sanghyun Lee
  • 21,644
  • 19
  • 100
  • 126
gor
  • 11,498
  • 5
  • 36
  • 42
  • 18
    +1 for the link. There is quite a long list of command line option parsers at https://github.com/joyent/node/wiki/modules#wiki-parsers-commandline – Thilo Sep 15 '11 at 05:24
129

Several great answers here, but it all seems very complex. This is very similar to how bash scripts access argument values and it's already provided standard with node.js as MooGoo pointed out. (Just to make it understandable to somebody that's new to node.js)

Example:

$ node yourscript.js banana monkey

var program_name = process.argv[0]; //value will be "node"
var script_path = process.argv[1]; //value will be "yourscript.js"
var first_value = process.argv[2]; //value will be "banana"
var second_value = process.argv[3]; //value will be "monkey"
Paul van Jaarsveld
  • 1,524
  • 1
  • 10
  • 9
117

No Libs with Flags Formatted into a Simple Object

function getArgs () {
    const args = {};
    process.argv
        .slice(2, process.argv.length)
        .forEach( arg => {
        // long arg
        if (arg.slice(0,2) === '--') {
            const longArg = arg.split('=');
            const longArgFlag = longArg[0].slice(2,longArg[0].length);
            const longArgValue = longArg.length > 1 ? longArg[1] : true;
            args[longArgFlag] = longArgValue;
        }
        // flags
        else if (arg[0] === '-') {
            const flags = arg.slice(1,arg.length).split('');
            flags.forEach(flag => {
            args[flag] = true;
            });
        }
    });
    return args;
}
const args = getArgs();
console.log(args);

Examples

Simple

input

node test.js -D --name=Hello

output

{ D: true, name: 'Hello' }

Real World

input

node config/build.js -lHRs --ip=$HOST --port=$PORT --env=dev

output

{ 
  l: true,
  H: true,
  R: true,
  s: true,
  ip: '127.0.0.1',
  port: '8080',
  env: 'dev'
}
Community
  • 1
  • 1
Michael Warner
  • 3,879
  • 3
  • 21
  • 45
  • `.slice(2, process.argv.length)` isn't the second arg redundant? `.slice()` goes to the end of string by default. – hastrb Nov 12 '21 at 06:54
90

Commander.js

Works great for defining your options, actions, and arguments. It also generates the help pages for you.

Promptly

Works great for getting input from the user, if you like the callback approach.

Co-Prompt

Works great for getting input from the user, if you like the generator approach.

balupton
  • 47,113
  • 32
  • 131
  • 182
  • 32
    @Evan Carroll please don't edit my answer to promote a library I don't use http://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. – balupton Nov 11 '13 at 01:56
83

Stdio Library

The easiest way to parse command-line arguments in NodeJS is using the stdio module. Inspired by UNIX getopt utility, it is as trivial as follows:

var stdio = require('stdio');
var ops = stdio.getopt({
    'check': {key: 'c', args: 2, description: 'What this option means'},
    'map': {key: 'm', description: 'Another description'},
    'kaka': {args: 1, required: true},
    'ooo': {key: 'o'}
});

If you run the previous code with this command:

node <your_script.js> -c 23 45 --map -k 23 file1 file2

Then ops object will be as follows:

{ check: [ '23', '45' ],
  args: [ 'file1', 'file2' ],
  map: true,
  kaka: '23' }

So you can use it as you want. For instance:

if (ops.kaka && ops.check) {
    console.log(ops.kaka + ops.check[0]);
}

Grouped options are also supported, so you can write -om instead of -o -m.

Furthermore, stdio can generate a help/usage output automatically. If you call ops.printHelp() you'll get the following:

USAGE: node something.js [--check <ARG1> <ARG2>] [--kaka] [--ooo] [--map]
  -c, --check <ARG1> <ARG2>   What this option means (mandatory)
  -k, --kaka                  (mandatory)
  --map                       Another description
  -o, --ooo

The previous message is shown also if a mandatory option is not given (preceded by the error message) or if it is mispecified (for instance, if you specify a single arg for an option and it needs 2).

You can install stdio module using NPM:

npm install stdio
sgmonda
  • 2,615
  • 1
  • 19
  • 29
  • 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. – Sridhar Sarnobat Jan 24 '22 at 04:58
  • ops.printHelp() did not work for me. maybe it was true for old versions? – Nir O. Dec 17 '22 at 21:42
  • @NirO. isn't the automatic `--help` behavior enough in your case? Help must be printed. – sgmonda Dec 18 '22 at 13:15
  • the fact that printHelp() doesn't work just shades a light on the fact that this post may be outdated and other readers should pay attention that the library may no longer behave as described here, that's all. I think that "required" behavior is also different than the post but I moved on – Nir O. Dec 18 '22 at 19:52
  • Where we can put the `ops` in `` ? – Anh-Thi DINH Mar 06 '23 at 23:23
  • @Anh-ThiDINH do you mean in a HTML `` tag? I don't get it :-) – sgmonda Mar 10 '23 at 14:24
60

If your script is called myScript.js and you want to pass the first and last name, 'Sean Worthington', as arguments like below:

node myScript.js Sean Worthington

Then within your script you write:

var firstName = process.argv[2]; // Will be set to 'Sean'
var lastName = process.argv[3]; // Will be set to 'Worthington'
riper
  • 833
  • 1
  • 9
  • 17
Sean H. Worthington
  • 1,701
  • 15
  • 9
46

Simple + ES6 + no-dependency + supports boolean flags

const process = require( 'process' );

const argv = key => {
  // Return true if the key exists and a value is defined
  if ( process.argv.includes( `--${ key }` ) ) return true;

  const value = process.argv.find( element => element.startsWith( `--${ key }=` ) );

  // Return null if the key does not exist and a value is not defined
  if ( !value ) return null;
  
  return value.replace( `--${ key }=` , '' );
}

Output:

  • If invoked with node app.js then argv('foo') will return null
  • If invoked with node app.js --foo then argv('foo') will return true
  • If invoked with node app.js --foo= then argv('foo') will return ''
  • If invoked with node app.js --foo=bar then argv('foo') will return 'bar'
Andrew Odri
  • 8,868
  • 5
  • 46
  • 55
  • Is `if ( process.argv.includes( \`--${ key }\` ) )` not `true` for `--foo=bar`? I'm confused how it ever gets past that first conditional. – temporary_user_name Apr 18 '22 at 17:43
  • 1
    @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. – Andrew Odri Apr 19 '22 at 18:54
  • Oh that's so obvious now that you say it. I totally knew that and wasn't thinking. Thank you for the reminder. – temporary_user_name Apr 19 '22 at 20:06
  • 1
    @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 – Andrew Odri Apr 19 '22 at 20:40
34

command-line-args is worth a look!

You can set options using the main notation standards (learn more). These commands are all equivalent, setting the same values:

$ example --verbose --timeout=1000 --src one.js --src two.js
$ example --verbose --timeout 1000 --src one.js two.js
$ example -vt 1000 --src one.js two.js
$ example -vt 1000 one.js two.js

To access the values, first create a list of option definitions describing the options your application accepts. The type property is a setter function (the value supplied is passed through this), giving you full control over the value received.

const optionDefinitions = [
  { name: 'verbose', alias: 'v', type: Boolean },
  { name: 'src', type: String, multiple: true, defaultOption: true },
  { name: 'timeout', alias: 't', type: Number }
]

Next, parse the options using commandLineArgs():

const commandLineArgs = require('command-line-args')
const options = commandLineArgs(optionDefinitions)

options now looks like this:

{
  src: [
    'one.js',
    'two.js'
  ],
  verbose: true,
  timeout: 1000
}

Advanced usage

Beside the above typical usage, you can configure command-line-args to accept more advanced syntax forms.

Command-based syntax (git style) in the form:

$ executable <command> [options]

For example.

$ git commit --squash -m "This is my commit message"

Command and sub-command syntax (docker style) in the form:

$ executable <command> [options] <sub-command> [options]

For example.

$ docker run --detached --image centos bash -c yum install -y httpd

Usage guide generation

A usage guide (typically printed when --help is set) can be generated using command-line-usage. See the examples below and read the documentation for instructions how to create them.

A typical usage guide example.

usage

The polymer-cli usage guide is a good real-life example.

usage

Further Reading

There is plenty more to learn, please see the wiki for examples and documentation.

Lloyd
  • 8,204
  • 2
  • 38
  • 53
33

Here's my 0-dep solution for named arguments:

const args = process.argv
    .slice(2)
    .map(arg => arg.split('='))
    .reduce((args, [value, key]) => {
        args[value] = key;
        return args;
    }, {});

console.log(args.foo)
console.log(args.fizz)

Example:

$ node test.js foo=bar fizz=buzz
bar
buzz

Note: Naturally this will fail when the argument contains a =. This is only for very simple usage.

Stan James
  • 2,535
  • 1
  • 28
  • 35
grebenyuksv
  • 1,729
  • 2
  • 12
  • 9
28

There's an app for that. Well, module. Well, more than one, probably hundreds.

Yargs is one of the fun ones, its docs are cool to read.

Here's an example from the github/npm page:

#!/usr/bin/env node
var argv = require('yargs').argv;
console.log('(%d,%d)', argv.x, argv.y);
console.log(argv._);

Output is here (it reads options with dashes etc, short and long, numeric etc).

$ ./nonopt.js -x 6.82 -y 3.35 rum
(6.82,3.35)
[ 'rum' ] 
$ ./nonopt.js "me hearties" -x 0.54 yo -y 1.12 ho
(0.54,1.12)
[ 'me hearties', 'yo', 'ho' ]
Kevin Burke
  • 61,194
  • 76
  • 188
  • 305
Zlatko
  • 18,936
  • 14
  • 70
  • 123
24

proj.js

for(var i=0;i<process.argv.length;i++){
  console.log(process.argv[i]);
}

Terminal:

nodemon app.js "arg1" "arg2" "arg3"

Result:

0 'C:\\Program Files\\nodejs\\node.exe'
1 'C:\\Users\\Nouman\\Desktop\\Node\\camer nodejs\\proj.js'
2 'arg1' your first argument you passed.
3 'arg2' your second argument you passed.
4 'arg3' your third argument you passed.

Explaination:

  1. The directory of node.exe in your machine (C:\Program Files\nodejs\node.exe)
  2. The directory of your project file (proj.js)
  3. Your first argument to node (arg1)
  4. Your second argument to node (arg2)
  5. Your third argument to node (arg3)

your actual arguments start form second index of argv array, that is process.argv[2].

Nouman Dilshad
  • 1,014
  • 13
  • 16
20

whithout librairies: using Array.prototype.reduce()

const args = process.argv.slice(2).reduce((acc, arg) => {

    let [k, v = true] = arg.split('=')
    acc[k] = v
    return acc

}, {})

for this command node index.js count=2 print debug=false msg=hi

console.log(args) // { count: '2', print: true, debug: 'false', msg: 'hi' }

also,

we can change

    let [k, v = true] = arg.split('=')
    acc[k] = v

by (much longer)

    let [k, v] = arg.split('=')
    acc[k] = v === undefined ? true : /true|false/.test(v) ? v === 'true' : /[\d|\.]+/.test(v) ? Number(v) : v

to auto parse Boolean & Number

console.log(args) // { count: 2, print: true, debug: false, msg: 'hi' }
Joseph Merdrignac
  • 3,510
  • 2
  • 19
  • 16
19

Parsing argument based on standard input ( --key=value )

const argv = (() => {
    const arguments = {};
    process.argv.slice(2).map( (element) => {
        const matches = element.match( '--([a-zA-Z0-9]+)=(.*)');
        if ( matches ){
            arguments[matches[1]] = matches[2]
                .replace(/^['"]/, '').replace(/['"]$/, '');
        }
    });
    return arguments;
})();

Command example

node app.js --name=stackoverflow --id=10 another-argument --text="Hello World"

Result of argv: console.log(argv)

{
    name: "stackoverflow",
    id: "10",
    text: "Hello World"
}
Manvel
  • 750
  • 7
  • 10
15

In the node code require the built in process lib.

const {argv} = require('process')

Run the program with their arguments.

$ node process-args.js one two=three four

argv is the array that follows:

argv[0] = /usr/bin/node
argv[1] = /home/user/process-args.js
argv[2] = one
argv[3] = two=three
argv[4] = four
Hender
  • 343
  • 2
  • 10
14

Passing,parsing arguments is an easy process. Node provides you with the process.argv property, which is an array of strings, which are the arguments that were used when Node was invoked. The first entry of the array is the Node executable, and the second entry is the name of your script.

If you run script with below atguments

$ node args.js arg1 arg2

File : args.js

console.log(process.argv)

You will get array like

 ['node','args.js','arg1','arg2']
Piyush Sagar
  • 2,931
  • 23
  • 26
11
npm install ps-grab

If you want to run something like this :

node greeting.js --user Abdennour --website http://abdennoor.com 

--

var grab=require('ps-grab');
grab('--username') // return 'Abdennour'
grab('--action') // return 'http://abdennoor.com'

Or something like :

node vbox.js -OS redhat -VM template-12332 ;

--

var grab=require('ps-grab');
grab('-OS') // return 'redhat'
grab('-VM') // return 'template-12332'
Abdennour TOUMI
  • 87,526
  • 38
  • 249
  • 254
10

Native Experimental Method

Nodejs team added util.parseArgs function in versions 18.3.0 and 16.17.0. So if you use these or higher versions of nodejs you can parse command line arguments with this native solution.

An example of usage from the documentation:

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

const args = process.argv;
const options = {
  foo: {
    type: 'boolean',
    short: 'f'
  },
  bar: {
    type: 'string'
  }
};
const {
  values,
  positionals
} = parseArgs({ args, options, allowPositionals: true });

console.log(values);
console.log(positionals);

Output sample:

$ node parseargs.js -f --bar b
[Object: null prototype] { foo: true, bar: 'b' }
[
  '/Users/mbelsky/.nvm/versions/node/v18.12.1/bin/node',
  '/Users/mbelsky/parseargs.js'
]
mbelsky
  • 6,093
  • 2
  • 26
  • 34
9

You can parse all arguments and check if they exist.

file: parse-cli-arguments.js:

module.exports = function(requiredArguments){
    var arguments = {};

    for (var index = 0; index < process.argv.length; index++) {
        var re = new RegExp('--([A-Za-z0-9_]+)=([A/-Za-z0-9_]+)'),
            matches = re.exec(process.argv[index]);

        if(matches !== null) {
            arguments[matches[1]] = matches[2];
        }
    }

    for (var index = 0; index < requiredArguments.length; index++) {
        if (arguments[requiredArguments[index]] === undefined) {
            throw(requiredArguments[index] + ' not defined. Please add the argument with --' + requiredArguments[index]);
        }
    }

    return arguments;
}

Than just do:

var arguments = require('./parse-cli-arguments')(['foo', 'bar', 'xpto']);
Amadu Bah
  • 2,919
  • 28
  • 27
8

You can reach command line arguments using system.args. And i use the solution below to parse arguments into an object, so i can get which one i want by name.

var system = require('system');

var args = {};
system.args.map(function(x){return x.split("=")})
    .map(function(y){args[y[0]]=y[1]});

now you don't need to know the index of the argument. use it like args.whatever

Note: you should use named arguments like file.js x=1 y=2 to use this solution.

Evren Kutar
  • 1,173
  • 1
  • 9
  • 12
8

Passing arguments is easy, and receiving them is just a matter of reading the process.argv array Node makes accessible from everywhere, basically. But you're sure to want to read them as key/value pairs, so you'll need a piece to script to interpret it.

Joseph Merdrignac posted a beautiful one using reduce, but it relied on a key=value syntax instead of -k value and --key value. I rewrote it much uglier and longer to use that second standard, and I'll post it as an answer because it wouldn't fit as a commentary. But it does get the job done.

   const args = process.argv.slice(2).reduce((acc,arg,cur,arr)=>{
     if(arg.match(/^--/)){
       acc[arg.substring(2)] = true
       acc['_lastkey'] = arg.substring(2)
     } else
     if(arg.match(/^-[^-]/)){
       for(key of arg.substring(1).split('')){
         acc[key] = true
         acc['_lastkey'] = key
       }
     } else
       if(acc['_lastkey']){
         acc[acc['_lastkey']] = arg
         delete acc['_lastkey']
       } else
         acc[arg] = true
     if(cur==arr.length-1)
       delete acc['_lastkey']
     return acc
   },{})

With this code a command node script.js alpha beta -charlie delta --echo foxtrot would give you the following object


args = {
 "alpha":true,
 "beta":true,
 "c":true,
 "h":true,
 "a":true,
 "r":true
 "l":true,
 "i":true,
 "e":"delta",
 "echo":"foxtrot"
}
isacvale
  • 627
  • 8
  • 13
6

Although Above answers are perfect, and someone has already suggested yargs, using the package is really easy. This is a nice package which makes passing arguments to command line really easy.

npm i yargs
const yargs = require("yargs");
const argv = yargs.argv;
console.log(argv);

Please visit https://yargs.js.org/ for more info.

Akshay Rajput
  • 1,978
  • 1
  • 12
  • 22
6

TypeScript solution with no libraries:

interface IParams {
  [key: string]: string
}

function parseCliParams(): IParams {
  const args: IParams = {};
  const rawArgs = process.argv.slice(2, process.argv.length);
  rawArgs.forEach((arg: string, index) => {
    // Long arguments with '--' flags:
    if (arg.slice(0, 2).includes('--')) {
      const longArgKey = arg.slice(2, arg.length);
      const longArgValue = rawArgs[index + 1]; // Next value, e.g.: --connection connection_name
      args[longArgKey] = longArgValue;
    }
    // Shot arguments with '-' flags:
    else if (arg.slice(0, 1).includes('-')) {
      const longArgKey = arg.slice(1, arg.length);
      const longArgValue = rawArgs[index + 1]; // Next value, e.g.: -c connection_name
      args[longArgKey] = longArgValue;
    }
  });
  return args;
}

const params = parseCliParams();
console.log('params: ', params);

Input: ts-node index.js -p param --parameter parameter

Output: { p: 'param ', parameter: 'parameter' }

rmolinamir
  • 1,121
  • 14
  • 15
5

Without libraries

If you want to do this in vanilla JS/ES6 you can use the following solution

worked only in NodeJS > 6

const args = process.argv
  .slice(2)
  .map((val, i)=>{
    let object = {};
    let [regexForProp, regexForVal] = (() => [new RegExp('^(.+?)='), new RegExp('\=(.*)')] )();
    let [prop, value] = (() => [regexForProp.exec(val), regexForVal.exec(val)] )();
    if(!prop){
      object[val] = true;
      return object;
    } else {
      object[prop[1]] = value[1] ;
      return object
    }
  })
  .reduce((obj, item) => {
    let prop = Object.keys(item)[0];
    obj[prop] = item[prop];
    return obj;
  }, {});

And this command

node index.js host=http://google.com port=8080 production

will produce the following result

console.log(args);//{ host:'http://google.com',port:'8080',production:true }
console.log(args.host);//http://google.com
console.log(args.port);//8080
console.log(args.production);//true

p.s. Please correct the code in map and reduce function if you find more elegant solution, thanks ;)

Cassidy
  • 317
  • 3
  • 5
  • 1
    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 }, {})``` – Joseph Merdrignac Oct 13 '17 at 12:23
5

The simplest way of retrieving arguments in Node.js is via the process.argv array. This is a global object that you can use without importing any additional libraries to use it. You simply need to pass arguments to a Node.js application, just like we showed earlier, and these arguments can be accessed within the application via the process.argv array.

The first element of the process.argv array will always be a file system path pointing to the node executable. The second element is the name of the JavaScript file that is being executed. And the third element is the first argument that was actually passed by the user.

'use strict';

for (let j = 0; j < process.argv.length; j++) {  
    console.log(j + ' -> ' + (process.argv[j]));
}

All this script does is loop through the process.argv array and prints the indexes, along with the elements stored in those indexes. It's very useful for debugging if you ever question what arguments you're receiving, and in what order.

You can also use libraries like yargs for working with commnadline arguments.

Rubin bhandari
  • 1,873
  • 15
  • 20
4

You can get command-line information from process.argv()

And I don't want to limit the problem to node.js. Instead, I want to turn it into how to parse the string as the argument.

console.log(ArgumentParser(`--debug --msg="Hello World" --title="Test" --desc=demo -open --level=5 --MyFloat=3.14`))

output

{
  "debug": true,
  "msg": "Hello World",
  "title": "Test",
  "desc": "demo",
  "open": true,
  "level": 5,
  "MyFloat": 3.14
}

code

Pure javascript, no dependencies needed

//  Below is Test
(() => {
  window.onload = () => {
    const testArray = [
      `--debug --msg="Hello World" --title="Test" --desc=demo -open --level=5 --MyFloat=3.14`,
    ]
    for (const testData of testArray) {
      try {
        const obj = ArgumentParser(testData)
        console.log(obj)
      } catch (e) {
        console.error(e.message)
      }
    }
  }
})()

//  Script
class ParserError extends Error {

}

function Cursor(str, pos) {
  this.str = str
  this.pos = pos
  this.MoveRight = (step = 1) => {
    this.pos += step
  }

  this.MoveToNextPara = () => {
    const curStr = this.str.substring(this.pos)
    const match = /^(?<all> *--?(?<name>[a-zA-Z_][a-zA-Z0-9_]*)(=(?<value>[^-]*))?)/g.exec(curStr) // https://regex101.com/r/k004Gv/2
    if (match) {
      let {groups: {all, name, value}} = match

      if (value !== undefined) {
        value = value.trim()
        if (value.slice(0, 1) === '"') { // string
          if (value.slice(-1) !== '"') {
            throw new ParserError(`Parsing error: '"' expected`)
          }
          value = value.slice(1, -1)
        } else { // number or string (without '"')
          value = isNaN(Number(value)) ? String(value) : Number(value)
        }
      }

      this.MoveRight(all.length)
      return [name, value ?? true] // If the value is undefined, then set it as ture.
    }
    throw new ParserError(`illegal format detected. ${curStr}`)
  }
}

function ArgumentParser(str) {
  const obj = {}
  const cursor = new Cursor(str, 0)
  while (1) {
    const [name, value] = cursor.MoveToNextPara()
    obj[name] = value
    if (cursor.pos === str.length) {
      return obj
    }
  }
}
Carson
  • 6,105
  • 2
  • 37
  • 45
4

NodeJS exposes a global variable called process.

we can use:

process.argv

to get the command line arguments passes to our script.

The output of process.argv will be a list in the following order:

[
full-path-to-node-executable,
full-path-to-the-script-file
...additonal-arguments-we-provide
]
Idan Krupnik
  • 443
  • 1
  • 6
  • 8
3

process.argv is your friend, capturing command line args is natively supported in Node JS. See example below::

process.argv.forEach((val, index) => {
  console.log(`${index}: ${val}`);
})
Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
bhwp
  • 41
  • 3
3

ES6-style no-dependencies solution:

const longArgs = arg => {
    const [ key, value ] = arg.split('=');
    return { [key.slice(2)]: value || true }
};

const flags = arg => [...arg.slice(1)].reduce((flagObj, f) => ({ ...flagObj, [f]: true }), {});


const args = () =>
    process.argv
        .slice(2)
        .reduce((args, arg) => ({
            ...args,
            ...((arg.startsWith('--') && longArgs(arg)) || (arg[0] === '-' && flags(arg)))
        }), {});

console.log(args());
shreyasm-dev
  • 2,711
  • 5
  • 16
  • 34
tibalt
  • 15,201
  • 1
  • 29
  • 22
3

I extended the getArgs function just to get also commands, as well as flags (-f, --anotherflag) and named args (--data=blablabla):

  1. The module
/**
 * @module getArgs.js
 * get command line arguments (commands, named arguments, flags)
 *
 * @see https://stackoverflow.com/a/54098693/1786393
 *
 * @return {Object}
 *
 */
function getArgs () {
  const commands = []
  const args = {}
  process.argv
    .slice(2, process.argv.length)
    .forEach( arg => {
      // long arg
      if (arg.slice(0,2) === '--') {
        const longArg = arg.split('=')
        const longArgFlag = longArg[0].slice(2,longArg[0].length)
        const longArgValue = longArg.length > 1 ? longArg[1] : true
        args[longArgFlag] = longArgValue
     }
     // flags
      else if (arg[0] === '-') {
        const flags = arg.slice(1,arg.length).split('')
        flags.forEach(flag => {
          args[flag] = true
        })
      }
     else {
      // commands
      commands.push(arg)
     } 
    })
  return { args, commands }
}


// test
if (require.main === module) {
  // node getArgs test --dir=examples/getUserName --start=getUserName.askName
  console.log( getArgs() )
}

module.exports = { getArgs }

  1. Usage example:
$ node lib/getArgs test --dir=examples/getUserName --start=getUserName.askName
{
  args: { dir: 'examples/getUserName', start: 'getUserName.askName' },
  commands: [ 'test' ]
}

$ node lib/getArgs --dir=examples/getUserName --start=getUserName.askName test tutorial
{
  args: { dir: 'examples/getUserName', start: 'getUserName.askName' },
  commands: [ 'test', 'tutorial' ]
}

shreyasm-dev
  • 2,711
  • 5
  • 16
  • 34
Giorgio Robino
  • 2,148
  • 6
  • 38
  • 59
3

Solution using Set to solve the position issue if using simple args (without key+values).

For example both commands will return same result:

node server.js detail json
node server.js json detail
const args = new Set(process.argv.slice(2));

Then one can use args.has('detail') or args.has('json') without worrying about position.

John Lee
  • 893
  • 13
  • 14
2

Use the minimist npm package. it is the easiest method and don't need to worry about anything.

const arguments = require("minimist")(process.argv.slice(2)); 
// get the extra argument of command line . 
eg node app.js --process="sendEmailWithReminder"

We can use it in windows task scheduler too.

enter image description here

enter image description here

enter image description here

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
1

as stated in the node docs The process.argv property returns an array containing the command line arguments passed when the Node.js process was launched.

For example, assuming the following script for process-args.js:

// print process.argv
process.argv.forEach((val, index) => {
   console.log(`${index}: ${val}`);
});

Launching the Node.js process as:

 $ node process-args.js one two=three four

Would generate the output:

0: /usr/local/bin/node
1: /Users/mjr/work/node/process-args.js
2: one
3: two=three
4: four
Adeojo Emmanuel IMM
  • 2,104
  • 1
  • 19
  • 28
1

Most of the people have given good answers. I would also like to contribute something here. I am providing the answer using lodash library to iterate through all command line arguments we pass while starting the app:

// Lodash library
const _ = require('lodash');

// Function that goes through each CommandLine Arguments and prints it to the console.
const runApp = () => {
    _.map(process.argv, (arg) => {
        console.log(arg);
    });
};

// Calling the function.
runApp();

To run above code just run following commands:

npm install
node index.js xyz abc 123 456

The result will be:

xyz 
abc 
123
456
S.Mishra
  • 3,394
  • 28
  • 20
0

The original question was asking to pass command line arguments, not about more complex parsing of arguments. Yet with all the complex answers, they all missed one simple, useful variation.

Did you know that the Unix shell supports named arguments? This dates back to the original Bourne shell in the 1980s. Usage is simple:

$ FOO=one BAR=two nodejs myscript.js

To fetch the parameters in Javascript:

var foo = process.env.FOO;
var bar = process.env.BAR;

Named parameters are much easier to read, once you get past two or three parameters. Optional parameters are simple, and order is not fixed.

(This might even work on Windows, with the recent support for Unix shells.)

Also, shockingly few Unix programmers know of this usage. :)

  • These aren't "named parameters" as such, they are environment variables. – CherryDT Feb 23 '22 at 16:56
  • They are parameters, and they are named. That they are environment variables is incidental. Or perhaps you have some other definition? :) – Preston L. Bannister Feb 24 '22 at 04:12
  • 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. – CherryDT Feb 24 '22 at 09:01
  • 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. – Preston L. Bannister Mar 06 '22 at 05:18
  • 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 Mar 06 '22 at 12:26
  • 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. – CherryDT Mar 06 '22 at 12:37
0

Typescript way to do it with minimist.

npm i minimist @types/minimist

app.ts

// import
import { MyProgram } from './main';

// libraries
import minimist from 'minimist';

// interfaces
import { ParsedArgs } from 'minimist';

// code
const args: ParsedArgs = minimist(process.argv.slice(2));

let app = new MyProgram(args.a).getApp();
export { app };

Command to run after compiling to JavaScript with gulp

node app.js -a MyParam

xinthose
  • 3,213
  • 3
  • 40
  • 59
-1

You can use Rest operator to accept n numbers of arguments in a function and use it like this i have posted a sample program i hope which will help you to get the point.

    function sum(...theArgs) {
  let total = 0;
  for (const arg of theArgs) {
    total += arg;
  }
  return total;
}

console.log(sum(1, 2, 3));
// Expected output: 6

console.log(sum(1, 2, 3, 4));
// Expected output: 10

    enter code here
-3

A simple snippet if any need it:

var fs = require('fs'), objMod = {};

process.argv.slice(2).map(function(y, i) {
  y = y.split('=');
  if (y[0] && y[1]) objMod[y[0]] = y[1];
  else console.log('Error in argument number ' + (i+1));
});
MatCas
  • 773
  • 8
  • 19