74

I tried to install generator-angularjs using Yo (Yoeman) without sudo:

npm install -g generator-angular

I get:

Error: EACCES, mkdir '/usr/lib/node_modules/generator-angular'

When I type in sudo yo, yo tells me that I should not use sudo (which is perfectly understandable).

I have a ~/node_modules directory - why doesn't yo install its packages there?

lorem monkey
  • 3,942
  • 3
  • 35
  • 49
Karan
  • 14,824
  • 24
  • 91
  • 157

6 Answers6

175

Generators are designed to be installed globally. Otherwise, you always have to install the generator you're about to use in each project, which is unnecessarily painful. Also, you don't get to see the lovely yo menu which lists you all the available generators (unless of course, you install them all locally):

yo

Setting up npm for global installation

So, how do we get npm to install packages globally? As you correctly said, you should never, ever run yo with sudo. There are lots of different solutions to this problem and you can spend hours discussing their pros and cons religiously.

I personally dislike installing my user packages into the global /usr/ folder. /usr/ is for software that is shared across all users on the computer. Even if it's only using the machine, there are still good reasons to respect the way the Unix file system hierarchy is designed. For example if you decide at one point to wipe your whole node installation.

My preferred way of enabling npm to install packages globally without breaking out of $HOME is to set a local node prefix. This is as easy as running

echo 'prefix = ~/.node' >> ~/.npmrc

in your local shell. After that, you want to adjust your $PATH, to point to the new installation destination for global node executables by adjusting your favorite shell's config. E.g. by adding

export PATH="$PATH:$HOME/.node/bin"

to your ~/.bashrc. After that, you can happily run npm install -g generator-angular without sudo, without running into permission conflicts and if something is completely broken and you want to start from scratch, all you need to do is remove your ~/.node directory.

alpi
  • 173
  • 1
  • 4
  • 14
passy
  • 7,170
  • 5
  • 36
  • 38
  • 1
    There shouldn't be a '$' in front of PATH when setting it. (I tried to perform an edit, but there is a unhelpful rule that 'edits must be at least 6 characters,' so the save was rejected.) – febeling Dec 29 '13 at 17:27
  • You're of course absolutely right. Thanks, I updated the answer. – passy Dec 29 '13 at 18:24
  • Additional note: well 1st i am running - OS 10.9 Mavericks at time of writing this. To find your bashrc file you can use `locate` command ie `locate bashrc` - see this post for more on locate command and about activating it https://stackoverflow.com/questions/13056247/use-osx-keychain-with-git/19649085#19649085 – jamie Jun 05 '14 at 05:25
  • @passy Any idea what could have gone wrong if after all that I still get EACCES error when installing generators? – Markus Jun 29 '14 at 19:35
  • 1
    @passy I still have access rights problems but it seems the prefix was set: **npm config get prefix => /home/friedrich/.node**. any idea why? ~/.node is in PATH :-/ – stephanfriedrich Jul 01 '14 at 14:40
  • @passy wouldn't it be much better to install node under a path like /opt/bin and give this path user access rights? Then you wouldn't have to install global node packages in the users home (which I think should be reserved for user data only). /usr/local/bin demands root access rights by default but we just noted above that using sudo with node packages isn't the way to go. But this might be something to ask the nodejs team. – Markus Jul 01 '14 at 19:39
  • Like @pukoo I also still have the permissions problem after following these instructions. npm config get prefix shows the proper path, but it still gives the error EACCES, mkdir '/usr/lib/node_modules/yo' – Stephen Smith Jul 15 '14 at 14:35
  • 2
    I just ran `sudo npm update -gf` and it fixed it. What did I do, and was it alright that I used sudo in this case? – Stephen Smith Jul 15 '14 at 14:59
  • 3
    I also needed to add: sudo chown -R 'username' ~/.npm – Marco Ramires Oct 15 '14 at 05:55
  • @passy I see a comment about removing that $ but I still see the $... confusing. – jcollum Oct 17 '14 at 18:18
  • @jcollum That comment has been addressed long ago. – passy Oct 17 '14 at 18:28
  • "There shouldn't be a '$' in front of PATH when setting it." and then you agreed, but I still see the $. pagetribe's answer below worked for me and it doesn't have the $. – jcollum Oct 17 '14 at 18:32
  • 1
    The second command should be `echo 'export PATH=$HOME/.node/bin:$PATH' >> ~/.bashrc` – Ryan Oct 30 '14 at 15:57
  • 1
    You have to also update your NODE_PATH env variable or yo can't see the generators you've installed. You can do this with the following command: echo "export NODE_PATH=$NODE_PATH:$HOME/.node/lib/node_modules" >> ~/.bashrc && source ~/.bashrc – mikesigs Dec 02 '14 at 23:00
  • `echo 'prefix = ~/.node' >> ~/.npmrc ` this worked for me! thank you. – seoyoochan Jun 16 '15 at 09:34
  • So... if you want to update npm after this what should you do? If I do `npm install -g npm` it installs it to my home folder but `npm -v` returns an older version. – GameKyuubi Jan 19 '19 at 20:09
  • How can I do the exact same thing but with zsh rather than with bash? – srWebDev May 07 '20 at 15:06
