184

I am trying to setup Node on Mac OSX Lion. It all seems to work ok, but I can't seem to import anything modules from my global modules folder. I get the error,

Error: Cannot find module <module>

If I run this: node -e require.paths, the response I get is:

[ '/usr/local/lib/node_modules',
  '/Users/Me/.node_modules',
  '/Users/Me/.node_libraries',
  '/usr/local/Cellar/node/0.4.12/lib/node' ]

Which is correct, my modules are indeed installed in /usr/local/lib/node_modules. When I try and run a script, however, I am getting this:

Error: Cannot find module 'socket.io'
    at Function._resolveFilename (module.js:326:11)
    at Function._load (module.js:271:25)
    at require (module.js:355:19)
    at Object.<anonymous> (/Users/Me/node/server.js:2:10)
    at Module._compile (module.js:411:26)
    at Object..js (module.js:417:10)
    at Module.load (module.js:343:31)
    at Function._load (module.js:302:12)
    at Array.<anonymous> (module.js:430:10)
    at EventEmitter._tickCallback (node.js:126:26)

My .bash_profile looks like this:

export PATH=/usr/local/mysql/bin:$PATH
export NODE_PATH=/usr/local/lib/node_modules
export DYLD_LIBRARY_PATH="$DYLD_LIBRARY_PATH:/usr/local/mysql/lib/"

Would really appreciate some help, I have no idea why I can't import any libraries.

Evan Carroll
  • 78,363
  • 46
  • 261
  • 468
Hanpan
  • 10,013
  • 25
  • 77
  • 115
  • 1
    You know that this is not exactly the preferred way to do things, right? – thejh Nov 01 '11 at 18:09
  • 2
    Could you elaborate? Do you mean I shouldn't be installing libraries to my global folder? – Hanpan Nov 01 '11 at 18:15
  • what happens if you ls into your project directory and type "npm list" – Justin Beckwith Nov 01 '11 at 18:17
  • 3
    @Hanpan: The preferred way is to install modules you want to use via require() locally. – thejh Nov 01 '11 at 18:23
  • Similar question: http://stackoverflow.com/questions/15636367/nodejs-require-a-global-module-package – Jess Oct 22 '13 at 02:57
  • require has no idea where your global installs are, but you can use npm link to generate symbolic links to global packages. Check out my answer below. – Nick Sotiros Apr 27 '14 at 00:17
  • 1
    A better and more updated answer (that does not rely on `npm link`) can be found here: http://stackoverflow.com/a/15646750/2671392 – GGG Jan 30 '16 at 08:02
  • "You know that this is not exactly the preferred way to do things, right?". – Stephen W. Wright Apr 05 '17 at 18:10
  • 3
    I'm old school and used to installing libraries in global locations. I've never seen any convincing reason for a heavy use of local library installs. The mongodb class i'm taking will end up with somewhere near a hundred small projects by the time we're finished, each one containing a mostly duplicate set of libraries - mongodb, express, consolidate, etc. The move to interactive languages leaves deposits of local libraries all over the place. I must have thousands of Scala libs in the local Scala repositories. Ditto Meteor, groovy and ruby. – Stephen W. Wright Apr 05 '17 at 19:48
  • Possible duplicate of [NodeJS require a global module/package](https://stackoverflow.com/questions/15636367/nodejs-require-a-global-module-package) – jpaugh Jan 04 '18 at 17:06
  • 1
    I am working for an open-source dev environment that targets React hosted in a Docker image. It uses global installed NPM packages. But it is considered as a development environment for several reasons: 1. yarn build or npm run build to bundle a React app for production. It does not require npm packages installed in production environment separately. You can achieve this by using webpack 2. It is easier to maintain our dev environment at same place for different React app projects. Only one time you have to link the deps into your React app by using "npm link". If you like to contribute or ben – Andreas Reuter Jun 23 '19 at 12:24

10 Answers10

168

Node.js uses the environmental variable NODE_PATH to allow for specifying additional directories to include in the module search path. You can use npm itself to tell you where global modules are stored with the npm root -g command. So putting those two together, you can make sure global modules are included in your search path with the following command (on Linux-ish)

export NODE_PATH=$(npm root --quiet -g)

Joel B
  • 12,082
  • 10
  • 61
  • 69
  • 6
    Thanks for the `NODE_PATH` environment variable hint. That helped a lot! – rekire Apr 28 '17 at 14:38
  • 13
    This should be the top comment – Adam Prax Jul 11 '17 at 22:59
  • I had to set `NODE_PATH` to the equivalent posix path to make npm work on MSYS2. Thank you. – Joyce Babu Aug 20 '17 at 08:07
  • Works with Windows and Git bash too. Perfect. :-) – inf3rno Sep 14 '17 at 02:36
  • This makes your `.node_modules` folder searchable, but in order to import modules using `require()`, they should still be installed in your local project directory (or alternatively, linked using `npm link`). Global modules cannot be imported in projects, only binaries/scripts can be run from there. – Prahlad Yeri Jun 23 '18 at 13:21
  • 1
    Works on Mac OSX. I am using a single JS file and using global modules. Much simpler to handle. – Rehmat Apr 26 '21 at 07:30
  • `node --help` shows all the environment variables (including `NODE_PATH`). (Verified with `node` `v17.0.1`.) – yaobin Nov 29 '21 at 18:56
  • If you are on windows cmd, you can do it via `FOR /f "tokens=* delims=" %A in ('npm root --quiet -g') do set "NODE_PATH=%A"` or `FOR /f "tokens=* delims=" %%A in ('npm root --quiet -g') do set "NODE_PATH=%%A"` in a batch file. – Donghua Liu Jan 04 '22 at 02:06
