Command Line Arguments in Node.js

What are Command Line Arguments?

Command line arguments are strings of text used to pass additional information to a program when an application is run through the command line interface (CLI) of an operating system. Command line arguments typically include information used to set configuration or property values for an application.

In most cases the arguments are passed after the program name in your prompt. An example of the syntax of command line arguments looks like this:

$ [runtime] [script_name] [argument-1 argument-2 argument-3 ... argument-n]

Here runtime can be anything that executes a program/script e.g. sh, java, node, etc. The arguments are usually separated by a space - however there are some runtimes that use commas to distinguish between multiple command line arguments. Also, depending on the program, you can pass arguments in the form of key-value pairs, which we'll see later in this article.

Why Use Command Line Arguments?

The following are some of the major benefits of using command line arguments:

  • You can pass information to an application before it starts. This is particularly useful if you want to perform large number configuration settings.
  • Command line arguments are passed as strings to your program. String data types can easily be converted to other data types within an application, making the arguments very flexible.
  • You can pass unlimited number of arguments via the command line.
  • Command line arguments are used in conjunction with scripts and batch files, which is particularly useful for automated testing.

And here are some of the disadvantages of using them:

  • The biggest disadvantage of passing information via the command line is that interface has steep learning curve, so it's difficult for most people to use unless they have a good deal of experience using CLI tools.
  • Command line applications can be difficult to use unless you're using a desktop or laptop computer, so they're not typically used on smaller devices like phones or tablets.

Passing Command Line Arguments in Node.js

Like many other languages, Node.js applications also accept command line arguments. By default Node will handle accepting the arguments for you, but there are also some great third party packages that add some very useful features.

In this section we'll show you how to use arguments via the built-in way (process.argv), as well as with the popular packages minimist and yargs.

Using process.argv

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.

To avoid confusion, I'd like to remind you beginners out there that JavaScript uses zero-based indexes on arrays (like many other languages), which means that first element will be stored at "0th" index and last element will be stored at "n-1" index, where "n" is the total number of elements in the array.

Now let's write a simple Node script that prints all of the command line arguments passed to the application, along with their index. Copy and paste the following code to a file named "processargv.js".

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

Now, to run this type the following command. Just make sure you are in the directory where the "processargv.js" file is saved.

$ node processargv.js tom jack 43

Here we are passing three arguments to the "processargv.js" program. You will see that "tom" will be stored at 2nd index while "jack" and "43" will be stored at 3rd and 4th indexes, respectively. The output should look something like this:

$ node processargv.js tom jack 43
0 -> /Users/scott/.nvm/versions/node/v4.8.0/bin/node  
1 -> /Users/scott/javascript/processargv.js  
2 -> tom  
3 -> jack  
4 -> 43  

You can see that first index contains the path to our node executable (which will likely have a different path than mine), the second index contains the path to the script file, and the rest of the indexes contain the arguments that we passed in their respective sequence.

Using the minimist Module

Another way to retrieve command line arguments in a Node.js application is using the minimist module. The minimist module will parse arguments from the process.argv array and transform it in to an easier-to-use associative array. In the associative array you can access the elements via index names in addition to the index numbers. Take a look at the following example.

'use strict';

const args = require('minimist')(process.argv.slice(2));

console.log(args);  
console.log(args.i);  

Save the above code in "minimist.js". In the above code we use the slice method of the process.argv global object. The slice method, in this case, removes all prior array elements starting from the index passed to it as the parameter. Here we know that the argument we manually pass are stored starting from the second index, we passed 2 to the slice function. We then printed the entire args object. We also printed single element of the array using the named index i.e. "i", rather than the index number.

Now when we pass argument to this program we can also specify the character by which we want to access the element. Since in the script we use the "i" index name to access the element, we have to specify the element stored at this index. Take a look at the script to execute the above program.

$ node minimist.js –i jacob –j 45

