Creating a command-line app in Node.js: Argument Parsing
Tags: javascript, tutorial, npm, node
Published: 2019-12-28 10:09:14

This article is in the continuity of [part 1](https://dev.to/kumar_abhirup/a-starter-guide-to-create-a-command-line-app-in-node-js-41hn). So before you proceed, please make sure you have followed the steps in part 1. :)

In Part 1, we learned about how a Node App can be run like it is a CLI. In this post, we will learn about **Argument parsing in command-line app**.

## What is `argument parsing` in a CLI?

If you have ever used CLIs like `git` and `yarn`, you know you have to pass a `--flag` as a suffix to the CLI command.

_For eg. `npm install`._ Here, `install` is an argument passed to the `npm` command that tells Node Package Manager to install a package.

In the same way, your CLI might need a different set of predefined arguments (also called 'parameters') to work properly. It is often used for doing different tasks and features in a CLI.

## Argument parsing in Node.js

- Create a file named `index.js`...

- In the file, paste the below code.
```js
console.log(process.argv)
```

- Now, in the terminal, run the following command to get the given output.
```bash
$ node index.js wow this is an argument

# Output 👇

[ 'node',
  '/home/username/Desktop/index.js',
  'wow',
  'this',
  'is',
  'an',
  'argument' ]
```

**Now, you can use the output you get to detect what argument is passed and you can make your CLI behave accordingly.**

## Better Argument Parsing

`process.argv` is the very fundamental line of code to know what argument is being passed.

In a CLI, you'll have to make users use a combination of commands to do certain things. _For eg. `npm install -g bulk-mail-cli`._ Here, `install` is passed as an argument and `-g` (`--global`) as a flag.

Computing what all the combinations will do in a CLI can be a hefty task. Therefore, it is recommended that you use **tried and tested libraries for argument parsing and its detection.**

## Libraries to parse arguments and flags.

- [Commander](https://www.npmjs.com/package/commander) (I recommend this)
- [Minimist] (https://www.npmjs.com/package/minimist)
- [Meow] (https://github.com/sindresorhus/meow)

## Commander

Let us see how `Commander` works. In Part 1, we created a demo CLI project. Continue coding in the `index.js` of the same coding project.

> The tutorial below will be relevant only if you have read Part 1 of the series.

Define the module.
```js
const commander = require('commander')
```

To use it in your program, paste the following code...
```js
commander
    .version('v0.0.1')
    .description('This is a dummy demo CLI.')
    .option('-n, --name <type>', 'To input a name')
    .option('demo', 'To output demo')
    .parse(process.argv)
```

The above lines of code will now help you parse and read the `--version`, `-n`, `--name`, `demo` arguments.

###  Reading the arguments

To read the argument, you now have to simply do the following...
```js
// Runs only if `name` argument is passed with a `<type>`...
if (commander.name) console.log(`Your name is ${commander.name}.`)

// Runs only if `demo` argument is passed...
if (commander.demo) console.log(`This is a DEMO.`)
```

## Try it out!

If you have continued from Part 1, then you have a `package.json` already created. `cd` in the directory where your code is stored and run the following in the terminal...

```bash
$ thisDemoCli demo
This is a DEMO.

$ thisDemoCli --name "Kumar Abhirup"
Your name is Kumar Abhirup.

$ thisDemoCli --version
v0.0.1
```

**Hooray! Now you are successfully parsing the arguments and doing something with it!**

I hope this article helps you understand the fundamentals of how a Command-Line app works in Node.js.

---

# About me

**I am Kumar Abhirup, a 16-year-old JavaScript React developer from India who keeps learning a new thing every single day.**

[Connect with me on Twitter 🐦](https://twitter.com/kumar_abhirup)
[My personal website and portfolio 🖥️](https://kumar.now.sh)

_Comment below your better ways, and suggestions to improve this article. :)_