How to Install Packages with npm: A Complete Guide
npm (Node Package Manager) is the default package manager for Node.js and one of the most widely used tools in modern web development. Whether you're adding a utility library, a front-end framework, or a build tool to your project, npm handles the installation and dependency management automatically. Here's everything you need to understand about how npm installation works — and what affects the outcome on your specific setup.
What npm Actually Does When You Install Something
When you run an npm install command, npm does several things at once:
- Resolves dependencies — it reads what you've requested, then traces all the packages that package depends on
- Fetches packages from the npm registry (registry.npmjs.org by default)
- Writes files into a
node_modulesfolder in your project directory - Updates
package.jsonandpackage-lock.jsonto record what was installed
The package-lock.json file is particularly important — it locks dependency versions so every developer on a team installs the exact same code.
Prerequisites Before You Install Anything
Before any npm command works, you need Node.js installed on your machine. npm ships bundled with Node.js, so installing Node automatically gives you npm.
You can verify both are available by running:
node --version npm --version If either command returns an error, Node.js isn't installed or isn't on your system's PATH. Operating system matters here — installation steps differ between Windows, macOS, and Linux, and some Linux distributions require manual PATH configuration after installation.
The Core npm Install Commands
Installing a Package into a Project
npm install package-name This installs the package locally — meaning it's added to the node_modules folder inside your current project directory and recorded under "dependencies" in your package.json.
Installing as a Development Dependency
npm install package-name --save-dev Use this for tools only needed during development — test runners, linters, bundlers, and transpilers. These get recorded under "devDependencies" and won't be included in production builds (depending on your build configuration).
Installing Globally
npm install -g package-name Global installs make a package available as a command-line tool across your entire system — not tied to any single project. CLI tools like create-react-app, nodemon, or typescript are often installed globally. 🌐
Installing All Project Dependencies at Once
npm install Run this inside a project folder that already has a package.json. npm reads that file and installs everything listed under both dependencies and devDependencies. This is the standard step after cloning a repository.
Installing a Specific Version
npm install [email protected] Version pinning matters when you need to match an existing team setup, avoid a known bug in a newer release, or maintain compatibility with other dependencies.
Key Flags and Options Worth Understanding
| Flag | What It Does |
|---|---|
--save-dev / -D | Saves as a dev dependency |
--global / -g | Installs system-wide, not project-scoped |
--save-exact / -E | Pins the exact version with no version range |
--legacy-peer-deps | Bypasses peer dependency conflicts (older behavior) |
--omit=dev | Skips dev dependencies (useful for production environments) |
What Can Go Wrong — and Why
npm installation failures are common and usually fall into a few categories:
Permission errors occur most often with global installs on macOS and Linux. Running npm install -g without the right permissions triggers an EACCES error. The fix depends on your system — some developers adjust npm's default directory, others use a version manager like nvm (Node Version Manager) to avoid needing elevated permissions entirely.
Peer dependency conflicts happen when two packages in your project require incompatible versions of a shared dependency. npm v7 and later treats peer dependency conflicts as hard errors by default, where earlier versions only issued warnings. The --legacy-peer-deps flag restores the older, more permissive behavior.
Network and proxy issues appear in corporate or restricted environments where outbound traffic to the npm registry is blocked or routed through a proxy. npm's configuration supports proxy settings via npm config set.
Corrupted node_modules sometimes cause cascading errors. Deleting the node_modules folder and package-lock.json, then running npm install fresh, resolves a large percentage of unexplained install failures.
Local vs. Global: Choosing the Right Scope 🔧
The local vs. global distinction trips up many developers new to npm. A useful mental model:
- Local installs are for packages your code imports — React, Lodash, Express
- Global installs are for tools you run — CLI utilities you invoke from the terminal
Installing a library globally and trying to import it inside a project typically doesn't work as expected, because Node.js resolves require() and import statements from the local node_modules folder, not the global directory.
How npm Version and Node Version Interact
Different versions of npm behave differently. npm v5 introduced package-lock.json. npm v7 changed how peer dependencies are handled. npm v9 and later made additional changes to the install algorithm and configuration defaults.
The Node.js version you're running determines which npm version ships with it, and some packages declare a minimum Node.js version they support. If you maintain multiple projects with different Node.js requirements, a version manager like nvm (macOS/Linux) or nvm-windows makes switching between Node versions straightforward.
The Variables That Shape Your Experience
How smooth or complicated npm installation feels depends on several overlapping factors:
- Your operating system and how Node.js was originally installed
- npm version — behaviors around peer dependencies, lockfiles, and permissions shifted across major releases
- The package itself — some packages include native C++ bindings that require build tools (
node-gyp, Python, Visual Studio Build Tools on Windows) - Your network environment — open internet vs. proxied corporate network vs. private registry
- Project age — older projects may pin to older package versions that conflict with newer dependencies
A straightforward npm install react in a fresh project on a modern setup takes seconds. The same command inside a three-year-old project with dozens of interdependent packages and a specific Node version requirement is a different experience entirely — and what works cleanly in one setup may require flags, workarounds, or tooling changes in another.