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/

Blairg23
  • 487

4 Answers4

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
krubo
  • 951
11

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.

Blairg23
  • 487
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
Mike
  • 713