Notice here we specified "i" as the name for second index the value stored at that index is "jacob". Similarly the third index is named as "j" and value at this index is 45. The output of above command will be as follows:

$ node minimist.js -i jacob -j 45
{ _: [], i: 'jacob', j: 45 }
jacob  

While not as feature-rich as some of the other arg-parsing modules (see yargs below), minimist has a few useful features you may want to look in to, like aliasing and defaults.

If you set an alias, then the caller of your program can use the alias in addition to the regular option name. This is useful if you want to have a shorthand notation for your options, as seen below:

'use strict';

const minimist = require('minimist');

let args = minimist(process.argv.slice(2), {  
    alias: {
        h: 'help',
        v: 'version'
    }
});

console.log('args:', args);  

Calling this code with the -h option sets both h: true and help: true in the output args:

$ node minimist-alias.js -h
args: { _: [], h: true, help: true }  

As for minimist's defaults feature, if no value is passed for an option then the default you set in your program will be used automatically.

'use strict';

const minimist = require('minimist');

let args = minimist(process.argv.slice(2), {  
    default: {
        port: 8080
    },
});

console.log('args:', args);  

Calling this code without the -port option still yields you with a port value in the returned args object:

$ node minimist-defaults.js
args: { _: [], port: 8080 }  

For more options, check out the README.

Using the yargs Module

Another module to help you parse command line arguments passed to Node programs is the yargs module. Using this module you can pass arguments in the form of key-value pairs and later access the argument values in your program using corresponding keys.

Note: You can install the yargs module with the following command:

$ npm install yargs

Now, take a look at the following script:

'use strict';

const args = require('yargs').argv;

console.log('Name: ' + args.name);  
console.log('Age: ' + args.age);  

In the above script we display the values provided for the 'name' and 'age' arguments, which were passed via the command line. Now save the above script in a file named "yargs.js".

Note: When you execute above program you have to pass values for 'name' and 'age' arguments, otherwise undefined will be given for the arguments by default and you will see undefined written to the console.

To execute above program, execute the following command in your prompt:

$ node yargs.js --name=jacob --age=45

Here we are passing values for both name and age arguments. The output of above script will look like this:

$ node yargs.js --name=jacob --age=45
Name: jacob  
Age: 45  

The yargs package is a very powerful one, not only providing the standard arg-parsing features but many advanced features as well. While we won't go through all of the features in this article, we'll at least touch on one of its most popular features.

One of the most powerful ways to use yargs is the .command() option, which helps you create, expose, and call Node functions via the command line. Here is a simple example of this feature in action:

'use strict';

const argv = require('yargs')  
    .command('upload', 'upload a file', (yargs) => {}, (argv) => {
        console.log('Uploading your file now...');

        // Do stuff here
    }).argv;

Calling this program with the "upload" command will invoke the function you passed to it, which in this case just prints to the command line. However, I'm sure you can imagine passing a much more capable function that uses the parsed argv object to determine what file to send where.

For example, this command could be called like this (assuming the code above is stored in a file called "s3-tool.js":

$ node s3-tool.js upload --file=my-file.txt --bucket=my-s3-bucket
Uploading your file now...  

And you don't have to stop there, you can even create a default command:

'use strict';

const argv = require('yargs')  
    .command('*', 'the default command handler', () => {}, (argv) => {
        console.log('This function is called by default');
    }).argv;

The .command() feature is even powerful enough to infer your required and optional parameters from a string:

'use strict';

const yargs = require('yargs');

yargs.command('login <username> [password]', 'authenticate with the server').argv  

For more information on the advanced features, check out the yargs advanced topics documentation.

Conclusion

It might be a bit surprising to you, but as you may have noticed, argument parsing can actually be a pretty complex topic. Depending on your needs you can make it as simple or complicated as you want. Regardless, there is a suitable solution for all needs, whether it's the basic process.argv array or the powerful yargs package.

How have you used minimist and yargs to create CLI programs? Let us know in the comments!