150

If you're using npm >=1.0, you can use npm link <global-package> to create a local link to a package already installed globally. (Caveat: The OS must support symlinks.)

However, this doesn't come without its problems.

npm link is a development tool. It's awesome for managing packages on your local development box. But deploying with npm link is basically asking for problems, since it makes it super easy to update things without realizing it.

As an alternative, you can install the packages locally as well as globally.

For additional information, see

BarnyardOwl
  • 51
  • 2
  • 3
  • 10
T W
  • 6,267
  • 2
  • 26
  • 33
  • 83
    I am reading this and can not believe my eyes. So if I install, say express, and then have 20 projects to build on top of express, I need to install it 20 times, for each of them, in every project folder, over and over? I don't have much experience with package managers but this kinda sucks... – treznik Jun 19 '12 at 23:31
  • 33
    That's correct, and if you think about it, it makes sense. Managing your dependencies locally makes keeps everything self-contained and allows you to specify a specific version of a dependency for any given project (e.g. project foo requires express 2.x, while project bar can use the express 3 beta). – grahamb Jun 26 '12 at 21:52
  • 50
    I struggled to understand the logic of this for a while as well, but after watching my Ruby friends struggle with global package updates, argue about gemsets and often simply never upgrade, I have conceded that installing dependencies locally is *absolutely the only sane way to do package management*. – timoxley Jul 15 '12 at 23:25
  • 3
    I'd like to draw a parallel between this situation and that of static-linking vs. dynamic-linking libraries as it pertains to the distribution of software. Consider that almost all Apps distributed on the iOS App Store must statically link dependencies not provided by the iOS SDK. Why is this done? Global dependency hell is a very real thing. – Steven Lu Feb 14 '13 at 03:24
  • 1
    It is also my understanding that `npm`'s cache (which lives in `~/.npm`) will make expedient the reinstallation process performed in your different locations. – Steven Lu Feb 14 '13 at 03:35
  • @StevenLu's analogy for iOS apps is flawed. Yes, I have to link them statically. But I don't have to copy the source to every single project. I can tell Xcode "hey, go use that source". One piece of source code in one place. No duplication. – Lloyd Sargent Jan 08 '14 at 15:51
  • that doesn't make my analogy flawed, i wasnt referring to the source code, I was referring to the generation of machine code (which doesn't get shared) – Steven Lu Jan 08 '14 at 16:55
  • Please include the relevant info in the answer itself :) Thanks – Zach Saucier May 19 '15 at 21:36
  • this shouldn't be accepted at all, tricks are for kids, and nm link is one of them. – xamiro Mar 13 '16 at 17:11
  • Nodejs also looks for /node_modules, so you could also create a symlink from root to your global node_modules, for example: sudo ln -s /usr/local/lib/node_modules /. – Yves Dorfsman Nov 06 '16 at 21:04
  • 1
    @StevenLu Distribution of dynamically linked code [can be solved](https://packages.debian.org/stretch/firefox-esr). It does require cooperation among package developers, however; there's no infrastructure-only solution, per my knowledge. The biggest problem is how to manage versioning of independent packages so that any valid combination can be installed simultaneously without conflict, and any invalid combination is disallowed. – jpaugh Jan 04 '18 at 16:48
  • @timoxley No it is not, unless robust and fully automated deduplication (requiring zero attention from package/module authors) is built into the package manager as a first-class fundamental level-0 feature, rather than everyone and their cousin writing mutually incompatible deduplicating wrappers, as is the case with pnpm, yarn and others. – Szczepan Hołyszewski Dec 18 '22 at 20:20
80

You can use npm link to create a symbolic link to your global package in your projects folder.

Example:

$ npm install -g express
$ cd [local path]/project
$ npm link express

All it does is create a local node_modules folder and then create a symlink express -> [global directory]/node_modules/express which can then be resolved by require('express')

Nick Sotiros
  • 2,194
  • 1
  • 22
  • 18
  • 1
    Is this cross-OS compatible? – UpTheCreek Jun 24 '15 at 11:52
  • Newer versions of Windows support it since this version: https://github.com/npm/npm/commit/24be9d3508eec7684bf3ca171c91f9f2766c0b5c For older Windows versions try https://www.npmjs.com/package/npm-junction – Alex Oct 02 '15 at 17:25
26

Install any package globally as below:

$ npm install -g replace  // replace is one of the node module.

As this replace module is installed globally so if you see your node modules folder you would not see replace module there and so you can not use this package using require('replace').

because with require you can use only local modules which are present in your node module folder.

Now to use global module you should link it with node module path using below command.

$ npm link replace

Now go back and see your node module folder you could now be able to see replace module there and can use it with require('replace') in your application as it is linked with your local node module.

Pls let me know if any further clarification is needed.

Konrad Krakowiak
  • 12,285
  • 11
  • 58
  • 45
user5341372
  • 1,003
  • 9
  • 4
21

You can use require with the path to the global module directory as an argument.

require('/path/to/global/node_modules/the_module');

On my mac, I use this:

require('/usr/local/lib/node_modules/the_module');

How to find where your global modules are? --> Where does npm install packages?

Community
  • 1
  • 1
ling
  • 9,545
  • 4
  • 52
  • 49
9

Setting the environment variable NODE_PATH to point to your global node_modules folder.

In Windows 7 or higher the path is something like %AppData%\npm\node_modules while in UNIX could be something like /home/sg/.npm_global/lib/node_modules/ but it depends on user configuration.

The command npm config get prefix could help finding out which is the correct path.

In UNIX systems you can accomplish it with the following command:

export NODE_PATH=`npm config get prefix`/lib/node_modules/
cancerbero
  • 6,799
  • 1
  • 32
  • 24
Ben Xu
  • 1,279
  • 4
  • 13
  • 26
3

Easy answer is to run node in npm global root directory.

cd $( npm root -g ) && node
0

I am using Docker. I am trying to create a docker image that has all of my node dependencies installed, but can use my local app directory at container run time (without polluting it with a node_modules directory or link). This causes problems in this scenario. My workaround is to require from the exact path where the module, e.g. require('/usr/local/lib/node_modules/socket.io')

0

If you are on windows cmd, you can do it via FOR /f "tokens=* delims=" %A in ('npm root --quiet -g') do set "NODE_PATH=%A" or FOR /f "tokens=* delims=" %%A in ('npm root --quiet -g') do set "NODE_PATH=%%A" in a batch file.

Donghua Liu
  • 1,776
  • 2
  • 21
  • 30
-2

require.paths is deprecated.

Go to your project folder and type

npm install socket.io

that should install it in the local ./node_modules folder where node will look for it.

I keep my things like this:

cd ~/Sites/
mkdir sweetnodeproject
cd sweetnodeproject
npm install socket.io

Create an app.js file

// app.js
var socket = require('socket.io')

now run my app

node app.js

Make sure you're using npm >= 1.0 and node >= 4.0.

4b0
  • 21,981
  • 30
  • 95
  • 142
Jamund Ferguson
  • 16,721
  • 3
  • 42
  • 50