Sling Academy
Home/Node.js/How to install NPM modules globally without ‘sudo’ (3 ways)

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

Last updated: January 28, 2024

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.

Next Article: Node.js: How to programmatically run Git commands

Previous Article: Node.js: How to get location from IP address (3 approaches)

Series: Node.js Intermediate Tutorials

Node.js

You May Also Like

  • NestJS: How to create cursor-based pagination (2 examples)
  • Cursor-Based Pagination in SequelizeJS: Practical Examples
  • MongooseJS: Cursor-Based Pagination Examples
  • Node.js: How to get location from IP address (3 approaches)
  • SequelizeJS: How to reset auto-increment ID after deleting records
  • SequelizeJS: Grouping Results by Multiple Columns
  • NestJS: Using Faker.js to populate database (for testing)
  • NodeJS: Search and download images by keyword from Unsplash API
  • NestJS: Generate N random users using Faker.js
  • Sequelize Upsert: How to insert or update a record in one query
  • NodeJS: Declaring types when using dotenv with TypeScript
  • Using ExpressJS and Multer with TypeScript
  • NodeJS: Link to static assets (JS, CSS) in Pug templates
  • NodeJS: How to use mixins in Pug templates
  • NodeJS: Displaying images and links in Pug templates
  • ExpressJS + Pug: How to use loops to render array data
  • ExpressJS: Using MORGAN to Log HTTP Requests
  • NodeJS: Using express-fileupload to simply upload files
  • ExpressJS: How to render JSON in Pug templates