Building a Simple CLI Tool with Node.js

Command-line interface (CLI) tools are programs designed for use from a text interface, such as a shell or terminal.

Node.js is an excellent platform for building CLI tools due to its built-in capabilities for interacting with the system and processing input/output. In this section, we'll explore creating a simple CLI tool using Node.js so you can see how you can use JavaScript to solve new problems.

Working with the process Object

The process object in Node.js provides information about and control over the current process. It's a global object that can be accessed from anywhere in your Node.js application without requiring an import.

Here are some examples of how we might use it:

// Print the current working directory
console.log('Current directory:', process.cwd());
// Output for me: Current directory: /Users/username/Projects/node-intro

// Print the Node.js version
console.log('Node version:', process.version);
// Output for me: Node version: v20.15.0

// Print the platform (e.g., 'darwin', 'win32', 'linux')
console.log('Platform:', process.platform);
// Output for me: Platform: darwin

Run the logs in your own Node.js script to test it out.

Handling Environment Variables

Environment variables are key-value pairs set outside your program. They're helpful for configuration and storing sensitive information or flagging certain functionality.

Building a CLI Tool with Node.js

[Previous sections remain the same]

Handling Environment Variables

Environment variables are key-value pairs set outside of your program, typically at the operating system level. They're useful for configuration and storing sensitive information.

Accessing Environment Variables

In Node.js, you can access environment variables through process.env:

// Access an environment variable
console.log('HOME directory:', process.env.HOME);

// Set an environment variable (only for the current process)
process.env.MY_VARIABLE = 'Hello, CLI!';
console.log('MY_VARIABLE:', process.env.MY_VARIABLE);

Now that you see the basics, lets dive in and start building something. Let's create a simple script that uses environment variables for configuration. We'll create a greeting script that can be customized with environment variables.

Save this script as greet.js:

// Get the name from an environment variable, or use a default
const name = process.env.GREET_NAME || 'Guest';

// Get the language from an environment variable, or use English as default
const lang = process.env.GREET_LANG || 'en';

// Greeting templates
const greetings = {
    en: 'Hello',
    es: 'Hola',
    fr: 'Bonjour',
    de: 'Hallo'
};

// Select the appropriate greeting
const greeting = greetings[lang] || greetings.en;

// Print the greeting
console.log(`${greeting}, ${name}!`);

Now, you can run this script and pass environment variables in several ways. But directly from your terminal, depending on your environment, you can do the following:

Setting environment variables inline (Unix-like systems):

GREET_NAME=Alice GREET_LANG=fr node greet.js

Setting environment variables inline (Windows Command Prompt):

set GREET_NAME=Alice && set GREET_LANG=fr && node greet.js

Setting environment variables inline (Windows PowerShell):

$env:GREET_NAME="Alice"; $env:GREET_LANG="fr"; node greet.js

Exporting environment variables before running the script (Unix-like systems):

export GREET_NAME=Bob
export GREET_LANG=es
node greet.js

Running the script with different environment variables will produce different outputs:

$ GREET_NAME=Alice GREET_LANG=fr node greet.js
Bonjour, Alice!

$ GREET_NAME=Carlos GREET_LANG=es node greet.js
Hola, Carlos!

$ GREET_LANG=de node greet.js
Hallo, Guest!

$ node greet.js
Hello, Guest!

This example demonstrates how you can use environment variables to configure your Node.js scripts without hardcoding values. This approach is beneficial for:

  • Keeping sensitive information (like API keys) out of your code
  • Changing behavior based on the environment (development, staging, production)
  • Allowing users to customize the script's behavior without changing the code

We probably overused environment variables in this section, so let's show you how to use command-line arguments to pass in different arguments to your CLI app next.

Command-Line Arguments

When you run a Node.js script from the command line, you can pass arguments to it. These arguments are available in the process.argv array.

The process.argv array contains:

  • The path to the Node.js executable (index 0)
  • The path to the JavaScript file being executed (index 1)
  • Any additional command-line arguments (starting from index 2)

Here's a simple example to demonstrate:

// Save this as cli.js
console.log(process.argv);

// Run it with: node cli.js arg1 arg2
// Output will be an array: 
// ['/path/to/node', '/path/to/cli.js', 'arg1', 'arg2']

Let's create a simple argument parser:

function parseArgs(args) {
    const parsedArgs = {};
    for (let i = 2; i < args.length; i++) {
        if (args[i].startsWith('--')) {
            const key = args[i].slice(2);
            const value = args[i + 1] && !args[i + 1].startsWith('--') ? args[i + 1] : true;
            parsedArgs[key] = value;
            if (value !== true) i++;
        }
    }
    return parsedArgs;
}

const args = parseArgs(process.argv);
console.log(args);

// Run with: node cli.js --name John --age 30 --verbose
// Output: { name: 'John', age: '30', verbose: true }

Now, let's put it all together to create a simple greeting CLI tool which will be another version of our greet.js from earlier:

function parseArgs(args) {
    const parsedArgs = {};
    for (let i = 2; i < args.length; i++) {
        if (args[i].startsWith('--')) {
            const key = args[i].slice(2);
            const value = args[i + 1] && !args[i + 1].startsWith('--') ? args[i + 1] : true;
            parsedArgs[key] = value;
            if (value !== true) i++;
        }
    }
    return parsedArgs;
}

function greet(name, language) {
    const greetings = {
        en: 'Hello',
        es: 'Hola',
        fr: 'Bonjour',
        de: 'Hallo'
    };

    const greeting = greetings[language] || greetings.en;
    console.log(`${greeting}, ${name}!`);
}

const args = parseArgs(process.argv);
const name = args.name || process.env.USER || 'Guest';
const language = args.lang || 'en';

greet(name, language);

// Test it out with some of the arguments:
// node greet.js --name Alice --lang fr
// node greet.js --name Bob
// node greet.js

This CLI tool does the following:

  1. Parses command-line arguments for a name and language.
  2. Uses environment variables as a fallback for the name.
  3. Greets the user in the specified language (or English by default).

Building CLI tools with Node.js allows you to create powerful, cross-platform utilities. As we advance, we will use more tools for more complex CLI applications, but understanding these fundamentals will provide a solid foundation for CLI development in Node.js.

BeginnerNodejs
Avatar for Niall Maher

Written by Niall Maher

Founder of Codú - The web developer community! I've worked in nearly every corner of technology businesses: Lead Developer, Software Architect, Product Manager, CTO, and now happily a Founder.

Loading

Fetching comments

Hey! 👋

Got something to say?

or to leave a comment.