Skip to content

Node.js Package Manager (NPM)

npm (Node Package Manager) is the default and most popular package manager for Node.js. It’s a crucial tool for any Node.js developer, providing two main functionalities:

  • Online Registry: A vast public database (the npm Registry) hosting hundreds of thousands of open-source Node.js packages (libraries, modules, tools). You can search for packages on the npmjs.com website.
  • Command-Line Interface (CLI) Tool: A command-line utility (npm) used to install, manage, update, and publish Node.js packages, handle project dependencies, and run project scripts.

npm is bundled with Node.js installs, so when you install Node.js, you automatically get npm. You can verify your installed npm version by opening your terminal and running:

$ npm --version
9.5.0 # Your version might differ

npm is updated more frequently than Node.js itself. You can update npm to its latest version using npm itself:

# Use sudo on Linux/macOS if needed, or run from an Administrator prompt on Windows
$ npm install -g npm@latest

Every Node.js project should have a package.json file in its root directory. This JSON file contains metadata about the project, including:

  • Project name, version, description, author, license.
  • Dependencies: Packages required for the application to run.
  • DevDependencies: Packages needed only for development (e.g., testing libraries, build tools).
  • Scripts: Custom commands you can run using npm run <script-name> (e.g., npm start, npm test).
  • Main entry point file.
  • Repository information.

To create a package.json file, navigate to your project directory in the terminal and run:

$ npm init

This command will prompt you for various pieces of information (project name, version, etc.). You can accept the defaults by pressing Enter or provide your own values.

To quickly create a package.json file with default values without the interactive prompts, use:

$ npm init -y

To install a package and add it as a project dependency (saving it in package.json), use the npm install command (or its shorthand npm i):

# Installs the 'lodash' utility library
$ npm install lodash

This command does several things:

  • Downloads the lodash package from the npm registry.
  • Places it into a node_modules folder within your project directory. (If node_modules doesn’t exist, it’s created).
  • Adds lodash to the dependencies section of your package.json file.
  • Creates or updates a package-lock.json file.

This file is automatically generated or updated whenever you modify your node_modules tree or package.json. It records the exact versions of every package that was installed, including dependencies of dependencies. This ensures that anyone else who sets up the project using npm install gets the exact same dependency versions, leading to more consistent builds. You should commit package-lock.json to your version control system (like Git).

To install packages needed only for development (e.g., testing frameworks like Jest, build tools like Webpack), use the --save-dev flag (or -D):

# Installs 'jest' testing framework as a dev dependency
$ npm install --save-dev jest
# or shorthand
$ npm i -D jest

These packages are added to the devDependencies section in package.json and are typically skipped during production installations.

Once a module is installed locally, you can use it in your Node.js code using the require function (CommonJS modules) or import statement (ES Modules, if your project is configured for them):

// Using CommonJS
const _ = require('lodash');
const numbers = [1, 2, 3, 4, 5];
const sum = _.sum(numbers);
console.log(`Sum calculated by lodash: ${sum}`);

Local Installation (Default & Recommended): Packages installed without the -g flag are placed in the node_modules directory of your current project. They are accessible via require() or import within that specific project. This is the standard way to manage project dependencies.

Global Installation: Using the -g or --global flag installs packages at a system-wide location. These are typically command-line tools that you want to run from anywhere on your system (e.g., nodemon, create-react-app, npm itself). Global packages are not typically accessible via require() in your project code.

# Example: Install nodemon globally to auto-restart Node apps
$ npm install -g nodemon

To list globally installed packages:

$ npm list -g --depth=0 # depth=0 shows only top-level packages

To list locally installed packages for the current project:

$ npm list --depth=0

npm also includes a companion tool called npx. It allows you to run commands from npm packages without having to install them globally or explicitly reference their path in node_modules/.bin. npx will check if the command exists locally in node_modules/.bin, or globally, or it will download the package temporarily, run the command, and then discard the package.

# Run the 'create-react-app' tool without installing it globally
$ npx create-react-app my-new-react-app
# Run the locally installed 'jest' test runner
$ npx jest
  • npm uninstall <package-name>: Removes a package from node_modules and package.json/package-lock.json.
  • npm update: Updates packages to the latest versions allowed by the version ranges specified in package.json and updates package-lock.json.
  • npm update <package-name>: Updates a specific package.
  • npm outdated: Checks the registry to see which installed packages are outdated.
  • npm run <script-name>: Executes a script defined in the scripts section of package.json (e.g., npm run test, npm run build). Common scripts start and test can be run without the run keyword: npm start, npm test.
  • npm ci: (Clean Install) Installs dependencies exactly as specified in package-lock.json. It first deletes node_modules and is often faster and more reliable for automated builds/CI environments than npm install.
  • npm search <keyword>: Searches the npm registry for packages matching the keyword.
  • npm view <package-name>: Shows detailed information about a package from the registry (versions, dependencies, etc.).
  • npm login: Log in to your npm account (required for publishing).
  • npm publish: Publishes the package in the current directory to the npm registry (requires package.json and being logged in).

Understanding Semantic Versioning (SemVer)

Section titled “Understanding Semantic Versioning (SemVer)”

npm packages typically follow Semantic Versioning (MAJOR.MINOR.PATCH, e.g., 16.8.2).

  • MAJOR: Incremented for incompatible API changes.
  • MINOR: Incremented for adding functionality in a backward-compatible manner.
  • PATCH: Incremented for backward-compatible bug fixes.

In package.json, version ranges like ^16.8.2 (allows updates up to <17.0.0) or ~16.8.2 (allows updates up to <16.9.0) are common, controlling how npm update behaves.