I am Hack Sparrow
Captain of the Internets.

Command line Node.js Programs / Scripts / Utilities / Modules

How to write command line programs in Node.js

Ever wondered how to create command line Node.js scripts? If not, go through Node's in-built modules like Child Process, File System, Readline, and Process and see if they inspire you in any way. If not, you can skip this post. Else, this post will take you to the next level of Node Fu.

We will write a command line utility called nodels, which will work something like the Linux ls command with the -la option.

Let's set up the project:

$ mkdir nodels
$ cd nodels
$ touch nodels.js

Use a text editor and copy the following to nodels.js.

var exec = require('child_process').exec;
var child = exec('ls -la', function(err, stdout, stderr) {
    if (err) throw err;
    else console.log(stdout);
});

nodels.js is a functional command line script, you can execute it this way:

$ node nodels.js 
total 12
drwxrwxr-x 2 hacksparrow hacksparrow 4096 2012-02-26 11:58 .
drwx------ 7 hacksparrow hacksparrow 4096 2012-02-26 11:17 ..
-rw-rw-r-- 1 hacksparrow hacksparrow 153 2012-02-26 11:58 nodels.js

Ok that's cool, but what's with the extra node infront of the script? Can't it be more integrated?

We are having to type node infront of the script to execute it using node. Just a line of code at the top of the script can fix it. It tells the system what to execute the script with.

#! /usr/bin/env node
var exec = require('child_process').exec;
var child = exec('ls -la', function(err, stdout, stderr) {
    if (err) throw err;
    else console.log(stdout);
});

Now change the permissions of the script to make it executable and run it just as you would any script.

$ chmod 755 nodels.js
$ ./nodels.js 
total 12
drwxrwxr-x 2 hacksparrow hacksparrow 4096 2012-02-26 12:10 .
drwx------ 7 hacksparrow hacksparrow 4096 2012-02-26 11:17 ..
-rwxr-xr-x 1 hacksparrow hacksparrow 175 2012-02-26 12:10 nodels.js

Can we do away with ./ and make it work like a real Linux command? You know, just execute it without any prefixes and stuff. I have seen some Node modules work like that, Express.js for example.

Good news - yes, you can. But it comes at a small price - you need to create a Node module, a global one.

Create a package.json file in the directory to mark it as a Node module directory:

$ touch package.json

Add the following to package.json:

{
"name": "nodels",
"version": "0.0.1",
"description": "List all the files in a directory, even hidden ones!",
"preferGlobal": "true",
"bin": { "nodels": "nodels.js" },
"author": "Hack Sparrow ",
"engines": { "node": "*" }
}

Note the bin field. nodels is the name of our command, nodels.js is the file that will do the execution.

Now link the module to make it available system-wide.

$ npm link

If you make any changes to the package.json bin field, you will need to link the project again for the changes to take effect.

Now nodels is available as a system command. Let's give it a spin:

$ nodels
total 16
drwxrwxr-x 2 hacksparrow hacksparrow 4096 2012-02-26 12:31 .
drwx------ 7 hacksparrow hacksparrow 4096 2012-02-26 11:17 ..
-rwxr-xr-x 1 hacksparrow hacksparrow 174 2012-02-26 12:28 nodels.js
-rw-rw-r-- 1 hacksparrow hacksparrow 278 2012-02-26 12:30 package.json

Wooohooo! There you have it - your own command, your own system utility written in Node.js.

Though you have created a command line utility using Node.js, it is confined only to your system. Want to create a global Node module that everyone can install using NPM? Read this post on creating NPM packages.

One Response to “Command line Node.js Programs / Scripts / Utilities / Modules”

  1. aoakenfo says:

    For global installation, an alternative solution is to simply move the file into a dir that’s located in PATH. For example, /usr/bin is in my PATH, so:

    > sudo mv nodels.js /usr/bin/nls
    > nls

Make a Comment