27

Thanks to @passy I managed to finally get this working on ubuntu 13.04 (in case anyone is having similar set up issues) with the following :

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

trying to run:

npm install -g yo

resulted in

Error: EACCES, mkdir '/usr/lib/node_modules/yo'

Fixed using:

echo prefix = ~/.node >> ~/.npmrc
echo 'export PATH=$HOME/.node/bin:$PATH' >> ~/.bashrc 
. ~/.bashrc

Running:

yo webapp

resulted in:

Error: EACCES, permission denied '/home/username/.config/configstore/update-notifier-yo.yml'

Fixed using:

sudo chown yourusername:yourusername /home/yourusername/.config/configstore/update-notifier-yo.yml
pagetribe
  • 15,031
  • 3
  • 24
  • 18
0

hi in my case (on ubuntu 12.04), the prefix addition in ~/.npmrc did not changed anything.

if so, build the node package by yourself and install it in /opt/node or /home/user/.node.

stephanfriedrich
  • 563
  • 5
  • 20
0

I had an almost identical error involving a rogue .yo-rc.json file in my root directory from a project I installed earlier. Yeoman was switching cwd from the installation dir to root dir half way through the installation, but was only outputting the EACCESS permissions error without any details that the installation directory was /. It took ages to figure out why this was, and involved debugging through the Yeoman source, but I eventually learned that Yeoman will look up through the directory tree until it finds a .yo-rc.json, and generate the code there by calling chdir to the new location.

Yeoman should maybe check that the user has write permissions for the directory. Alternatively, it could mention in the output either that the cwd has changed, or print the name of the installation directory if where it finds .yo-rc.json is different than cwd.

The command for finding rogue .yo-rc.json files

sudo find / -name .yo-rc.json

Sean
  • 11
  • 2
0

From yoeman getting started page appears the command:

yo doctor

In my case, $NODE_PATH (which in my case, Ubuntu 14.04, is defined in /etc/profile.d) isn't the same than npm root. Adding in npm root in $NODE_PATH solve the problem.

molavec
  • 8,848
  • 1
  • 27
  • 22
  • it necessary restart. Another way is add $NODE_PATH=$NODE_PATH:/usr/local/lib/node_modules in your .bashrc. – molavec Feb 27 '16 at 19:52
0

I have been trying to get yeoman to play nice with my vagrant box and this is what I had to do to install npm packages globally without sudo on ubuntu:

1. Create the directory to store global packages

$ mkdir "${HOME}/.npm-packages"

2. Tell npm where to put any packages installed globally

Insert this snippet into your ~/.npmrc file:

prefix=${HOME}/.npm-packages

3. Make sure that npm can locate installed binaries et cetera

Insert this snippet into your .bashrc/.zshrc:

NPM_PACKAGES="${HOME}/.npm-packages"

PATH="$NPM_PACKAGES/bin:$PATH"

// `unset` `manpath` to allow inheritance from `/etc/manpath` with
// the `manpath` command
unset MANPATH // remove this line if you have previously modified `manpath`
export MANPATH="$NPM_PACKAGES/share/man:$(manpath)"

4. Run the following or restart terminal

$ source ~/.bashrc

Hope this helps anyone who finds themselves in a similar situation.

datatype_void
  • 433
  • 5
  • 23