What is a command line application? Usually it means a program that is ran via the command line. It can be a simple script that changes your working directory. Or it can be a complicated program that has a multitude of options and arguments. Examples of command line applications are mutt, irssi, htop.
You can write a command line application using most programming languages. Today, dynamically typed programming languagues are popular choices for writing such scripts. Reason being they tend to be shorter to write and easy to learn. A short startup time is also important. If a script only takes a fraction of a second to run, and startup time takes 5s, it makes the script feels slow. Examples are the JVM languages. Node.js fits the bill for all these cases. Let’s take a look to see how we can write a command line application using Node.js.
In Node.js, there are many libraries that can help you to write a command line application. Which to choose? There are a few main features that all these libraries provide:
- Option parsing
- Interactive prompt
- Usage/help message helpers
- Interface elements(progress bars, coloring, password input, spinners, etc)
Let us classify the libraries.
All in one
These libraries provides all the major features. CLI provides input parsing as well.
Specialist option parsers
These libraries only do option parsing
Interactive prompt is like a sub shell. You can run custom commands in it. Good examples are node interactive shell and irb.
Components of a command line application
We can break a command line application into separate components. Namely, the entry point, arguments and options, output, documentation, configuration and distribution. I’ll be using the twitter search app as an example for illustrating the components.
Entry point is the executable script which starts the program. Typically there’re 3 ways to run a command line application.
One way is to indicate both the program loader and the path to the script. Assuming you have installed the example application and is now on the project root.
A shorter way is to indicate just the path to the script. Don’t forget to make the script executabe by changing the permissions. Another caveat is, if the path to the program loader is wrong, the program won’t run correctly.
It is possible to do that because of the shebang) line present on the first line of the script. The shebang line hints to the operating system which program loader to use. You are encouraged to use it in your own scripts.
Here is an example of the shebang line used in the example application
It can be even shorter if the script is placed in the PATH directories.
The operating system will find the script and run it. The only caveat is you have to install the script there.
By convention, scripts meant to be executed are placed in the bin directory of your project.
Arguments and options
A complex command line application usually takes in arguments and options. An option(or flag or switch) is used by the program to modify the operation. In Unix like systems, it is usually indicated by a hyphen-minus followed by a letter or word. Using node as an example.
node is the command and -v is the option.
For the example application, I chose Optimst because of its simplicity. Accessing the options is very easy as illustrated below
Optimist parses the option and makes it accessible via the argv object. For example when running the command
Optimist parses the arguments and options and returns argv in an object like this:
1 2 3 4 5
The r option value is placed under the r property and the rest of the arguments are in the underscore array.
If your command line application need to show output, you can do so using plain old console.log.
It comes with logging levels like info, warn and error which also comes in color. Applying them is as easy as
There’re plenty of other features to Winston. Feel free to explore the library.
If you want to add colors to your text output, you can make use of Colors.js. Applying colors is very easy.
Typically a command line application comes with documentation in the form of man pages. In fact NPM does comes with man pages. NPM generates its man pages via the RonnJS package. It generates man pages from a Markdown file. You can also use the Ronn ruby gem directly. DailyJS did a good write up on generating man pages in Node.js.
Your application should also come with HTML documentation.
If your command line application has a lot of options, a configuration file could help. Let’s take a look at Mocha. Mocha has a mocha.opts file which you can state the common options that you want included.
Adding a configuration file feature is as easy as reading from file. But do note that by convention, the option stated on the command line has higher precendence. Which means if I stated an option to print the output in green, but the option in the configuration file says it should be red, you should render it in green. Here’s the conventional order of precedence in overriding configurations.
- Command line options
- Configuration file options
- Application default options
If the user installs the package locally like this
The program’s executable script would be found in 2 places:
NPM adds a symbolic link from the .bin directory to your script.
If the user chose to install your package globally like this:
Despite the relative youth of the Node.js eco-system, all the pieces required for building a command line application are already there. Feel free to give the example application a run to see how easy it is to build one in Node.js.