NPM modules won't install globally without sudo
I have just reinstalled Ubuntu 12.04 LTS, and before anything else i did these steps:
-
Installed Node via package manager with the following script
sudo apt-get update sudo apt-get install python-software-properties python g++ make sudo add-apt-repository ppa:chris-lea/node.js sudo apt-get update sudo apt-get install nodejs
-
Tried to install yeoman, express, n, yeoman's generators globally and all of them returned the same error
npm ERR! Error: EACCES, symlink '../lib/node_modules/n/bin/n'
npm ERR! { [Error: EACCES, symlink '../lib/node_modules/n/bin/n'] errno: 3, code: 'EACCES', path: '../lib/node_modules/n/bin/n' }
npm ERR!
npm ERR! Please try running this command again as root/Administrator.
npm ERR! System Linux 3.8.0-29-generic
npm ERR! command "/usr/bin/node" "/usr/bin/npm" "install" "-g" "-d" "n"
npm ERR! cwd /home/heberlz
npm ERR! node -v v0.10.20
npm ERR! npm -v 1.3.11
npm ERR! path ../lib/node_modules/n/bin/n
npm ERR! code EACCES
npm ERR! errno 3
npm ERR! stack Error: EACCES, symlink '../lib/node_modules/n/bin/n'
npm ERR!
npm ERR! Additional logging details can be found in:
npm ERR! /home/heberlz/npm-debug.log
npm ERR! not ok code 0
Reclaimed ownership of the following folders recursively ~/.npm, /usr/lib/node, /usr/lib/node_modules, and of the following symlinks /usr/bin/node, /usr/bin/nodejs with absolutely no success
I need to install yeoman and its generators without sudo not to be in trouble later on :(
Solution 1:
Ubuntu 12.04 and using Chris Lea's PPA for install the following works for me:
npm config set prefix '~/.npm-packages'
and adding $HOME/.npm-packages/bin to $PATH
append to .bashrc
export PATH="$PATH:$HOME/.npm-packages/bin"
see https://stackoverflow.com/a/18277225 from @passy
Solution 2:
If you already have $HOME/bin
in your path, a simpler solution is just ...
npm config set prefix ~
- New node commands will now install into your
$HOME/bin
directory. - No need to change your path!
Since this discussion is really about reducing the security risks of running sudo
, you should also be aware that any node app could potentially be installing an app name that does not match the registered node package name you think you're installing. So there is a security risk that an npm install
will replace an existing system command or one you already have in $HOME/bin
. If you're concerned, check the bin
, and scripts
properties in the package.json
file of the app you're installing first.
In general, it's safest to:
- (a) Place
$HOME/bin
last in your path so system commands are not superseded. - (b) don't include "." or any relative path in your
$PATH
so you don't accidentally run a command that happens to be in the current directory.
Reference:
- package.json properties
- npm install
- NodeJS security vulnerabilities: nodesecurity.io.
Solution 3:
As for October 2014:
Node.js is available from the NodeSource Debian and Ubuntu binary distributions repository.
curl -sL https://deb.nodesource.com/setup | sudo bash -
sudo apt-get install -y nodejs
That's it.
Outdated answer:
The fastest way without using sudo is like described here by isaac
I strongly encourage you not to do package management with sudo! Packages can run arbitrary scripts, which makes sudoing a package manager command as safe as a chainsaw haircut. Sure, it's fast and definitely going to cut through any obstacles, but you might actually want that obstacle to stay there.
I recommend doing this once instead:
sudo chown -R $USER /usr/local
EDIT:
There are certain security concerns and functionality limitations regarding changing the ownership of /usr/local to the current user:
- if there is another user on the machine who could use global npm packages - do not change the ownership of /usr/local
- https://apple.stackexchange.com/questions/1393/are-my-permissions-for-usr-local-correct
- https://askubuntu.com/questions/261326/is-it-safe-to-chown-usr-local
Having said that, if you want to install global module without using sudo, I don't see any better solution (from pragmatic point of view) than mentioned. Security vs easy of use is very broad topic, and there is no easy answer for that - it just depends on your requirements.
Solution 4:
The issue was i installed node using sudo, to avoid errors when installing npm modules globally one MUST NEVER install node with sudo.
My solution was to reinstall node it this way:
Download latest stable node sources from nodejs.org #in my case node-v0.10.20.tar.gz
tar -zxf node-v0.10.20.tar.gz #uncompress sources
cd node-v0.10.20 #enter uncompressed folder
sudo chown -R $USER /usr/local
./configure --prefix=/usr/local && make && make install
One thing to note is that only taking ownership of the /usr/local folder wouldn't work in my case because node installation itself was made with sudo
Last step to install yeoman: #although at yeoman.io it says that doing "npm install -g yo" already installs bower and grunt, there are some submodules of grunt that fail, so i fixed that by installing it by itself
npm install -g bower
npm install -g grunt
npm install -g yo
npm install -g generator-angular