How to write cli application in Nodejs?

Javascript is created to be used in the web browser, however now we can create command line application with nodejs.

Nodejs come with useful built in library, some of which can be used to create command line applications. To begin, let's explore what a command line application is?

What is command line application?

If you are new in programming, you are probably confused with the term comman line or cmd. However, let me explain it in a simple manner.

Command line applications are executable programs that work without the use of a graphical user interface. They can only accept input and output.

Node.js itself is a command line program. It takes an input, which is a file, and then sends the file to a processor to process.

Example :

node cli.js

Or if no input from the commanline arguments it will prompt a javascript interpreter.

So here's an example of nodejs interpreter :

node
Welcome to Node.js v12.13.0.
Type ".help" for more information.
> var name = "Ahmad Rosid"
> console.log(name)
Ahmad Rosid
>

So most of the cmd application only work with text, but it very useful and easy to create.

Let's write cli app

We are going to create a cli application today using nodejs, which will generate file from template the user will need to input file name and title. It is actually this app that I use to write this blog post.

So here is the example of how it works.

node cli.js
yarn run v1.22.10
$ node src/lib/cli.js
Slug: test-post
Title: Test post
File created: ./posts/test-post.md
---
title: "Test post"
date: "2021-09-21T05:28:46.306Z"
image: "/images/"
image_author: ""
image_author_url: ""
published: true
---

Get user input via stdin

In order to get user input we can use nodejs builtin library called readline.

const readLine = require("readline")

And then we need to create promise wrapper around it to make it easier to work with.

function ask(query) {
    const input = readLine.createInterface({
        input: process.stdin,
        output: process.stdout
    })

    return new Promise(resolve => input.question(query, answer => {
        input.close()
        resolve(answer)
    }))
}

So now we can get user input just like this.

const slug = await ask("Slug: ")
const title = await ask("Title: ")

Format string

One more builtin library from nodejs is util we will use this to work with string, since we will generate text from template.

Let's create template for the blog post :

const template = `---
title: "%s"
date: "%s"
image: "/images/"
image_author: ""
image_author_url: ""
published: true
---
`

And then format the string using util, we are adding title and date to template :

const util = require("util")

...

const date = new Date()
const out = util.format(template, title, date)

And we need to have file path to save the generated text that we have.

const filePath = util.format("./posts/%s.md", slug)

Save File

Now we come to the last part which is saving the text to the file, for that we are going to use another builtin library from nodejs to work with file system and the library called fs.

const fs = require("fs")

...

fs.writeFileSync(filePath, out)

And that's all now we have cli application to generate file from the template, in this case is for my blog post template. Now it's your turn to create cli for your need.