Running npm install using custom nodejs installation - node.js

I have 2 nodejs installation v0.8.18 ( executable name is node) and v0.10.20 (executable name is nodejs) in my ubuntu 12.04 system.
when I running npm install how can I specify npm use the executable named "nodejs" instead of "node"

If you in-fact actually want to toggle between various nodejs releases, there is an environment variable NODE_PATH which controls the directory path node uses to reach modules. The other issue is the env var PATH which the unix uses to reach executables, IE. node and npm
Additionally, node/npm uses these dirs/files :
~/.npmrc
~/.npm
~/tmp
~/.npm-init.js
those may or may not be impacted by different releases of node.
If you install each release from source code you have full control of NODE_PATH and PATH
source code for all releases available at http://nodejs.org/dist/
Below are the steps to install a given release from source
NOTE - this installs nodejs which gives you both node as well as npm, they come together per release.
to start fresh remove prior node.js and npm installs as well as these :
sudo mv ~/.npmrc ~/.npmrc_ignore
sudo mv ~/.npm ~/.npm_ignore
sudo mv ~/tmp ~/tmp_ignore
sudo mv ~/.npm-init.js ~/.npm-init.js_ignore
to install nodejs and npm as yourself NOT root do these commands (OSX/linux) :
parent_dir=${HOME}/bin_xxxx # replace bin_xxx with something specific
# to node release like bin_v0.10.31
mkdir ${parent_dir}
download source from : http://nodejs.org/download/
cd node-v0.xxxx
./configure --prefix=${parent_dir}/nodejs
make -j8
make install
which puts it into dir defined by above --prefix
export PATH=${parent_dir}/nodejs/bin:$PATH
define environment variable NODE_PATH so node can find dir for modules otherwise
npm install xxx will put newly installed module into dir in curr dir :
export NODE_PATH=${parent_dir}/nodejs/lib/node_modules
do above AND use syntax : npm install -g some_cool_module
always use the -g for global so it gets installed into dir $NODE_PATH
and not your $PWD
nodejs install gives you npm as well :
ls -la ${parent_dir}/nodejs/bin

Related

npm upgrade with homebrew

When node (v.0.10.33) is installed with homebrew (v. 0.9.5), at one point it says:
==> Caveats
If you update npm itself do NOT use the npm upgrade command
Instead execute:
npm install -g npm#latest
So, what exactly is npm upgrade and what is the difference with npm install -g npm#latest?
-- edit 2015
the problem doesn't exist anymore with the current version of node. (but I never had an answer to what npm upgrade is?)
Use npm install to install a package and npm update to update a package.
That Homebrew npm caveat was removed after the issue with npm update -g was fixed.
npm comes bundled with node, both part of Node.js install --- no need to install separately
Below are the steps to install Node.js from source (OSX/linux)
Issue cmds as yourself NOT root (sudo)
to start fresh remove prior node and npm installs as well as these :
sudo mv ~/.npmrc ~/.npmrc_ignore
sudo mv ~/.npm ~/.npm_ignore
sudo mv ~/tmp ~/tmp_ignore
sudo mv ~/.npm-init.js ~/.npm-init.js_ignore
download source from : http://nodejs.org/download/
cd freshly-downloaded-dir
define environment variable NODE_PATH as the dir for subsequent module installs
export NODE_PARENT=${HOME}/nodejs-v0.10.33
export PATH=${NODE_PARENT}/bin:${PATH}
export NODE_PATH=${NODE_PARENT}/lib/node_modules
./configure --prefix=${NODE_PARENT}
make
make install # IMPORTANT this is NOT using sudo
# not wanted since installing into $USER owned $NODE_PARENT
which puts it into dir defined by above --prefix
when you use syntax : npm install -g some_cool_module
the -g for global installs it into dir $NODE_PATH and not your $PWD
Now put above three export xxx=yyy
commands into your ~/.bashrc or some such to persist these environment variable changes

Npm not working after Mavericks update

