148

Is there a way to move the node_modules directory in an application to let's say /vendor/node_modules like bower does with the bowerrc file? I thought it could be specified in package.json but I can't seem to find a solution. Your help is much appreciated.

4
  • I guess something similar to http://stackoverflow.com/questions/18974436/change-node-modules-location Commented Oct 10, 2014 at 6:18
  • 31
    I'm not sure why you've accepted an answer that clearly doesn't answer your question. You ask how to set the path to node_modules in package.json, and xShirase's answer simply doesn't provide a way to do that.
    – Mark Amery
    Commented Mar 21, 2017 at 11:03
  • 8
    He probably accepted the answer because this is very clearly an XY problem and an alternative solution is better than "sorry, that's not possible." Commented Feb 4, 2019 at 18:39
  • In webpack.config there is an option which could do the trick. Webpack docs: webpack.js.org/configuration/resolve/#resolvemodules Here "node_modules" is set by default but you can remove it and search modules in another place. To test it I created a copy of the node_modules after install: (in package.json) "postinstall": "cp -r ./node_modules ./juan_node_modules", And in webpack.config.js i added this: resolve: { modules: [path.resolve(__dirname, 'juan_node_modules')], ... It seems to work.
    – Juan Gil
    Commented Apr 1, 2023 at 20:59

5 Answers 5

90

yes you can, just set the NODE_PATH env variable :

export NODE_PATH='yourdir'/node_modules

According to the doc :

If the NODE_PATH environment variable is set to a colon-delimited list of absolute paths, then node will search those paths for modules if they are not found elsewhere. (Note: On Windows, NODE_PATH is delimited by semicolons instead of colons.)

Additionally, node will search in the following locations:

1: $HOME/.node_modules

2: $HOME/.node_libraries

3: $PREFIX/lib/node

Where $HOME is the user's home directory, and $PREFIX is node's configured node_prefix.

These are mostly for historic reasons. You are highly encouraged to place your dependencies locally in node_modules folders. They will be loaded faster, and more reliably.

Source

6
  • 1
    That is great. So in my case where I have local node_modules to each application I'm building, would I do that export in a js file in the project?
    – sturoid
    Commented Oct 10, 2014 at 6:26
  • 3
    nope, it's an environment variable, it's setup at system-level. So you have to type it in your terminal. env variables are accessed within a node app in process.env
    – xShirase
    Commented Oct 10, 2014 at 6:28
  • i try to run that in Windows and it doesnt work, it says: 'export' is not recognized as an internal or external command, operable program or batch file., it worked for me in OS X. Commented Oct 1, 2015 at 4:33
  • 148
    I don't really think this is the answer to the question: He was asking for a property within the package.json to put a path for LOCAL (application level) npm-Packages. This answer tells him how he can move the GLOBALLY (-g) installed packages into another folder. Commented Mar 6, 2016 at 9:55
  • There is no word "property" in question or its title. Author write I thought it could be in package.json. But you can specify env variable in package.json at script run command like this: {"scripts": { "start": "NODE_PATH='yourdir'/node_modules node ./your-app.js"}} You also can use all expand ability of your shell.
    – oklas
    Commented Dec 10, 2021 at 15:34
38

In short: It is not possible, and as it seems won't ever be supported (see here https://github.com/npm/npm/issues/775).

There are some hacky work-arrounds with using the CLI or ENV-Variables (see the current selected answer), .npmrc-Config-Files or npm link - what they all have in common: They are never just project-specific, but always some kind of global Solutions.

For me, none of those solutions are really clean because contributors to your project always need to create some special configuration or have some special knowledge - they can't just npm install and it works.

So: Either you will have to put your package.json in the same directory where you want your node_modules installed, or live with the fact that they will always be in the root-dir of your project.

2
  • 23
    "If you want to spell "node_modules" differently, sorry, no can do. That's built into node-core. Changing that is tantamount to building a completely different package manager." <== good job using variables I guess. Commented Jan 6, 2017 at 15:26
  • 4
    A comment from 2019: it looks like yarn supports overriding the modules directory. Well, yarn is a new package manager, I suppose.
    – Vanuan
    Commented Mar 5, 2019 at 11:02
24

Yarn supports this feature:

# .yarnrc file in project root
--modules-folder /node_modules

But your experience can vary depending on which packages you use. I'm not sure you'd want to go into that rabbit hole.

8

I'm not sure if this is what you had in mind, but I ended up on this question because I was unable to install node_modules inside my project dir as it was mounted on a filesystem that did not support symlinks (a VM "shared" folder).

I found the following workaround:

  1. Copy the package.json file to a temp folder on a different filesystem
  2. Run npm install there
  3. Copy the resulting node_modules directory back into the project dir, using cp -r --dereference to expand symlinks into copies.

I hope this helps someone else who ends up on this question when looking for a way to move node_modules to a different filesystem.

Other options

There is another workaround, which I found on the github issue that @Charminbear linked to, but this doesn't work with grunt because it does not support NODE_PATH as per https://github.com/browserify/resolve/issues/136:

lets say you have /media/sf_shared and you can't install symlinks in there, which means you can't actually npm install from /media/sf_shared/myproject because some modules use symlinks.

  • $ mkdir /home/dan/myproject && cd /home/dan/myproject
  • $ ln -s /media/sf_shared/myproject/package.json (you can symlink in this direction, just can't create one inside of /media/sf_shared)
  • $ npm install
  • $ cd /media/sf_shared/myproject
  • $ NODE_PATH=/home/dan/myproject/node_modules node index.js
0

What if I am inside docker and I want to persist the node_modules in a volume? Then, having the node_modules inside of my app path is not an option for me.

When I deploy new code into the container, I put a tar into it, extract it to a temporary folder and then rsync from that to the app directory. I have the --delete flag set for rsync, so everything that's not in the tar is removed from the app folder. That also applies to the node_modules folder, so unfortunately the only solution that worked for me is the following:

Create a symbolic link in the app directory to a directory that contains the node_modules and is mounted into the container from the host.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.