Can my NPM CLI package be executed on CMD without installing globally?
Asked Answered
F

2

7

I have written an NPM package which has its own CLI commands.

Let's name that package as xyz and imagine it's now avaialable on npmjs.com

So, let's say a user installs this package in his project by running npm install xyz.

And now he wants to run a CLI command provided by xyz package on his terminal in his project.

xyz do_this

Can this be done without installing this package globally by user ? Or without any further configuration for the user ?

Here's some part of the package.json of the xyz package.

{
  "name": "xyz",
  "version": "1.0.0",
  "description": "Description",
  "main": "index.js",
  "preferGlobal": true,
  "bin": "./index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": {
........
Flannery answered 24/5, 2021 at 20:18 Comment(0)
O
5

Here's how npm works. When you install a package in the local directory, it installs the executable dependencies files inside node_modules inside the folder with package.json, but if you use --global, it places it globally where the user has set their path. For example, when I run npm install http-server, my executable ends up as ./node_modules/http-server/bin/http-server but when I install it globally, I have it as node_modules/http-server/bin

The work around for this is, if you want to just run the executable, just execute it inside like so ./node_modules/http-server/bin/http-server. If you want it as a command, you'll need to have the user add the directory to their Path so when the user enters the command, the computer looks for the command inside that folder. Here's a guide to adding PATH directories in Linux, you'll just add the directory /pathtofolder/node_modules/http-server/bin/ or whatever your folder is. https://linuxize.com/post/how-to-add-directory-to-path-in-linux/

For example, if I wanted to add http-server from my local folder to my path, I would run

export PATH="/pathtofolder/node_modules/http-server/bin/:$PATH"

Good luck! Let me know how I can help you!

Orchardist answered 24/5, 2021 at 20:33 Comment(5)
Thanks a lot! So, if I want it as a command, either user has to update the PATH or install it globally ? And If he's calling it from inside the project folder, he needs to run the command like ./node_modules/http-server/bin/http-server ? I hope I got it clear.Flannery
Since, I want it as a command, like sequelize db:migrate, I should mention in the package README, that the user needs to install it globally right ? Otherwise it's not a convenient command for the user to update his PATH or call it with the full path.Flannery
That's correct, you wouldn't want to have the user manually add it to the path, it's really complex and not useful. Having a user just run npm install --global xyz would probably be the best solution. I hoped this helped! If you think my solution was the correct one, feel free to accept my answer as the solution by pressing the big check mark next to the solution icon! :)Orchardist
Hi Tharindu! I know it's been a long time but I just found something. You can run command line packages without installing it globally. There are 2 more ways. First, install npm install -g npx and then run npx <command> that is in the node_modules. That will try to run it. Another way is to run a script inside package.json just be referencing it like http-server, no global flag needed. Good luck!Orchardist
@KylerChin you should add this as an answer instead of a comment.Thorlie
M
0

The easiest way, as also given in the comment above, is to install the needed package locally like

$ node install [@<scope>/]<package>

and run the command later on with npx from same directory

$ npx <package/command>

We do this in our build systems to avoid global installs and their permission issues.

Morbidity answered 1/9, 2023 at 6:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.