My npm in terminal isn't working after Mavericks update.
node app.js works well and runs my app, but when I run npm followed by anything I get -bash: npm: command not found. I know this question has been asked before here:
Global installation with npm doesn't work after Mac OS X Mavericks update
and
How do I install a module globally using npm?
and npm not working after reinstalling Mac OS X
, but none of the answers resolved my situation.
$ echo $PATH /usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/opt/X11/bin:/usr/local/mongodb/bin
How did you install node.js ? typically it comes bundled with both node and npm, where both are in the same directory. My suggestion is to remove your current install(s) and do the following with just works.
to install nodejs and npm as yourself NOT root do these commands (OSX/linux) :
parent_dir=${HOME}/bin_xxxx # replace bin_xxx with something specific
# to node release like bin_v0.10.31
mkdir ${parent_dir}
download source from : http://nodejs.org/download/
cd node-v0.xxxx
./configure --prefix=${parent_dir}/nodejs
make -j8
make install
which puts it into dir defined by above --prefix
export PATH=${parent_dir}/nodejs/bin:$PATH
define environment variable NODE_PATH so node can find dir for modules otherwise
npm install xxx will put newly installed module into dir in curr dir :
export NODE_PATH=${parent_dir}/nodejs/lib/node_modules
do above AND use syntax : npm install -g some_cool_module
always use the -g for global so it gets installed into dir $NODE_PATH
and not your $PWD
nodejs install gives you npm as well :
ls -la ${parent_dir}/nodejs/bin
For Debian, after installing node do following
curl -k -O -L https://npmjs.org/install.sh
ln -s /usr/bin/nodejs /usr/bin/node
sh install.sh

How do I know whether I have Node.js and npm successfully installed on Ubuntu 14.04?

