Simple interactive CLI tool in Node/Javascript
Rohit Ambre
Posted on March 25, 2024
I was always fascinated with CLI tools provided by different applications, thinking that how simple and easy commands on CLI can result into such a big actions which can take quite a time to navigate through the UI.
At my workplace I had one task that has to be done manually every time there's a need of doing it, which is a step-by-step process so I was thinking of automating it my level. I had two options, one is creating a small UI and other one is creating CLI tool. Me already wanting to create a CLI tool obviously chose a CLI tool 🤩.
Here I will give you a small example about how can you create simple but very effective CLI tool in nodeJS
Using Commander and inquirer packages.
Requirement
If you're going to use inquirer
NodeJS version >=
v18.12.0
We're going to create a small Burger maker tool, which will accept inputs about bread, patty, toppings etc
-
Commander
is used to create CLI tool with commands and flags. -
inquirer
provides ability to ask questions, interactivity and actions on the basis of answers.
Implementation
Start a new javascript project with npm init -y
inquirer v9
uses esm modules hence you cannot use commonjs
syntax, to change your project to use module import/export change type
property in your package.json
file to module
. You can read more about esm modules here.
Import commander
and inquirer
import { Command } from 'commander';
import inquirer from 'inquirer';
create a new Program using Command
class and add name along with some description.
const program = new Command();
program
.name('burger-maker')
.description('Order a burger from CLI')
.version('1.0.0');
program.parse();
Now, try running your basic command on terminal.
It should display command description with available options.
Now, add order
command to the program and create basic questions using inquirer prompts
const prompts = [
{
name: 'name',
message: 'Your Name?',
validate: function(name) {
if (!name) {
return "Name is required"
}
return true
}
},
{
name: 'bun',
message: 'Choose a bun?',
type: 'rawlist',
choices: ['Classic', 'Whole Wheat', 'Gluten Free'],
default: 'Classic'
},
{
name: 'patty',
message: 'Choose a patty?',
type: 'rawlist',
choices: ['Veg', 'Chicken', 'Today\'s Special'],
default: 'Veg'
},
{
name: 'toppings',
message: 'Choose your favourite toppings',
type: 'checkbox',
choices: ['Tomato', 'Lettuce', 'Cheese', 'Onion']
},
{
name: 'sauces',
message: 'Choose your favourite sauces',
type: 'checkbox',
choices: ['Mayonnaise', 'Ketchup', 'Mustard']
},
]
These prompts are self explanatory, there are different types of prompts offered by inquirer like input, list, rawlist, checkbox, password
etc. Prompts with documentations can be found here github
Add action
listener on created order
command like below
.command('order')
.description('Order a burger')
.action(async function(){
const answers = await inquirer.prompt(prompts)
console.log(answers)
})
Now, when you run your order
command you'll get prompts to input the order details.
At this point you can do whatever with the response, you can make http
api call and save in database.
You can also make nested prompts to gather more information about particular item like below
const answers = await inquirer.prompt(prompts)
console.log(answers)
if (answers.patty === 'Chicken') {
const pattyAnswers = await inquirer.prompt([]) // new prompts here
}
I also added small spinner by nanospinner and printed placed order details after a small delay.
Make it Globally available
- Update
main
property in package.json toindex.js
- Add
#! /usr/bin/env node
at the top of your file (this lines tells your OS to run this file with node interpreter) - Add
bin
property to package.json as follows. ```json
"bin": {
"burger-maker": "./index.js"
}
- Run `npm install -g .` to install this app
- Now, open a new terminal and run `burger-maker -V`
![Final command output](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9iq8gtx3ush09jemxach.png)
NOTE:
- if you're using Typescript give a path to a `dist/index.js` file
- If you're using `nvm` make sure correct node version to run the command
### ✅ There you go, You have your first CLI tool.
---
My example code is available on [Github Repo](https://github.com/rohit-ambre/burger-maker-cli/).
Posted on March 25, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.