This will be a short read, probably, I can't promise you that though, but at least I'll make it as entertaining as it can get.
First, what is NPX, and what are CLI commands?
NPX is a command-line tool meant to run NPM packages containing CLI scripts.
A CLI command is a program that can be run from the command line by name, for example, gcc
or cd
or ls
, etc.
In NodeJs you have the option to create CLI commands that can be run only from NPM scripts, remember npm run <script name>
?
A good example of this is tsc
or babel
or webpack
that unless installed globally (and added to the path) they can be only
summoned from inside a script from the scripts
section in the package.json
.
We will need NodeJs and NPX installed as a global package for the rest of the article. Any NodeJs > v5.0 should have NPX already installed but if it doesn't work you can always run npm install -g npx
.
From NPX's Github page, we can get the following command to run in a terminal: npx github:piuccio/cowsay JavaScript FTW!
.
It should prompt us with something like this:
_________________
< JavaScript FTW! >
-----------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
This command installed the package in a temporary folder and run the command with the same name as the repository.
Just to mention the npx cowsay JavaScript FTW!
command will work just fine because the package exists on NPM as well.
As we just covered how to use it, next we should learn how to write a command that can be used from the CLI (or using NPM).
To save some time I will list the instructions:
- Create a new folder
- Open a terminal in the folder
-
package.json
- for that we use can usenpm --init
and accept the defaults or customize the inputs like name, description, license, etc. - Create the main file of the application - create, let's say, a file named
index.js
- In the
package.json
we will add the commands section:
"bin": {
"awesome-command": "index.js",
}
- Add in the
index.js
on the first line#!/usr/bin/env node
For example:
#!/usr/bin/env node
console.log("Awesome Command");
Good job, now if we publish the package and install it, we will be able to use it, but... Let's say we are in a hurry and we just want to see if it works, so, what can we do? We
npm link
. This command will add it to the global packages like it would have installed it with the-g
flag.Run
awesome-command
from any terminal and it will printAwesome Command
Sooo, how does the NPX helps? We already are able to run the command from any terminal. Well, that is true, but only now and definitely not always.
If we would have installed the package locally, then we wouldn't have been able to run awesome-command
in a terminal and expect it to work. We would have had to add it to the scripts
section in the package.json
like this:
"scripts": {
"awesome": awesome-command
},
and then npm run awesome
or... run npx awesome-command
.
Now comes the good part, what if we want to make the command available over the internet?
Well then we publish the npm package and anyone can choose to
npm -install <package>
it or npx <package>
. Remember only to have one of the commands match the name of the package.
But what if we don't want to publish the package?
Then we can just host the package on Github in a new repository and anyone will be able to install it using npm -install user/<repository>
or run it using npx github:<user>/<repository>
. Again remember to have one of the commands in the bin
section match the name of the repository.
Ending thoughts, if the command accepts extra arguments we can always add them after the command name, for example npx github:<user>/<repository> arg1 arg2
.
I hope you enjoyed reading the article as much as I enjoyed writing it.
Top comments (7)
I’m finding
npx github:piuccio/cowsay
doesn’t execute, and I can’t figure out why. I started researching this because I could not get another package on GitHub to execute, so now I’m trying to figure out why.I’m using v8.5.5 of
npx
and would love it if some others could test this and see if it is a version issue?I got it to work, but I’ll need to research GitHub for bug reports.
I had to run the non-aliased form first:
npm exec github:piuccio/cowsay
, and then I could runnpx …
The same behavior occurred with my project. Once I ran
npm exec …
first,npx
works correctly.@timrohrer Did you ever figure out why
npm exec github:piuccio/cowsay
works, butnpx github:piuccio/cowsay
doesn't? That is the behavior I'm seeing.Nope. I just run
npm exec
first. Afterwards, I can often usenpx
but no solid pattern.Great read!
For me was usefull this simple line:
#!/usr/bin/env node
Keep it simple stupid (Clean code)
Thanks...Lulian Preda
Thank you!!!