I installed Node.js with these instructions and it seemed successful:
sudo add-apt-repository ppa:chris-lea/node.js
sudo apt-get update
sudo apt-get install nodejs
Then I installed npm with these instructions:
sudo curl https://www.npmjs.org/install.sh | sh
The nodejs installation seemed to work without errors but the npm command gave me a lot of errors. But it seems like they are installed because when I test what version I have they both come up:
nodejs -v
v0.10.30
npm -v
1.4.21
So If this doesn't tell me that I have both programs successfully installed, which I assume I do not, how do I know?
I think your tests tell that both or properly installed.
But you can try just type node in terminal & it should open a node shell, where you can check by running basic commands.
Current distributions of node.js (including the one you downloaded) already include npm. So maybe installing npm manually is one source of your errors. Beware that usually you run "npm install" with the permissions of a regular user. There are only some npm-based utilities that are to be installed with root permissions and the '-g' (global) command line switch.
On linux if you wish to install node.js and npm as yourself NOT root :
to start fresh remove prior node.js and npm installs as well as these :
~/.npmrc
~/.npm
~/tmp
~/.npm-init.js
create your ~/bin/ directory if not already created :
mkdir ${HOME}/bin
download source from : http://nodejs.org/download/
cd node-v0.10.30/
./configure --prefix=${HOME}/bin/nodejs
make -j8
make install
which puts it into dir defined by above --prefix
export PATH=${HOME}/bin/nodejs/bin:$PATH
define NODE_PATH so node can find dir for modules otherwise
npm install xxx will put newly installed module into dir in curr dir :
export NODE_PATH=${HOME}/bin/nodejs/lib/node_modules
do above AND use syntax :
npm install xxxxx -g
always use the -g for global which puts package xxxxx into $NODE_PATH
NOTE - nodejs install gives you npm as well :
ls -la ${HOME}/bin/nodejs/bin

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 :(
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"
For more see this answer from #passy
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.
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.
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
I solved this problem with environment variable and shell alias:
export NPM_PREFIX=$HOME/node
alias npmg="npm -g --prefix $NPM_PREFIX"
For me npm did not honor the "prefix" config setting in .npmrc.
Find the path to npm's directory:
npm config get prefix
For many systems, this will be /usr/local.
Change the owner of npm's directories to the name of the current user (your username!):
sudo chown -R $(whoami) $(npm config get prefix)/{lib/node_modules,bin,share}
This changes the permissions of the sub-folders used by npm and some other tools (lib/node_modules, bin, and share).
Here is the link for full details
https://docs.npmjs.com/getting-started/fixing-npm-permissions
According to this similar SO post: npm throws error without sudo
Looks like you might have an ownership issue with ~/.npm directory.
As with the answer in that one, try:
sudo chown -R `whoami` ~/.npm
If you're on a developping machine, you might be better off considering using nvm.
If not, you simply want to install using your favorite package manager.
Whatever the case may be, I'd recommend checking this answer on stackoverflow
Actually, I just changed the permission of a user folder that was owned by root:
sudo chown -R $USER ~/.config/configstore
Then I could "npm install" and "bower install" without sudo!
Worked fine!
using lubuntu 14.04.3, I tried changing ownership of .npm and npm prefix, updated my path, npm installed modules to my home directory without sudo but the path was incorrect so the modules like ember were not found, linuxbew solved the problem, quick setup guide here for node/npm
This issue and other caused by the same reason can be solved installing Node in user space.
You can do it just copying and pasting in your terminal
NODEJS_ROOT=${NODEJS_ROOT:-~/nodejs}
cd /tmp
wget -N http://nodejs.org/dist/node-latest.tar.gz && tar xzf node-latest.tar.gz
NODEJS_CURRENT=$(tar tf node-latest.tar.gz|head -1)
mkdir -p $NODEJS_ROOT/$NODEJS_CURRENT
cd $NODEJS_CURRENT
./configure --prefix=$NODEJS_ROOT/$NODEJS_CURRENT && make install
cd $NODEJS_ROOT
rm current 2> /dev/null # Removes current symbolic link, if any
ln -s $NODEJS_CURRENT current
Same commands can be launched also to get Node updated to latest version.
Don't forget to edit your environment. Only once, do
echo "export NODEJS_ROOT=$NODEJS_ROOT" >> $HOME/.bash_profile
echo 'export PATH=$NODEJS_ROOT/current/bin:$PATH' >> $HOME/.bash_profile
source $HOME/.bash_profile # reload your env, so you can use node right now
Check out this article as a reabout how to Install Node.js without sudo.
For a more general solution about this topic (i.e., install software locally) see dotsoftware.
just use nvm
you will be able to dynamically switch between different node versions and it is installed locally for your user. No sudo needed. Just make sure you have fully cleaned up the old node beforehand.
https://github.com/nvm-sh/nvm
In order to install Node.js and npm locally without having to use sudo open the terminal and type:
echo 'export PATH=$HOME/local/bin:$PATH' >> ~/.bashrc
. ~/.bashrc
mkdir ~/local
mkdir ~/node-latest-install
cd ~/node-latest-install
wget -c http://nodejs.org/dist/node-latest.tar.gz | tar xz --strip-components=1
./configure --prefix=~/local
make install
wget -c https://www.npmjs.org/install.sh | sh
Use NVM
I had the same "permission denied" issue. Instead of trying to fix the NodeJS installed from https://nodejs.org/en/ which installs into folders that are owned by root instead of $USER, I used NVM. node version manager.
Install it: run curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
Install a version of node: run nvm install 16
Use it:
nvm use 16
npm install -g yarn
Everything worked fine when I used Node installed by NVM.
The best solution I found was to install Node.js from the tar package on to user home directory & link the lib folder location. Here is what you need to do
This will install Nodejs under ~/.local/ instead of the default /usr/local/
Add this to your ~/.npmrc (create the file if it doesn't exist already):
root = /home/YOUR-USERNAME/.local/lib/node_modules
binroot = /home/YOUR-USERNAME/.local/bin
manroot = /home/YOUR-USERNAME/.local/share/man
Download the Nodejs source code from nodejs.org and install it under your ~/.local tree:
tar xf node......
cd node........
./configure --prefix=~/.local
make
make install
Create ~/.node_modules symlink. (This directory will be automatically searched when you load modules using require "module" in scripts. I'm not sure why Node doesn't search ~/.local/lib/node_modules by default.)
cd
ln -s .local/lib/node_modules .node_modules
Is ~/.local/bin in your path? Type
which npm
If it says ~/.local/bin/npm, you're done.
Otherwise, do this...
export PATH=$HOME/.local/bin:$PATH
...and add that line to your ~/.profile file, so it'll run every time you log in.
If you still encounter ownership or permission error while installing packages, then change ownership of ~/.local/ dir by running
chown -R user:user ~/.local/
Now you should be good to install packages via 'npm'
Note: ALL OF THE ABOVE COMMANDS ARE TO BE RUN AS USER. DO NOT USE SUDO OR ROOT LOGIN
NEVER EVER CHANGE THE PERMISSION OF FOLDERS UNDER '/USR/LIB/'. WILL LEAD TO UNSTABLE OS
I find Pawel Grzybek's explanations very convincing: They boil down to 3 simple sudo commands, never having to use sudo again for global npm installs:
sudo chown -R $(whoami) /usr/local/lib/node_modules
sudo chown -R $(whoami) /usr/local/bin
sudo chown -R $(whoami) /usr/local/share

Install NPM into home directory with distribution nodejs package (Ubuntu)

I'd like to use the distribution Node.js packages (or the chris-lea ppa for more recent releases) but install NPM to my home directory.
This may seem picky, but it's a pretty idiomatic way for polyglot/github-using developers to setup language runtime/library environments under Linux: distro packages for the runtime, 3rd-party libraries in per-user environment (see virtualenv, RVM - RVM will also build Ruby for you if you want). If necessary I will build node locally but it's a PITA since Node is becoming an incidental development requirement for lots of projects.
Instructions for installing node+npm to home directory
NPM will install local packages into your projects already, but I still like to keep the system away from my operating system's files. Here's how I suggest compartmentalizing Nodejs packages:
Install Nodejs and NPM via the chris-lea PPA. Then I set up a package root in my homedir to hold the Node "global" packages:
$ NPM_PACKAGES="$HOME/.npm-packages"
$ mkdir -p "$NPM_PACKAGES"
Set NPM to use this directory for its global package installs:
$ echo "prefix = $NPM_PACKAGES" >> ~/.npmrc
Configure your PATH and MANPATH to see commands in your $NPM_PACKAGES prefix by adding the following to your .zshrc/.bashrc:
# NPM packages in homedir
NPM_PACKAGES="$HOME/.npm-packages"
# Tell our environment about user-installed node tools
PATH="$NPM_PACKAGES/bin:$PATH"
# Unset manpath so we can inherit from /etc/manpath via the `manpath` command
unset MANPATH # delete if you already modified MANPATH elsewhere in your configuration
MANPATH="$NPM_PACKAGES/share/man:$(manpath)"
# Tell Node about these packages
NODE_PATH="$NPM_PACKAGES/lib/node_modules:$NODE_PATH"
Now when you do an npm install -g, NPM will install the libraries into ~/.npm-packages/lib/node_modules, and link executable tools into ~/.npm-packages/bin, which is in your PATH.
Just use npm install -g as you would normally:
[justjake#marathon:~] $ npm install -g coffee-script
... (npm downloads stuff) ...
/home/justjake/.npm-packages/bin/coffee -> /home/justjake/.npm-packages/lib/node_modules/coffee-script/bin/coffee
/home/justjake/.npm-packages/bin/cake -> /home/justjake/.npm-packages/lib/node_modules/coffee-script/bin/cake
coffee-script#1.3.3 /home/justjake/.npm-packages/lib/node_modules/coffee-script
[justjake#marathon:~] $ which coffee
/home/justjake/.npm-packages/bin/coffee
Jake's answer was posted in 2012 and while useful it references Chris Lea's Node.js PPAs who are no longer updated since march 2015.
Here's the steps I use to install Node.js and npm in my home directory:
Install Node.js with nvm (no sudo required):
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.2/install.sh | bash
source ~/.bashrc
nvm install 7
npm install -g npm # update npm
Now you can install -g without sudo and everything goes into ~/.nvm/
Or install Node.js without nvm (official instructions):
Install Node.js
Node.js v6 (current LTS as of May 2017):
curl -sL https://deb.nodesource.com/setup_4.x | sudo -E bash -
sudo apt-get install -y nodejs
Node.js v7:
curl -sL https://deb.nodesource.com/setup_7.x | sudo -E bash -
sudo apt-get install -y nodejs
Change npm's default directory to a local one:
mkdir ~/.npm-global
npm config set prefix '~/.npm-global'
export PATH="$HOME/.npm-global/bin:$PATH" # ← put this line in .bashrc
source ~/.bashrc # if you only updated .bashrc
Alternatively replace .npm-global by the directory of your choice.
Update npm and check it is installed in your $HOME directory:
$ npm install npm -g
/home/<username>/.npm-global/bin/npm -> /home/<username>/.npm-global/lib/node_modules/npm/bin/npm-cli.js
/home/<username>/.npm-global/lib
└─┬ npm#3.10.6
├─┬ glob#7.0.5
│ └── minimatch#3.0.2
├── npm-user-validate#0.1.5
└── rimraf#2.5.3
Now you can install -g without sudo and without messing with your system files.
The solution posted by Just Jake is great. However, due to a bug with npm > 1.4.10, it may not work as expected. (See this and this)
While the bug is solved, you can downgrade to npm 1.4.10 by following this steps:
Comment the prefix line in your $HOME/.npmrc
Run sudo npm install -g npm#1.4.10
Ensure that the right version of npm is installed (npm --version)
Uncomment the prefix line in your $HOME/.npmrc
Proceed to install your global packages in your home folder!.
Because python does already a great job virtualenv, I use nodeenv. Compared to nvm, you can create multiple environments for the same node version (e.g. two environments for node 0.10 but with different sets of packages).
ENVNAME=dev1
# create an environment
python -m virtualenv ${ENVNAME}
# switch to the newly created env
source ${ENVNAME}/bin/activate
# install nodeenv
pip install nodeenv
# install system's node into virtualenv
nodeenv --node=system --python-virtualenv
The readme is pretty good:
https://github.com/ekalinin/nodeenv
I used #just-jake solution for some time and found that nvm is easier to setup.
Also it's much powerful solution that allows to install and use different versions of nodejs.
On Ubuntu 14.04 or 16.04:
Install prerequisite packages for building nodejs:
sudo apt-get update
sudo apt-get install build-essential libssl-dev
Install nvm:
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.31.1/install.sh | bash
In case newer version of nvm will be available you can find actual installation command on nvm site.
nvm installer will add bootstrap script to ~/.bashrc, so you need either to reopen terminal to run it, or to do:
source ~/.bashrc
Now you can install any nodejs version you like, switch between them etc.
Use nvm ls-remote to list available nodejs versions.
To install, for example, nodejs v4.2.4 do:
# install v4.2.4
nvm install v4.2.4
# use nodejs v4.2.4 in the current terminal session
nvm use v4.2.4
# use v4.2.4 by default in new terminal session
nvm alias default v4.2.4
As stated already here and here
npm config set prefix ~
echo export PATH=\$PATH:\~/bin >> ~/.bashrc
. ~/.bashrc
Other answers have outdated solutions: 2020's solution is using NPM_CONFIG_PREFIX environment variable. (See details)
For example,
$ NPM_CONFIG_PREFIX="$HOME/.npm-packages" npm install -g ios-sim
/Users/<name>/.npm-packages/bin/ios-sim -> /Users/<name>/.npm-packages/lib/node_modules/ios-sim/bin/ios-sim
+ ios-sim#9.0.0
added 108 packages from 68 contributors in 3.094s
To expand on the answer provided by Just Jake and user1533401: I am unable to downgrade as I use shared hosting and node is installed in a system directory. This is also why I have change the directory where npm installs global scripts if I want it to do that. For those in the same boat, here is a another temporary fix I found works:
npm install -g --prefix=$(npm config get prefix) <package>
The bug is that npm doesn't read your per-user config file, but specifying it every time you install a global script fixes that. Found here.
I have a slightly different solution to a similar problem, which was due to my installing npm globally so I can use it in the Terminal of my macOS system. I simply initialised it locally at the root directory of my repository with the command:
npm init --yes
This did the trick for enabling me to install node packages in the local root directory at /node_modules with the "package.json" and "package-lock.json" files instead of at the user's home directory.
You can use npm-user to automatically set up npm to install packages into your user's directories instead of the system's. No root privileges needed.
Here's a link to the script, instructions on how to use it and information about its options. It works on macOS, Linux, *BSD and Windows.
You can run it like so:
$ curl -s "https://raw.githubusercontent.com/alexdelorenzo/npm-user/main/npm-user.sh" | bash
After you run it, using npm install -g <package> will install packages to your user's directories without needing to use sudo.
Here's the code if you want to copy and paste it into your console:
#!/usr/bin/env bash
# Copyright 2022 Alex DeLorenzo <alexdelorenzo.dev>. Licensed under the GPLv3.
export ROOT="${1:-$HOME}"
export NPM_DIR=".npm-packages"
export NPM_ROOT="$ROOT/$NPM_DIR"
export NPM_BIN="$NPM_ROOT/bin"
export NPM_MAN="$NPM_ROOT/share/man"
export BASH_RC="$HOME/.bashrc"
export ZSH_RC="$HOME/.zshrc"
export DEFAULT_RC="$BASH_RC"
export RC_ERR=1
export INDENT=2
set -e
shopt -s expand_aliases
alias indent="paste /dev/null - | expand -$INDENT"
quiet() {
"$#" &> /dev/null
}
expand-tilde() {
local path="$1"
echo "${path/#\~/$HOME}"
}
create-paths() {
local bin="${1:-$NPM_BIN}"
local man="${2:-$NPM_MAN}"
mkdir --parents --verbose "$bin" "$man"
}
set-prefix() {
npm config set prefix "$NPM_ROOT"
}
get-vars() {
local bin="${1:-$NPM_BIN}"
local man="${2:-$NPM_MAN}"
cat <<EOF
export PATH="\$PATH:$bin"
export MANPATH="\${MANPATH:-\$(manpath)}:$man"
export NPM_PACKAGES="$NPM_ROOT"
EOF
}
already-added() {
local rc="${1:-$DEFAULT_RC}"
local bin="${2:-$NPM_BIN}"
local man="${2:-$NPM_MAN}"
local vars="$(get-vars "$bin" "$man")"
quiet grep "$vars" "$rc"
}
main() {
local rc="$(expand-tilde "${1:-$DEFAULT_RC}")"
local bin="$(expand-tilde "${2:-$NPM_BIN}")"
local man="$(expand-tilde "${3:-$NPM_MAN}")"
printf "Creating %s and %s\n" "$bin" "$man"
create-paths "$bin" "$man" || {
printf "Couldn't create paths: %s and %s.\n" "$bin" "$man"
return $RC_ERR
}
printf "Setting npm prefix.\n"
set-prefix || {
printf "Couldn't set prefix.\n"
return $RC_ERR
}
if ! already-added "$rc" "$bin" "$man"; then
printf "Writing to %s.\n" "$rc"
get-vars "$bin" "$man" >> "$rc"
fi || {
printf "Unable to write to %s.\n" "$rc"
printf "Add the following to your shell's configuration file:\n\n"
get-vars "$bin" "$man" | indent
return $RC_ERR
}
printf "Done.\n\n"
printf "To load the changes in this shell, run:\n"
printf "\tsource %s\n" "$rc"
}
main "$2" "$3" "$4"
At least on Ubuntu the default config for system wide npm is that npm install --global tries to install packages to /usr/lib/node_modules. To set different default for your own user account run following once:
mkdir -p ~/.npm/lib/bin
npm config set prefix "~/.npm/lib"
in addition you want following fragment in .profile:
# set PATH so it includes user's private .npm/lib/bin if it exists
if [ -d "$HOME/.npm/lib/bin" ] ; then
PATH="$HOME/.npm/lib/bin:$PATH"
fi
If you now install something with npm install --global packagename it will end up in correct location and can be found in your PATH (you may need to logout and re-login for .profile changes to take effect).
Of course, you could select some other directory instead. For example ~/.config/npm could make sense for modern systems.

Resources