Skip to main content

NPM (Node Package Manager)

One of Node.js’s greatest strengths is its ecosystem. Instead of writing everything from scratch, you can leverage hundreds of thousands of open-source packages built by developers worldwide. NPM (Node Package Manager) is the tool that makes this possible.

Why Package Management Matters

Imagine building a web application and needing to:
  • Parse JSON data
  • Make HTTP requests
  • Validate user input
  • Hash passwords
  • Connect to a database
You could write all this code yourself, but it would take months. Instead, you can install battle-tested packages that solve these problems in seconds. The Hardware Store Analogy: NPM is like a massive hardware store for code. You would not forge your own nails, mix your own paint, or smelt your own copper wire when building a house. You buy components that thousands of other builders have already tested. NPM works the same way—package.json is your shopping list, node_modules is your toolshed, and package-lock.json is the receipt that records the exact brand and model of everything you bought so your teammate gets the same parts.

The Node.js Ecosystem

This massive ecosystem means there’s likely a package for almost any problem you’re trying to solve.

How NPM Works

NPM serves three main purposes:
  1. Registry: A database of open-source packages anyone can publish to or download from
  2. CLI Tool: A command-line tool (installed with Node.js) to install and manage packages
  3. Website: npmjs.com for discovering and learning about packages
NPM comes bundled with Node.js—if you have Node installed, you already have NPM. Check with npm --version.

package.json

The package.json file is the manifest for your project. It keeps track of dependencies, scripts, version, and other metadata. To create one, run:

Installing Packages

Local Installation

Installs the package in the node_modules folder of your current project.
This adds lodash to the dependencies list in package.json.

Dev Dependencies

Packages only needed for development (e.g., testing tools, linters).

Global Installation

Installs the package globally on your system (usually for CLI tools).

Using Packages

Once installed, you can require them in your code.

NPM Scripts

You can define custom scripts in package.json.
Run them using:

Semantic Versioning (SemVer)

Versions are typically Major.Minor.Patch (e.g., 1.2.3).
  • ^1.2.3: Updates to latest minor/patch version (e.g., 1.3.0, 1.2.4) but not 2.0.0. This is the default when you npm install.
  • ~1.2.3: Updates to latest patch version (e.g., 1.2.4) but not 1.3.0. More conservative.
  • 1.2.3: Exact version. Most conservative—you get exactly this version, nothing else.
The caret (^) trap: Because ^ is the default, npm install express writes "express": "^4.18.2" in your package.json. This means next time someone runs npm install, they might get 4.19.0 or 4.21.3—a different version than yours. This is why package-lock.json exists: it pins the exact resolved versions. If you delete package-lock.json and reinstall, you may get different dependency versions that introduce subtle bugs. This is also why you should use npm ci (not npm install) in CI/CD pipelines—it installs exactly what the lockfile specifies and fails if there is a mismatch.

Summary

  • NPM is the package manager for Node.js
  • package.json tracks dependencies and scripts
  • Use npm install <package> to add dependencies
  • Use npm install -D <package> for dev dependencies
  • node_modules folder contains installed packages (never commit to Git—add it to .gitignore)

package-lock.json

The package-lock.json file locks exact versions of all dependencies:
Always commit package-lock.json to version control! It ensures consistent installs across all environments.

Essential NPM Commands

NPX - Execute Packages

npx runs packages without installing globally:

Workspaces (Monorepos)

NPM 7+ supports workspaces for managing multiple packages:

Creating Your Own Package