Reputation: 20437
I'm building a cli node module. I would like people to be able to npm install
it and use it right away with a command like npm my-project --arg=foo
. It's meant for local project CLI use as a dev tool, not global installation.
It seems like the standard is to use bin
in the package.json
, but I don't understand some things about it:
bin
and when should I use scripts
?npm my-project
doesn't do it.Here is what I am doing now in package.json
:
{
"name": "my-project",
"bin": "./cli.js"
}
And I can run it locally:
node cli.js --arg=foo
But when I npm-install my-project
somewhere else, I don't know how to run the script it puts in bin (npm run my-project
doesn't work), or if I'm using this correctly.
Upvotes: 1
Views: 5319
Reputation: 203306
Let's start by explaining the difference between bin
and scripts
: the former you use if you want to provide a command line tool, the latter you use if you want to provide an additional command to npm
(with some caveats though, see below).
In your situation, I think you want to use bin
. However, instead of the user using npm my-project --arg=foo
, they will use my-project --arg=foo
, provided that your script is called my-project
. To make that happen, your package.json
will contain something like this:
"bin" : "./bin/my-project"
During installation, this will copy ./bin/my-project
to a "bin" directory (usually /usr/local/bin
on Unix-like OS'es). During development, you can call it as node bin/my-project
, or even just ./bin/my-project
, provided that it has correct permissions and "shebang".
EDIT: so I forgot that npm
will use the package name, and not the name of the file in ./bin
, as the executable name (if bin
is a string). If your package is called my-project
, and you install the package (you need to use the -g
flag before npm will install the executable), it will create an executable called my-project
, regardless of where the bin
property points to.
In other words:
package.json:
"name" : "my-project"
"bin" : "./cli.js"
npm install -g:
copies ./cli.js to /usr/local/bin/my-project and sets executable permissions
END EDIT
FWIW, storing CLI tools in ./bin
is convention, but not mandatory.
The scripts
directive is useful for more internal purposes. For instance, you can use it to run a test suite, or linters, or pre/post install scripts.
Lastly, there are various modules available to help with command line parsing. I like docopt
, but other often-used modules are commander
or nomnom
. You already mentioned yargs
.
Upvotes: 4