Notes on creating a CLI in NodeJS

Because I just did that.

Creating the CLI application

After running npm init to create a package.json, I usually create a cli.js file that runs the app. (I reserve index.js for exports).

The first line should be:

#!/usr/bin/env node

even before the requires, so that various terminals know to run the file using NodeJS. I’m on Windows, so it typically doesn’t do anything, but it does light up differently on my terminal.

I tend to use minimist to do argument parsing, because I cannot remember how NodeJS deals with it otherwise. There are more sophisticated tools like oclif, but for a simple one-file program minimist is enough.

The result looks something like this (the example is from a program to convert a custom file format to fountain scripts):

#!/usr/bin/env node

const stageToFountain = require('./index')
const argv = require('minimist')(process.argv.slice(2));
const fs = require('fs')

if (!argv._ || argv._.length === 0) {
    console.log('Usage: stage-fountain input-file.stage optional-file-2.stage -o outputfile.fountain')
    return;
}

let str = ''
for (let file of argv._) {
    const fileString = fs.readFileSync(file, 'utf-8')
    const fountainString = stageToFountain(fileString)

    str += fountainString + '\n\n'
}

if (argv.o) {
    fs.writeFileSync(argv.o, str)
} else {
    console.log(str)
}

NPM

To get NPM to install the program as a CLI, add the following lines to package.json:

    "bin": {
        "name-of-tool": "./cli.js"
    }

You can then go to the parent directory of the project, and run

$ npm install -g ./path-to-project

to be able to use the tool globally.