How to Install Packages from npm: A Complete Guide

npm (Node Package Manager) is the default package manager for Node.js and one of the largest software registries in the world. Whether you're pulling in a utility library, a framework, or a build tool, understanding how npm installation works — and what affects it — will save you hours of debugging and configuration headaches.

What npm Actually Does When You Install a Package

When you run an npm install command, npm does several things at once. It contacts the npm registry (or a configured private registry), resolves the dependency tree for the package you requested, downloads the package and all its dependencies, and places everything inside a node_modules folder in your project directory.

It also reads and writes to two important files:

  • package.json — lists your project's direct dependencies and metadata
  • package-lock.json — locks the exact versions of every installed package, including nested dependencies

These files matter because they're what allow someone else to clone your project and reproduce the exact same environment.

Prerequisites Before You Install Anything

You need Node.js installed on your machine before npm is available. npm ships bundled with Node.js, so installing Node gives you both. You can verify both are present by running:

node -v npm -v 

If either command returns a "not found" error, you'll need to install Node.js first from the official Node.js website. Most developers use either the LTS (Long Term Support) version for stability or the Current version for the latest features.

The Core Installation Commands

Installing a package locally (most common)

npm install package-name 

This installs the package into the node_modules folder of your current project directory. It also adds the package to the dependencies section of your package.json. Local installs are the standard approach for anything your project actually uses.

Installing as a dev dependency

npm install package-name --save-dev 

Use this flag for tools that only run during development — test runners, linters, bundlers, TypeScript compilers. These go into devDependencies in your package.json and won't be included in a production build in most setups.

Installing a package globally 🌍

npm install -g package-name 

A global install places the package in a system-wide location, making it available as a command-line tool from any directory. This is typical for CLIs like create-react-app, nodemon, or eslint when you want to use them outside of a specific project.

Installing all dependencies from an existing project

npm install 

Running this command with no arguments reads your package.json and installs everything listed under both dependencies and devDependencies. This is the first command most developers run after cloning a project.

Version Control: Installing Specific Versions

npm gives you precise control over which version of a package you install:

SyntaxWhat It Installs
npm install pkg@latestMost recent published version
npm install [email protected]Exact version 2.3.1
npm install pkg@^2.0.0Latest minor/patch in the 2.x range
npm install pkg@~2.3.0Latest patch in the 2.3.x range

Semantic versioning (semver) is the system behind these flags. Understanding the difference between ^ (caret) and ~ (tilde) matters when you need stability — caret allows minor updates, tilde restricts to patch updates only.

What Affects How npm Install Behaves

Several variables change what actually happens during installation:

Your Node.js version — some packages have peer dependency requirements tied to specific Node versions. Installing a package designed for Node 18 on Node 14 can trigger warnings or failures.

Your operating system — packages with native bindings (compiled C/C++ code) behave differently on Windows, macOS, and Linux. Some require build tools like python or make to compile on install.

Network and registry configuration — corporate environments often route npm through a private registry or proxy. If npm install hangs or throws authentication errors, the issue may be registry configuration rather than the package itself.

The package-lock.json presence — when a lockfile exists, npm installs the exact versions it specifies. Without one, npm resolves versions fresh from the registry, which can produce different results across machines.

npm version itself — behavior around peer dependencies changed significantly between npm v6, v7, and later versions. npm v7+ automatically installs peer dependencies by default; earlier versions do not.

Local vs. Global: The Practical Difference

Most package-related problems stem from confusion between local and global installs. A globally installed package isn't automatically available inside your project's code — it's only accessible as a CLI tool. If you try to require() or import a package that was installed globally rather than locally, Node.js won't find it.

The general best practice is: install locally by default, globally only for standalone CLI tools you use across many projects.

🔧 When Things Go Wrong

Common install failures usually come down to a few categories:

  • Permission errors on macOS/Linux — often triggered by incorrect npm ownership on the global directory; solvable without using sudo by configuring npm's prefix path
  • Peer dependency conflicts — more common after npm v7; the --legacy-peer-deps flag can bypass strict checks when needed
  • Corrupted node_modules — deleting the node_modules folder and package-lock.json, then running npm install fresh, resolves many mysterious errors

The Variables That Shape Your Experience

Whether a straightforward npm install works cleanly or requires troubleshooting depends on the intersection of your Node.js version, your OS, the package's native dependencies, your registry configuration, and your existing lockfile state. A setup that works without friction on one machine may behave differently on another — not because either is wrong, but because those variables interact differently.

Understanding which of these factors apply to your environment is the starting point for diagnosing anything that doesn't install as expected.