How to install NPM modules globally without ‘sudo’ (3 ways)

Updated: January 28, 2024 By: Guest Contributor Post a comment

Introduction

Node Package Manager (NPM) is an essential tool for JavaScript developers as it serves as the default package manager for the JavaScript runtime environment Node.js. By default, installing global packages using NPM requires administrator privileges, which is why ‘sudo’ is commonly prefixed to the command on systems like macOS and Linux. However, using ‘sudo’ can pose security risks and cause permissions issues. In this tutorial, we’ll go through how to configure your system to install NPM modules globally without needing ‘sudo’.

Method 1: Changing the NPM Default Directory

One way to resolve this issue is by changing the directory where NPM stores global packages. You should select a directory you have ownership of, which will negate the need for ‘sudo’.

$ mkdir ~/.npm-global
$ npm config set prefix '~/.npm-global'

Now, you will need to add this directory to your PATH variable so that your system knows where to find the globally installed modules:

echo "export PATH=~/.npm-global/bin:$PATH" >> ~/.profile

Refresh your profile by running source ~/.profile, or open a new terminal session.

To test your new configuration, try installing a global package:

$ npm install -g jshint

You should now be able to run jshint without any permission issues.

Method 2: Using Node Version Manager (NVM)

Node Version Manager (NVM) allows you to install and manage multiple versions of Node.js without needing root privileges. When you install Node.js via NVM, any NPM global packages will be inside your user directory.

$ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
$ nvm install node
$ nvm use node

Now, install a module globally, and it should work without ‘sudo’:

$ npm install -g create-react-app

Your installation should complete without requiring elevated permissions.

Method 3: Using a Package Manager

Some package managers, such as Homebrew for macOS, allow you to install Node.js in a way that avoids ‘sudo’ for global packages.

$ brew install node

After installation, try installing a global NPM package:

$ npm install -g typescript

You should see that it installs globally with your user permissions.

Advanced Configuration

For those who need a more advanced configuration, like setting up multiple paths for global packages or integrating with Docker containers, you will need to modify both ‘.npmrc’ and PATH variables appropriately.

Multiple Global Paths

If you need multiple directories for global packages due to different projects or Node versions, you need to set multiple prefixes and adjust your PATH accordingly.

$ npm config set prefix '~/npm-packages-for-project1'
$ echo "export PATH=~/npm-packages-for-project1/bin:$PATH" >> ~/.project1_profile

Then source the specific profile when you work on that project:

$ source ~/.project1_profile

Integration with Docker Containers

When working with Docker, you can build images that already have the necessary folders and PATH settings to handle global NPM installations without ‘sudo’:

FROM node:latest
ENV NPM_CONFIG_PREFIX=/home/node/.npm-global
ENV PATH=$PATH:/home/node/.npm-global/bin
USER node

This Dockerfile sets up a non-root ‘node’ user with custom NPM settings that do not require ‘sudo’.

Conclusion

In conclusion, managing NPM global packages without ‘sudo’ enhances both security and convenience. The methods described here provide a reliable approach to achieve this, whether you’re configuring for a local development environment or a Docker container. Opt for the solution that best fits your workflow and enjoy seamless JavaScript package management.