Node.js command-line packages
November 29, 2019 • 🍒 3 min read
Have you ever wondered how can you build a Node.js package that can be called via a Command Line Interface ?
You know, that kind of packages that you can call as global packages directly by writing something [...args]
in your terminal. Some of them you might have used: create-react-app
, gatsby-cli
, now
, yarn
, serve
.
Let’s dive into it.
I assume that you have installed Node.js on your computer. If you haven’t, click here and download the latest LTS version.
1. Init your package
We will start by creating a new package. Head to your terminal and execute:
$ mkdir my-cli-package
$ cd my-cli-package
$ npm init -y
Here we are first creating a new folder called my-cli-package
for the package we will create. Then we move to it with the cd
command. Finally, we initialize the package avoiding to fill further non relevant details at the moment with the -y
option.
2. Write a simple script
Next, we will create a dumb script that will just log a message to the console:
// my-cli-package/hello.js
console.log("Hi there !");
If you want to check what happens when you would execute this script you can run it executing node hello.js
.
3. Convert the script into a shell command
How can be this script executed as a shell command without having to reference node
?
You add the following at the top of your file:
#!/usr/bin/env node
console.log("Hi there !");
This line tells the system that it should execute the file using node
, so now you can execute the file like ./hello.js
. If you get a “Permission denied” error, it probably means your system doesn’t give execute permissions by default to new files. Execute chmod +x hello.js
to fix it.
4. Make the script executable
But this is not the end right ? We would like to call our script executing hello
.
Let’s update our package.json
file for that:
{
"name": "my-cli-package",
"version": "1.0.0",
"description": "",
"main": "index.js",
"bin": { "hello": "./hello.js" }, "scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
Adding the bin
entry, we map a command name to an executable file. Read more about it here.
As a details, we now need to run:
$ npm link
This will create a symlink pointing to our script. Again, you might get a “Permission denied” error. You will need to execute sudo npm link
in that case.
Don’t forget to run
npm unlink
when you are finish working on the library to clean up your local work environment.
Now if you execute:
$ hello
You should see the message “Hi there !” appear right in your terminal.
Closing words
From here, you can explore how to build scripts with more interactions and real goals. You could use process.argv
to catch arguments used in the command call or use Commander.js to build more complex command-line interfaces. Also checkout Ink if you want to build stateful/web-like interfaces using the power of React.