229

Is it possible to specify a custom package destination for npm install, either through a command flag or environment variable?

By default, npm local installs end up in node_modules within the current directory, but I want it to install into node_modules within a different directory, for example vendor/node_modules. How can I make that happen?

5
  • what are you trying to accomplish? this has been discussed here: stackoverflow.com/questions/13668097/… Commented Feb 7, 2013 at 2:42
  • 12
    @PascalBelloncle: Instead of installing packages into subdirectories of ./node_modules, I want npm to install them into subdirectories of ./vendor/node_modules. (Or to be told that that isn't configurable.) Commented Feb 7, 2013 at 2:49
  • 1
    I understood that's what you want to do, which I don't think is possible out of the box. Plus require would not work either. So I was asking why you wanted to do this. Maybe there is an alternative solution to do what you want. Commented Feb 7, 2013 at 2:52
  • 1
    I'm installing a package solely for its binary (i.e. it will only be used on the command line and never required) but I don't want to install it globally. Commented Feb 7, 2013 at 2:58
  • I see. See my suggestion below then. Commented Feb 7, 2013 at 3:02

6 Answers 6

214

TL;DR

You can do this by using the --prefix flag and the --global* flag.

pje@friendbear:~/foo $ npm install bower -g --prefix ./vendor/node_modules [email protected] /Users/pje/foo/vendor/node_modules/bower 

*Even though this is a "global" installation, installed bins won't be accessible through the command line unless ~/foo/vendor/node_modules exists in PATH.

TL;DR

Every configurable attribute of npm can be set in any of six different places. In order of priority:

  • Command-Line Flags: --prefix ./vendor/node_modules
  • Environment Variables: NPM_CONFIG_PREFIX=./vendor/node_modules
  • User Config File: $HOME/.npmrc or userconfig param
  • Global Config File: $PREFIX/etc/npmrc or userconfig param
  • Built-In Config File: path/to/npm/itself/npmrc
  • Default Config: node_modules/npmconf/config-defs.js

By default, locally-installed packages go into ./node_modules. global ones go into the prefix config variable (/usr/local by default).

You can run npm config list to see your current config and npm config edit to change it.

PS

In general, npm's documentation is really helpful. The folders section is a good structural overview of npm and the config section answers this question.

Sign up to request clarification or add additional context in comments.

7 Comments

As I test, actually if follow the command above, it will be installed into ./vendor/node_modules/lib/bower using npm#3.8.0
When doing this, I am getting error No version provided in package.json
Is it possible to achieve something similar with a package.json file? i.e. if I run npm install in directory A with package.json file, packages will be install in directory B. It seems this solution is for individual packages being installed.
Is there any way of installing all dependencies using this method? npm install installs dependencies locally. npm install X -g -prefix "..." installs module X to the prefix, npm install -g -prefix "..." installs the current package to the prefix.
Doesn't work for me: instead of installing deps to the prefix, it creates a symlink under the prefix leading back to the current directory, and claims that it installed "1 package". Repeating the command gives "up to date", which is probably related to this bug.
|
38

If you want this in config, you can set npm config like so:

npm config set prefix "$(pwd)/vendor/node_modules" 

or

npm config set prefix "$HOME/vendor/node_modules" 

Check your config with

npm config ls -l

Or as @pje says and use the --prefix flag

1 Comment

I believe this sets the global prefix? So doing npm install will still install locally to ./node_modules but npm install -g will install to "$(pwd)/vendor/node_modules". I can imagine settings this then forgetting about it, coming back later wondering why my global packages are acting weirdly.
16

For OSX, you can go to your user's $HOME (probably /Users/yourname/) and, if it doesn't already exist, create an .npmrc file (a file that npm uses for user configuration), and create a directory for your npm packages to be installed in (e.g., /Users/yourname/npm). In that .npmrc file, set "prefix" to your new npm directory, which will be where "globally" installed npm packages will be installed; these "global" packages will, obviously, be available only to your user account.

In .npmrc:

prefix=${HOME}/npm

Then run this command from the command line:

npm config ls -l

It should give output on both your own local configuration and the global npm configuration, and you should see your local prefix configuration reflected, probably near the top of the long list of output.

For security, I recommend this approach to configuring your user account's npm behavior over chown-ing your /usr/local folders, which I've seen recommended elsewhere.

Comments

9

On Windows 7 for example, the following set of commands/operations could be used.

Create an personal environment variable, double backslashes are mandatory:

  • Variable name: %NPM_HOME%
  • Variable value: C:\\SomeFolder\\SubFolder\\

Now, set the config values to the new folders (examplary file names):

  • Set the npm folder

npm config set prefix "%NPM_HOME%\\npm"

  • Set the npm-cache folder

npm config set cache "%NPM_HOME%\\npm-cache"

  • Set the npm temporary folder

npm config set tmp "%NPM_HOME%\\temp"

Optionally, you can purge the contents of the original folders before the config is changed.

  • Delete the npm-cache npm cache clear

  • List the npm modules npm -g ls

  • Delete the npm modules npm -g rm name_of_package1 name_of_package2

1 Comment

Thanks, I follow the steps. But it creates a directory called c:/%NPM_HOME%/npm, etc. instead of c:/npm_home/npm
7

After searching for this myself wanting several projects with shared dependencies to be DRYer, I’ve found:

  • Installing locally is the Node way for anything you want to use via require()
  • Installing globally is for binaries you want in your path, but is not intended for anything via require()
  • Using a prefix means you need to add appropriate bin and man paths to $PATH
  • npm link (info) lets you use a local install as a source for globals

→ stick to the Node way and install locally

ref:

2 Comments

This should be a comment as it adds nothing on the point. It basically summarizes to "install packages locally", which is exactly what the OP does, and OP is asking how to make local installation use a different directory. This answer also mentions "when to use global installation", but does not mention how's that relevant to the question. Idk how this unrelated text got 8 points 🤷‍♂️
Btw, every link in the answer is 404. Mentioning in case they contained something important.
-2

We can set the default npm resource download path by this command :

npm config set registry https://registry.npmjs.org/

I added registry=https://registry.npmjs.org/ path to the .npmrc file of my react project root path and install my needed package with --force :

npm install react-c3js --force

enter image description here

Also we can comment npm resource path in this file : enter image description here

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.