Node.js Command-Line Interfaces simplify task automation and streamline workflows. A Node CLI allows users to execute commands in a terminal, providing a quick and efficient way to control applications and scripts. Node.js, with its event-driven architecture and non-blocking I/O, is ideal for building CLIs.
The Node.js Commander package is a popular choice for creating CLIs due to its simplicity and powerful features. It helps in parsing command-line arguments, handling commands, and adding options effortlessly. Whether you're building CLI with Node.js for any use, mastering this skill is invaluable for efficient task management.
This article will provide information on how to write a CLI, use Node.js and other applicable packages, and distribute a new CLI. Learn more on how to build a CLI with Node.js by enrolling in Node.js Advanced course.
How to Build a CLI with Node.js?
Prerequisites
The following tools are required to build a CLI in Node.js. All these tools should be installed before starting:
A recent version of Node.js should be installed.
- A text editor
- Setting up the project
A basic Node.js project will be set as mentioned below.
1. Open the terminal.
2. Create a folder for the project.
~$mkdir CLItermTranslate
3. Navigate to the folder
~$cd CLItermTranslate
4. Initialize a Node.js project in the CLItermTranslate folder.
~$npm init
5. Fill in the prompt.
6. Project is set up now
How to Create the Basic CLI in Node.js?
Let's move ahead to create CLI Node.js. Below are the steps.
- Create a folder bin in the root directory of the project.
- Create a file index.js inside the bin. This will be the entry point of our CLI.
- Open the package.json file and modify the "main" part to bin/index.js.
- Add another entry into the package.json file called bin and set the key to tran, and its value to ./bin/index.js.
It should look as below:
"bin": {
"tran": "./bin/index.js"
}
key tran is the keyword calling the CLI. This keyword is used in the terminal for using the CLI. The name defined is not permanent and can be changed any time.
The package.json file would be viewed as below:
{
"name": "termtran",
"version": "1.0.0",
"description": "A CLI used to translate languages in the terminal",
"main": "bin/index.js",
"scripts": {
"test": "echo "Error: nothing specified" && exit 1"
},
"keywords": [
"cli"
],
"bin": {
"tran": "./bin/index.js"
},
"author": "Rajesh Bhagia",
"license": "ISC"
}
Note: Add extra comma after adding new entry into the package.json file.
Open the index.js file (in bin folder) and add the below code:
#! /usr/bin/env node
console.log("Hello World This is the first program!");d this is the first program!");
The first line with #! is called a shebang line or a bang line. The shebang line is used for Linux or UNIX type systems, but the node requires it for Windows and macOS, too, for proper installation and execution of the script.
Test CLI after it is installed.
People may call CLI from anywhere in the system hence having it installed globally.
Run below command after Navigating to the root directory of the project
~$npm install -g .
The -g will install the package globally on the system.
Test the CLI by executing the command in the terminal
~$tran
If all is done correctly, then a greeting message, i.e., console.logged in the index.js file, will appear.
rajesh.bhagia:-~$ tran
Hello World This is the first program!
rajesh.bhagia:-~$
How to Handle Command Line Arguments?
The basic CLI is ready. Let us move ahead to add additional functionality. The most vital task that any CLI does is handling command-line arguments. We will receive the language name and the sentence to be translated as arguments, then parse it in our CLI as below.
Node.js delivers built-in functionality for managing command-line arguments. We will use an npm package called yargs which is especially made for building CLI.
s. yargs will facilitate the process of parsing arguments and help to organize command-line flags.
1. Install yargs
~$npm i yargs
2. Include the module in your index.js after installing
~$const yargs = require("yargs");
3. Create options object with command line flags:
const usage = "\nUsage: tran <lang_name> sentence or words to be translated";const options = yargs
.usage(usage)
.option("l", {alias:"languages", describe: "List all languages supported.", type: "boolean", demandOption
: false })
.help(true)
.argv;
An option -l is defined to print all the supported languages by the API; Yargs provides us with --help and --version flags by default.
To set the option to be compulsory, then set it’s demandOption value to true; this will get yargs will throw a Missing argument error if the flag is not fed.
Let us Test it:
rajesh.bhagia:-~$ tran - -help
Usage: tran <lang_name> sentence or words to be translated
Options:
-l, - - version Show version number
- - languages list all supported languages
- - help Show help |
[boolean]
[boolean]
[boolean] |
The Node.js course is one of the best Full-stack Developer courses which would help candidates to gain expertise on the subject. The Course would help the candidates to gain expertise and it assists in getting jobs.
How to Add Utility Functions?
A. Let us add utility functions.
Take input as:
~$tran lang_name sentence or words to be translated
B. Let us parse the arguments
All the utility functions should be written in our index.js. Separate file utils.js for all functions so that looks neat.
Do this as below:
- Create a file called utils.js in the bin folder.
- Include file in index.js
const utils = require('./utils.js')
To parse the sentence create a function
module.exports = { parseSentence: parseSentence };function parseSentence(words) {
var sentence = "";
for(var i = 1; i < words.length; i++) {
sentence = sentence + words[i] + " ";
}
Call it in index.js :
Create a function in utlil.js to display help when no argument is passed
module.exports = { showHelp: showHelp, parseSentence: parseSentence };const usage = "\nUsage: tran <lang_name
> sentence and words to be translated";
function showHelp() {
console.log(usage);
console.log('\nOptions:\r')
console.log('\t--version\t ' + 'Show version number.' + '\t\t' + '[boolean]\r')
console.log(' -l, --languages\t' + ' ' + 'List all languages.' + '\t\t' + '[boolean]\r')
console.log('\t--help\t\t ' + 'Show help.' + '\t\t\t' + '[boolean]\n')
}
Call it in index.js
if(yargs.argv._[0] == null){
utils.showHelp();
return;
}
Write a function in utils.js to display supported for all languages:
module.exports = { showAll: showAll, showHelp: showHelp, parseSentence: parseSentence};
function showAll(){
console.log(chalk.magenta.bold("\nLanguage Name\t\tISO-639-1 Code\n"))
for(let [key, value] of languages) {
console.log(key + "\\t\\t" + value + "\\n")
}
}
let languages = new Map();
languages.set('afrikaans', 'af')
languages.set('albanian', 'sq')
languages.set('amharic', 'am')
languages.set('arabic', 'ar')
languages.set('armenian', 'hy')
languages.set('azerbaijani', 'az')
languages.set('basque', 'eu')
languages.set('belarusian', 'be')
languages.set('bengali', 'bn')
languages.set('bosnian', 'bs')
languages.set('bulgarian', 'bg')
languages.set('catalan', 'ca')
languages.set('cebuano', 'ceb')
languages.set('chinese', 'zh')
languages.set('corsican', 'co')
languages.set('croatian', 'hr')
languages.set('czech', 'cs')
languages.set('danish', 'da')
languages.set('dutch', 'nl')
languages.set('english', 'en')
languages.set('esperanto', 'eo')
languages.set('estonian', 'et')
languages.set('finnish', 'fi')
languages.set('french', 'fr')
languages.set('frisian', 'fy')
languages.set('galician', 'gl')
languages.set('georgian', 'ka')
languages.set('german', 'de')
languages.set('greek', 'el')
languages.set('gujarati', 'gu')
languages.set('haitian creole', 'ht')
languages.set('hausa', 'ha')
languages.set('hawaiian', 'haw') // (iso-639-2)
languages.set('hebrew', 'he') //or iw
languages.set('hindi', 'hi')
languages.set('hmong', 'hmn') //(iso-639-2)
languages.set('hungarian', 'hu')
languages.set('icelandic', 'is')
languages.set('igbo', 'ig')
languages.set('indonesian', 'id')
languages.set('irish', 'ga')
languages.set('italian', 'it')
languages.set('japanese', 'ja')
languages.set('javanese', 'jv')
languages.set('kannada', 'kn')
languages.set('kazakh', 'kk')
languages.set('khmer', 'km')
languages.set('kinyarwanda', 'rw')
languages.set('korean', 'ko')
languages.set('kurdish', 'ku')
languages.set('kyrgyz', 'ky')
languages.set('lao', 'lo')
languages.set('latin', 'la')
languages.set('latvian', 'lv')
languages.set('lithuanian', 'lt')
languages.set('luxembourgish', 'lb')
languages.set('macedonian', 'mk')
languages.set('malagasy', 'mg')
languages.set('malay', 'ms')
languages.set('malayalam', 'ml')
languages.set('maltese', 'mt')
languages.set('maori', 'mi')
languages.set('marathi', 'mr')
languages.set('mongolian', 'mn')
languages.set('burmese', 'my')
languages.set('nepali', 'ne')
languages.set('norwegian', 'no')
languages.set('nyanja', 'ny')
languages.set('odia', 'or')
languages.set('pashto', 'ps')
languages.set('persian', 'fa')
languages.set('polish', 'pl')
languages.set('portuguese', 'pt')
languages.set('punjabi', 'pa')
languages.set('romanian', 'ro')
languages.set('russian', 'ru')
languages.set('samoan', 'sm')
languages.set('scots', 'gd')//gd gaelic
languages.set('serbian', 'sr')
languages.set('sesotho', 'st')
languages.set('shona', 'sn')
languages.set('sindhi', 'sd')
languages.set('sinhalese', 'si')
languages.set('slovak', 'sk')
languages.set('slovenian', 'sl')
languages.set('somali', 'so')
languages.set('spanish', 'es')
languages.set('sundanese', 'su')
languages.set('swahili', 'sw')
languages.set('swedish', 'sv')
languages.set('tagalog', 'tl')
languages.set('tajik', 'tg')
languages.set('tamil', 'ta')
languages.set('tatar', 'tt')
languages.set('telugu', 'te')
languages.set('thai', 'th')
languages.set('turkish', 'tr')
languages.set('turkmen', 'tk')
languages.set('ukrainian', 'uk')
languages.set('urdu', 'ur')
languages.set('uyghur', 'ug')
languages.set('uzbek', 'uz')
languages.set('vietnamese', 'vi')
languages.set('welsh', 'cy')
languages.set('xhosa', 'xh')
languages.set('yiddish', 'yi')
languages.set('yoruba', 'yo')
languages.set('zulu', 'zu')
Function created in utils.js
module.exports = { parseLanguage: parseLanguage, showAll: showAll, showHelp: showHelp, parseSentence: parseSent
ence };
function parseLanguage (language) {
if(language.length == 2){
return language;
}
if(languages.has(language)){
return languages.get(language)
}
else {
console.error("Language is not supported here!")
return; //returning null if the language is unsupported.
}
};
Convert language to lower case and call the function created in index.js
f(yargs.argv._[0])
var language = yargs.argv._[0].toLowerCase(); // stores the language.
//parsing the language specified to the ISO-639-1 code.
language = utils.parseLanguage(language);
Send it to API if the sentence is empty
Have the API at the top of your index.js :
const translate = require('[@vitalets/google-translate-api](http://twitter.com/vitalets/google-translate-api)')
;if(sentence == ""){
console.error("\nThe entered sentence resembles like John Moore, I can't see it!\n")
console.log("Enter tran --help to get started.\n")
return;
}translate(sentence, {to: language}).then(res => {console.log("\n" + "\n" + res.text + "\n" + "\n";}).catch
(err => {
console.error(err);
});
Hurray! Your CLI is complete now.
How to Write Logic?
We may want the text to be displayed well-formatted. For example, to show the text in red color.
- Use chalk to modify the color of the text and background color. To have borders around the text, use a module named boxen.
- Add both the modules to the project.
- npm install chalk boxen
Replace the code in the bin/index.js file
#!/usr/bin/env node
const chalk = require("chalk");
const boxen = require("boxen");
const greeting = chalk.white.bold("Hello World This is the first Program!");
const boxenOptions = {
padding: 1,
margin: 1,
borderStyle: "round",
borderColor: "green",
backgroundColor: "#555555"
};
const msgBox = boxen( greeting, boxenOptions );
console.log(msgBox);
Install the updated script and execute it.
npm install -g .
Hello World This is the first program!
The message in your console will look as below:
Hello World This is the first Program!
Looking to enhance your coding skills? Discover the power of Python, the best python certification course for aspiring programmers. Unleash your potential and join the Python revolution today!
Conclusion
This article reviewed how to build a CLI tool in Node.js. We also went through what shebang is and why it is vital in CLI applications.
Finally, we understood how to pass arguments and commands to the application. We also used chalk and boxen to make our output look nice and colorful.
Node.js is widely open for all major operating systems. It is tailored for both server and desktop environments. It provides a fast runtime environment for tasks with the V8 JavaScript engine and is also utilized for browsers like Chrome and Brave. All these strengths, coupled with the familiarity with JavaScript, will make Node.js the preferred technology for many CLI-based tools.
Check out KnowledgeHut’s Node.js Advanced course to explore more details about syllabus, course schedule, etc.