Create a CLI Entry Point in Node.js

7 min read·Jan 1, 2026

In software development, an entry point is a point in a program where its execution begins.

It is usually responsible for:

  1. Loding configuration and environment variables.
  2. Initializing dependencies.
  3. Reading command-line arguments.
  4. Deciding what the program should do next.

In this lesson, you'll learn how to write a clean and reusable entry point for your Node.js CLI apps and how to turn a Node.js script into a real command you can run from anywhere.

Write an entry point

Unlike in other programming languages, Node.js doesn't provide a standard entry point like the main() function in C or Java.

While this implementation is left up to each developer, a common way to implement an entry point in Node.js is to set up a try...catch block responsible for catching and gracefully handling any eventual error that may occur during the script's initialization:

index.js
try {
  //
} catch(error) {
  //
}

Write an asynchronous entry point

An elegant way to implement an asynchronous entry point in Node.js is to use an immediately invoked function expression (IIFE), whose anonymous function is declared using the async keyword, which will in turn enable the future use of the await operator within the function's body.

index.js
(async () => {
  try {
    //
  } catch(error) {
    //
  }
})();

Set an exit code

By convention, command-line programs running on Unix-like operating systems will terminate with a return value of 0 when everything goes well, and another value between 1 and 255 when something goes wrong.

Terminate the process gracefully

To terminate a process gracefully, which means setting its exit code and letting Node.js complete running asynchronous tasks and flush whatever data is left in the internal buffer, you can set the value of the global process.exitCode property and using the return statement.

(async () => {
  try {
    //
  } catch(error) {
    //
    process.exitCode = 1;
    return;
  }
  process.exitCode = 0;
})();

Terminate the process immediately

On the other hand, to set the exit code and immediately terminate the execution of the program, you can use the global process.exit() method that takes as argument an optional integer representing the exit code:

(async () => {
  try {
    //
  } catch(error) {
    //
    process.exit(1);
  }
  process.exitCode = 0;
})();

Note: This method should only be used when you control every part of your script and you are sure there are no pending operations.

Make a script executable system-wide

In order to be able to invoke a Node.js script from anywhere in the shell without having to prefix it with the node command, you can:

  1. Add this shebang directive at the very top of your script:

    index.js
    #!/usr/bin/env node
    
    (async () => {
      //
    })();
    
  2. Make the entry point file executable using the chmod command:

    $ chmod +x index.js
    
  3. Create a symbolic link into the /usr/local/bin directory pointing to the absolute path to the entry point file:

    $ ln -s /path/to/script/index.js /usr/local/bin/myscript
    
  4. Ensure that the /usr/local/bin directory is in your PATH environment variable:

    $ echo $PATH | grep /usr/local/bin
    

    Or add it to you shell's configuration and reload it:

    $ echo 'export PATH="/usr/local/bin:$PATH"' >> ~/.bashrc
    $ source ~/.bashrc
    
  5. Execute your script like any other shell command:

    $ myscript
    

Enjoying the courses?

I've made these courses completely free so anyone can learn from them. If they've helped you and you'd like to actively support the work behind BackendBrewery, you can leave a tip:

Support BackendBrewery
Create a CLI Entry Point in Node.js | Backend Brewery