Understanding Local and Global npm Packages

Lewistech
4 min readJul 6, 2023

--

In this article, we will explore the concepts of local and global npm packages, highlighting their differences, installation locations, and when it is appropriate to install a package locally versus globally.

Creating a JavaScript Project
To provide practical examples of local and global packages using npm, let’s create an npm package by following these steps:

1. Create a directory named “local-global.”
2. Navigate to the “local-global” directory using the command line.
3. Run the command “npm init -y” to initialize a package.json file with default project information.

The “npm init -y” command generates a package.json file that includes a list of our local installations.

npm Local Packages
In the npm ecosystem, a local package refers to a package that is installed using the command “npm install <package_name>.” Local packages are only accessible within the project in which they are installed. For instance, let’s install the “express” package locally:

npm install express

When a package is installed locally, it is listed under the “dependencies” or “devDependencies” section in the package.json file. Look for the following structure inside the package.json file:

“dependencies”: {
“express”: “⁴.18.1”
}

Hence, the “express” package is only available within the current project since it was installed locally. If we were to create another npm project called “local-global-2” and try to require “express,” we would encounter a “module not found” error. Additionally, we can install packages locally as devDependencies by appending “ — save-dev” to the “npm install” command. Let’s do this with “ESLint”:

npm install eslint — save-dev

Now, if we examine the package.json file, “ESLint” should be listed under the “devDependencies” section:

“devDependencies”: {
“eslint”: “⁸.17.0”
}

Packages listed as devDependencies are essential for the development process but not required in the production environment.

Location of Local Packages
When packages are installed locally, they are stored in the “node_modules” folder. The current project structure should resemble the following:

local-global
|
| — node_modules
| — package.json
| — package-lock.json

The “node_modules” folder serves as a repository for locally installed packages. Whenever a package is installed locally using npm, it gets copied into the “node_modules” folder. When a specific package is required, Node.js searches for it within the “node_modules” directory. For example, if we create an “index.js” file and require “express,” Node.js will look inside the “node_modules” folder:

// Node.js searches for “express” inside the node_modules folder
const express = require(‘express’);

The contents of the “node_modules” folder change whenever there are changes to the dependencies in the package.json file and the “npm install” command is executed. It’s worth noting that if we explore the “node_modules” folder, we will find many more packages besides “express” and “eslint.” This is because, since npm version 3, project dependencies and sub-dependencies are installed at the top level. Sub-dependencies are only installed at deeper levels when conflicts arise.

Global Packages
Global packages, as the name implies, are installed in a single location on the system. They can be installed using the “-g” flag with the “npm install” command. Let’s install the “nodemon” package globally as an example:

npm install nodemon -g

Location of Global Packages
To determine the installation location of Global Packages, we can use the command “npm root -g”:

npm root -g

The “npm root” command displays the effective “node_modules” folder to the console. By adding the “-g” flag, it shows the location of the global “node_modules” directory. The output of this command may vary depending on the operating system and the method of Node.js installation. For example, if “nvm” is listed in the path, it indicates that Node.js was likely installed through “nvm.” An example output could be:

/home/wittcode/.nvm/versions/node/v14.15.3/lib/node_modules

Listing Global Packages
To view the global packages installed on a system, we can use the command “npm list -g — depth 0”:

npm ls -g — depth 0

The “npm ls” command lists all the installed packages. Adding the “-g” flag restricts the list to global packages, and “ — depth 0” specifies that only the top-level packages should be displayed without any sub-dependencies. The output should be similar to the following:

/home/wittcode/.nvm/versions/node/v14.15.3/lib
├── node-gyp@9.0.0
├── nodemon@2.0.15
└── npm@6.14.9

Installing Packages Locally or Globally?
As a general guideline, it is recommended to install packages locally. This approach allows for different project dependencies to use different package versions. If multiple projects rely on a global package and that package is updated, it could potentially introduce breaking changes across those projects.

When to Install Packages Globally?
However, there are scenarios where installing a package globally is appropriate. Global installation is suitable when a package includes an executable that is intended to be run from the command line interface (CLI) and is shared across multiple projects. For instance, a commonly installed global package is “nodemon,” a tool that automatically restarts a Node.js application after file changes.

In conclusion, understanding the ability to install npm packages locally and globally is extremely beneficial. Installing packages locally provides flexibility in managing different versions across projects, while global installation is useful for tools and utilities shared across multiple projects. If you found this article helpful, consider donating by using the link at the top of the page and sharing it with others.

--

--