NodeJS require a global module/package
Solution 1
In Node.js, require doesn't look in the folder where global modules are installed.
You can fix this by setting the NODE_PATH environment variable. In Linux this will be:
export NODE_PATH=/usr/lib/node_modules
Note: This depend on where your global modules are actually installed.
See: Loading from the global folders.
Solution 2
After you install package globally you have to link the local project with global package
npm install express -g
cd ~/mynodeproject/
npm link express
See here
Solution 3
Apologies for the necromancy but I'm able to specify hard-coded paths to globally installed modules:
var pg = require("/usr/local/lib/node_modules/pg");
This isn't perfect but considering that Unity3d tries to "compile" all javascript that is included in the project directory I really can't install any packages.
Solution 4
As per documentation, Node.js will search in the following locations by default:
-
Path specified in the
NODE_PATH
environment variable.Note:
NODE_PATH
environment variable is set to a colon-delimited list of absolute paths. Current
node_modules
folder. (local)-
$HOME/.node_modules
(global)Note:
$HOME
is the user's home directory. -
$HOME/.node_libraries
(global) -
$PREFIX/lib/node
(global)Note:
$PREFIX
is Node.js's configurednode_prefix
.To check the current value of
node_prefix
, run:node -p process.config.variables.node_prefix
Note: Prefix corresponds to
--prefix
param during build and it's relative toprocess.execPath
. Not to confuse with value from thenpm config get prefix
command.source
If the given module can't be found, that means it is not present in one of the above locations.
Location of global root folder where modules are installed can be printed by: npm root -g
(by default the path is computed at run-time unless overridden in npmrc
file).
Solution
You can try the following workarounds:
-
Specify your global module location in
NODE_PATH
environment variable. E.g.echo 'require("forever")' | NODE_PATH="$(npm root -g):$NODE_PATH" node
To test and print the value of
NODE_PATH
, run:echo 'console.log(process.env.NODE_PATH); require("forever")' | NODE_PATH="$(npm root -g):$NODE_PATH" node
-
For more permanent solution, link your
$HOME/.node_modules
global user folder to point to the root folder, by running this command:ln -vs "$(npm root -g)" "$HOME"/.node_modules
Then re-test it via:
echo 'require("forever")' | node
command. -
Temporary change the current folder to where the extension has been installed globally, before invoking the script. E.g.
npm install -g forever cd "$(npm root -g)" echo 'require("forever")' | node cd -
-
Configure global installation destination in
npm
userconfig file (see:npm help 5 npmrc
) or byuserconfig
param (--prefix
).To display the current config, run:
npm config list
.To edit the current config, run:
npm config edit
. -
Specify the full path of node modules location when calling
require()
. E.g.require("/path/to/sub/module")
-
Install the package to custom location, e.g.
npm install forever -g --prefix "$HOME"/.node_modules
However, the installation will go under
~/.node_modules/lib/node_modules/
, so the location still needs to be added. -
Create a symlink in the current folder from the location of the global package. E.g.
npm link forever
Solution 5
I know this is an old question, but I ran into this when trying to do some version checking using semver
in a preinstall
script in package.json
. Since I knew I can't depend on any local modules installed, I used this to require semver
from the global node_modules
folder (as npm
depends on it I know it's there):
function requireGlobal(packageName) {
var childProcess = require('child_process');
var path = require('path');
var fs = require('fs');
var globalNodeModules = childProcess.execSync('npm root -g').toString().trim();
var packageDir = path.join(globalNodeModules, packageName);
if (!fs.existsSync(packageDir))
packageDir = path.join(globalNodeModules, 'npm/node_modules', packageName); //find package required by old npm
if (!fs.existsSync(packageDir))
throw new Error('Cannot find global module \'' + packageName + '\'');
var packageMeta = JSON.parse(fs.readFileSync(path.join(packageDir, 'package.json')).toString());
var main = path.join(packageDir, packageMeta.main);
return require(main);
}
I like this approach because this doesn't require the install of any special modules in order to use.
I didn't go with a NODE_PATH
solution like others have suggested since I wanted to get this to work on anyone's machine, without having to require additional configuration/setup before running npm install
for my project.
The way this is coded, it is only guaranteed to find top-level modules (installed using npm install -g ...
) or modules required by npm
(listed as dependencies
here: https://github.com/npm/npm/blob/master/package.json). If you are using a newer version of NPM, it may find dependencies of other globally installed packages since there is a flatter structure for node_modules
folders now.
Hope this is useful to someone.
Related videos on Youtube
alexandernst
Updated on December 26, 2020Comments
-
alexandernst over 3 years
I'm trying to install globally and then use
forever
andforever-monitor
like this:npm install -g forever forever-monitor
I see the usual output and also the operations that copy the files to the global path, but then if I try to
require("forever");
I get an error saying that the module wasn't found.I'm using latest version of both node and npm and I already know about the change that npm made in global vs local install, but I really don't want to install localy on every project and I'm working on a platform that doesn't support
link
sonpm link
after a global install isn't possible for me.My question is: why I can't require a globally installed package? Is that a feature or a bug? Or am I doing something wrong?
PS: Just to make it crystal clear: I don't want to install locally.
-
Marecky over 5 years
-
Skippy le Grand Gourou about 5 yearsPossible duplicate of How do I import global modules in Node? I get "Error: Cannot find module <module>"?
-
localhostdotdev about 5 yearsso it's
~/.config/yarn/global
for yarn
-
-
alexandernst about 11 yearsI'm running on a platform that doesn't support link (as my question states) blog.nodejs.org/2011/04/06/npm-1-0-link
-
user568109 about 11 yearswhich platform are you using ?
-
alexandernst about 11 yearsI'm on Windows XP. I'm de deploying to a Linux machine (which does support link). Anyways, I'd like to be able to require modules on my dev machine (the XP one)
-
user568109 about 11 yearscan u try fsutil for symlink it looks like some work but worth trying serverfault.com/questions/7109/…
-
alexandernst about 11 yearsI really don't want to mess with link (nor symbolic links at all). I just want to install packages globally and require them. I know NPM was re-designed to avoid this, but how hard could it be to achieve something like this?
-
Drew Noakes over 10 yearsOn my Ubuntu 13.10 machine, the global path for modules is different than you show here. I had to use
export NODE_PATH=/usr/local/lib/node_modules
instead. -
Wes Johnson about 10 yearsIf you're on Windows 7 / 8 and haven't overridden any of Node's install defaults, setting the
NODE_PATH
environment variable toC:\Users\{USERNAME}\AppData\Roaming\npm\node_modules
will likely work. -
AnnanFay almost 10 yearsWhat if I don't have a project? Say
~/some-stand-alone-random-nodejs-test.js
. I don't want to turn my home folder into a project directory. I don't want to create new folders for every small experiment. -
dynamiclynk over 9 yearsWorked perfect on Windows 8.1. From node command line cd to my projects' local node_modules folder then executed
npm link <module>
Then you will see a shortcut(link) created in your projects' node_module folder referencing the global node module. -
theblang over 8 years@WesJohnson Just
%AppData%\npm\node_modules
will work on Windows 10. -
Flion over 8 yearswatch out, if you ever remove the project, including the
node_modules
folder, you'll remove your global module installation -
Paulo Oliveira about 8 yearsIf I set
NODE_PATH
can I use global and local modules simultaneously? -
Alexander Mills almost 8 yearsinteresting, but the NODE_PATH method is probably more canonical
-
amenthes over 7 yearsthe beauty of
NODE_PATH
is also, that you don't need to change any code. (my use case is grading a lot of student projects, where I don't want to runnpm install
for each one, and also don't want them to providenode_modules
directory). -
lifeisfoo over 7 years@DrewNoakes same path in alpine linux
-
Slipp D. Thompson about 7 yearsUnity3D doesn't support JavaScript. It supports a JS-like syntax for its Boo interpreter/compiler (Boo is a Python-like language for .NET) that is deceptively marketed as “JavaScript”. The more-accurate name for the language Unity supports is UnityScript. Because it's not even close to the same language, next to none of the JS written for the web or for Node.js will work in Unity. Much more info on the differences on the official Unity wiki: wiki.unity3d.com/index.php/UnityScript_versus_JavaScript
-
Carmela about 7 yearsThis is not working for me. I've set the NODE_PATH to the exact location of globally installed node_modules but simple require('module_name') still doesn't work. (using linux)
-
jpaugh over 6 years@flion That varies greatly depending on which OS and which method you use to remove the files. Every OS which uses symlinks (or shortcuts) provides a method to remove the link without removing the target; but yes, you do need to be careful.
-
Király István over 5 years@Carmela, you must export NODE_PATH in the shell process where you actually start node.
-
Király István over 5 yearsIt looks like 4. Current node_modules folder. (local) takes priority over 3. $PREFIX/lib/node (global)
-
Király István over 5 yearsLocal node_modules folders always take priority over global folders!
-
holmberd almost 5 yearsAlternatively instead of a static path, i.e. if you are using NVM:
NODE_PATH=$(npm root -g)
-
thisismydesign over 4 yearsNo, it will not do the trick because you can't require
requireg
in the first place, this is the whole point. -
Luis Paulo over 4 yearsNo. This is the generic way of getting the global
node_modules
. This is an old answer but I remember I got it from somwhere in the documentation. Anyway, in my computer (in 2020) the global npmnode_modules
directory isusr/lib/node_modules
. Anyway, I trustnpm config get prefix
because it is used globally by npm whenever a global package is installed so it should be right. -
Luis Paulo over 4 yearsEither way (I didn't say this in my initial answer because I wasn't very experienced in Node.JS), using globally installed packages in a program is an edge use case and should seldom be done because in a project it will create problems whenever the project is committed to VCS and cloned in another environment due to that specific dependency not being in the
package.json
file or inyarn.lock
/package-lock.json
. -
Luis Paulo over 4 yearsOh! I understand now. I believe you're mistaking the NODE_PATH with PATH. PATH is where a shell will look for executables. NODE_PATH is where node will look for packages. It will start by looking at the current directory for a
node_modules
folder, then it's parent, then it's parent, ... until it finds anode_modules
folder which contains that module. However, if you install a package globally, it won't be inside anynode_modules
folder above the script's current directory so you use NODE_PATH as a fallback where node will look for packages. -
Ryan Taylor over 4 yearsahahahah @Luis Paulo you're totally right!! I'm sorry! I'll try and delete some of my comments to prevent confusion, nice job and thank you
-
Luis Paulo over 4 years@Ryan Taylor You shouldn't delete comments and questions once they get resolved because someone else could have the same ones. Now it just looks like I had a monologue in the comments! ahahahah
-
Vlad almost 4 yearsor for custom global path
var pg = require('/home/<username>/.npm-global/lib/node_modules/pg')
-
ruffin over 3 yearsNever apologize for necromancy. It's a badge for cryin' out loud. ;^)
-
Leo Gasparrini over 3 yearsThanks man! I appreciate it, it's working fine now. JIC I want to mention that I could fix it on macOS
-
Henrique Bruno about 3 years
export NODE_PATH=$(npm root -g)
also works for n -
Kenneth Garza almost 3 yearsi was having issues with shellJs + typescript + ncc + docker working properly. This answer lead me down the right path and finally got it to work using a globally installed shelljs and requireq.
let shell = require("requireg")("shelljs");
-
José Manuel Blasco over 2 yearsAwesome function! Thank you!
-
Jeff about 2 years@holmberd definitely the preferred answer! Do you happen to know if there's a hook in nvm so that it will automatically be re-exported following
nvm use
? -
holmberd about 2 years@Jeff not that I know off. You can always create an alias for
nvm use
to also execsource
.