27

Normal installation would be sudo apt install nodejs to install Node.js and then sudo apt install npm to install Node Package Manager. However, upon doing so, npm -v says 3.5.2. To upgrade normally, I would do sudo npm install -g npm, which updates to the latest version (which, at the time of writing this article, is 6.0.1).

When I do a which npm, I get /usr/local/bin/npm, however apt installs a symlink at /usr/bin/npm. If I sudo apt purge npm to remove npm, it still leaves the npm version of npm at /usr/local/bin/npm, however npm -v says -bash: /usr/bin/npm: No such file or directory.

Many articles say to use a PPA to install nodejs, but I think there should be a native way to do this through apt.

DigitalOcean instructions on installation normally and through PPA: https://www.digitalocean.com/community/tutorials/how-to-install-node-js-on-ubuntu-18-04

TecAdmin instructions on installation through PPA: https://tecadmin.net/install-latest-nodejs-npm-on-ubuntu/

4 Answers 4

57

TLDR: This problem is caused by Bash caching the path of the npm command, and can be solved by hash -d npm. You don't even need to deal with apt purge unless you want to.

Explanation

Here were my steps for getting a new npm version on Ubuntu. First, do the installation as OP describes:

$ sudo apt-get install npm
(...apt installation of npm was successful...)
$ npm -v
3.5.2
$ command -v npm
/usr/bin/npm
$ sudo npm install -g npm
(...npm installation of npm was successful...so far, so good)

You can see that the new version is already working fine in /usr/local/bin/npm, but unfortunately the Bash cache still has /usr/bin/npm:

$ /usr/local/bin/npm -v
6.4.1
$ npm -v
3.5.2
$ command -v npm
/usr/bin/npm
$ type npm
npm is hashed (/usr/bin/npm)

To fix the problem, clear it from the Bash cache (do this in all open shells):

$ hash -d npm

Now the new version works as desired:

$ npm -v
6.4.1
$ command -v npm
/usr/local/bin/npm
5
  • 1
    I actually like this answer better than my own.
    – Blairg23
    May 31, 2019 at 19:36
  • This solved my problem. Thank you so much. Great explanation, too. The one thing that's unclear to me is the exact nature of why clearing the bash cache fixes the problem. Wouldn't it be better to delete the npm stored at /usr/bin/npm? And why is the right version picked up after clearing the bash cache, if both versions remain installed? Dec 26, 2019 at 4:23
  • @temporary_user_name You can see the path using echo $PATH, which shows that /usr/local/bin will be preferred before /usr/bin if both targets exist when Bash looks through the path. Bash looks through the path only if it doesn't remember where it found the target before.
    – krubo
    Aug 20, 2020 at 15:26
  • Lifesaver! Thx. I was stuck trying to do a production build for hours. This solved the issue.
    – RyanNerd
    Oct 10, 2020 at 20:52
  • All I had to do was hash -d npm then everything was running!!! Thanks alot!!!
    – Tom Bird
    Nov 3, 2020 at 5:51
12

The way I found is to purge npm through sudo apt purge npm, then simply recreate a symlink to the global installation via ln -s /usr/local/bin/npm /usr/bin/npm. After that fix, npm -v returns 6.0.1 as expected.

3
  • 2
    Worked with Ubuntu 18.04 running through UserLAnd on Android 6.0.1. Thank you! :)
    – l3l_aze
    Aug 26, 2018 at 8:58
  • 1
    OP you should mark this as the answer. Dec 2, 2018 at 17:07
  • Weird thing, for me it was quite different. I had the updated version in /usr/bin/npm, so I went the opposite route using ln -s /usr/bin/npm /usr/local/bin/npm. Strange, but your answer helped me to find out how to deal with the incorrect version issue. May 13, 2019 at 6:34
2

To have control on installed npm version, I always use nvm (node version control). You can install it through the instructions here: https://github.com/creationix/nvm Then by following command install the latest npm on your computer:

nvm install node

0

Unfortunately none of the other answers worked for me. Here is how I got it to work on Ubuntu 18.04.

tl;dr do this:

sudo ln -s /usr/local/lib/nodejs/node-v10.16.3-linux-x64/bin/npm /usr/local/bin

Explanation:

I had installed npm via the default repositories (i.e. not PPA) which installed the npm executable to /usr/bin/npm.

When I updated it with sudo npm install -g npm, a new executable was installed to /usr/local/lib/nodejs/node-v10.16.3-linux-x64/bin/npm.

To get npm to work for a non-root user, you can put the following in that user's ~/.profile file (which I think is what is done when doing npm install -g npm without sudo):

# Nodejs
VERSION=v10.16.3
DISTRO=linux-x64
export PATH=/usr/local/lib/nodejs/node-$VERSION-$DISTRO/bin:$PATH

However since this directory is not in root's $PATH environment variable it won't work for sudo commands:

$ sudo npm -v
3.5.2

As you can see, sudo does not use the latest npm, but instead uses the one installed via the package manager.

The root's default $PATH on Ubuntu is:

root ~# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin

Since the package manager version of npm was installed in /usr/bin, we can just create a symbolic link to put the latest version higher up the $PATH priority chain, like /usr/local/bin, and this way it also won't be overwritten if the package manager version is ever updated:

$ sudo ln -s /usr/local/lib/nodejs/node-v10.16.3-linux-x64/bin/npm /usr/local/bin
$ sudo npm -v                                                                                                                                                                                                    
6.14.1          

Note I'm assuming that if node is ever updated as well, this path will change, so you will have to repeat this step with the updated path:

$ sudo rm /usr/local/lib/nodejs/node-v10.16.3-linux-x64/bin/npm
$ sudo ln -s /usr/local/lib/nodejs/{NEW_NODE_VERSION}-linux-x64/bin/npm /usr/local/bin

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .