Quick answer
npm (Node Package Manager) is a package manager for JavaScript that manages all the libraries and tools your React app needs. When you install React with npm install, you’re using npm to download React from a global repository, save it to your project, and track what version you’re using in package.json.
In simple terms: npm lets you download, install, update, and manage code packages so you don’t have to build everything from scratch.
What is npm?
npm is the default package manager for Node.js — it comes installed automatically when you install Node.js. It solves one critical problem: managing external code dependencies.
Imagine building a React app without npm. You’d need to:
- Manually download React from GitHub
- Copy the files into your project
- Download React DOM separately
- Download Axios (for API calls), React Router (for navigation), Bootstrap (for styling)
- Track which versions of each you’re using
- Keep track of which packages depend on other packages
- Manually update everything quarterly
That would take hours. npm does all of this in seconds.
npm is 100% essential to modern React development. You cannot build a React app without it.
Why React needs npm
1. Dependency Management
React apps use dozens of packages. Your app might depend on:
react(the core library)react-dom(renders React to the browser)react-router(navigation between pages)axios(making HTTP requests)styled-components(styling)- Testing libraries, linting tools, bundlers, etc.
Each of these packages depends on other packages. npm automatically handles the entire dependency tree — it downloads not just React, but everything React needs to function.
2. Version Control
npm tracks the exact version of each package your project uses via package.json. If you download React 19.0.0 today and your teammate installs your project next month, they get React 19.0.0 — not the latest version (which might break your code).
3. Reproducible Environments
npm creates a package-lock.json file that locks every single version and dependency. This ensures your project runs identically on your machine, your teammate’s machine, your production server, and Docker containers.
4. Security & Updates
npm monitors your installed packages for security vulnerabilities. Run npm audit to see if any package has a known security issue, then npm audit fix to patch it automatically.
How npm works in a React project
The package.json file (your project blueprint)
When you create a React project with Vite, npm generates a package.json file. This is the configuration file that tells npm what your project needs.
Here’s a real example from a Vite React project:
{
"name": "my-react-app",
"version": "1.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"react": "^19.0.0",
"react-dom": "^19.0.0"
},
"devDependencies": {
"@vitejs/plugin-react": "^4.2.0",
"vite": "^5.1.0"
}
}
Let’s break this down:
name— Your project name (appears when you publish to npm)version— Your project version (important for releases)type: "module"— Tells npm to use ES modules (modern JavaScript)scripts— Commands you run withnpm.npm run dev→ runs the dev serverdependencies— Packages your app needs to run (React, React DOM)devDependencies— Packages only needed during development (Vite, linters, test runners)
Understanding version numbers: Semantic Versioning
That ^ symbol in "react": "^19.0.0" is important. It’s called semantic versioning:
^19.0.0
^^^ patch
^ minor
^ major
- Major version (19) — Breaking changes. Don’t auto-update.
- Minor version (0) — New features, backward compatible.
^allows updates here. - Patch version (0) — Bug fixes only. Always update.
Version specifiers:
"react": "19.0.0"— Exact version, never update"react": "^19.0.0"— Allow minor + patch updates (19.1.0, 19.2.5, but not 20.0.0)"react": "~19.0.0"— Allow only patch updates (19.0.1, 19.0.5, but not 19.1.0)"react": "*"— Any version (not recommended, breaks things)
npm commands you’ll use every day
npm install (or npm i)
Downloads all packages listed in package.json and saves them to a node_modules/ folder:
npm install
Run this when you clone a project or create a new one. You’ll see output like:
added 245 packages in 12s
npm install package-name
Adds a new package to your project and updates package.json:
npm install axios
This downloads Axios (for HTTP requests) and adds it to your dependencies.
Shortcut: npm i axios
npm install –save-dev (or -D)
Installs a package only for development (not in production):
npm install --save-dev typescript
Use this for testing libraries, linters, and bundlers that aren’t needed when the app runs.
Shortcut: npm i -D typescript
npm update
Updates all packages to their latest compatible versions:
npm update
Respects your version constraints. If you have ^19.0.0, it updates to the latest 19.x.x, not 20.0.0.
npm list
Shows all installed packages and their versions:
npm list
Output shows a tree of packages:
my-react-app@1.0.0
├── react@19.0.0
├── react-dom@19.0.0
└── @vitejs/plugin-react@4.2.0
npm audit
Checks for security vulnerabilities in your packages:
npm audit
Shows critical, high, moderate, and low severity issues. Then:
npm audit fix
Automatically patches vulnerable packages.
npm run script-name
Runs a script defined in package.json:
npm run dev
This runs the Vite dev server (defined in scripts.dev).
Other common scripts:
npm run build— Create a production-ready buildnpm run preview— Preview the production build locallynpm test— Run testsnpm run lint— Check code for errors
package.json: A real-world example
Here’s a more complete example of a React app using multiple packages:
{
"name": "ecommerce-app",
"version": "2.1.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview",
"test": "vitest",
"lint": "eslint src/"
},
"dependencies": {
"react": "^19.0.0",
"react-dom": "^19.0.0",
"react-router-dom": "^6.20.0",
"axios": "^1.6.0",
"zustand": "^4.4.0"
},
"devDependencies": {
"@vitejs/plugin-react": "^4.2.0",
"vite": "^5.1.0",
"vitest": "^1.0.0",
"eslint": "^8.55.0",
"@testing-library/react": "^14.1.0"
}
}
What’s happening here:
- Runtime dependencies: React, React Router (for pages), Axios (for API calls), Zustand (for state management)
- Dev dependencies: Vite (build tool), Vitest (testing), ESLint (code quality), Testing Library (test utilities)
When you run npm install, all of these download automatically.
npm vs. Yarn vs. pnpm: Which one to use?
Three package managers dominate the JavaScript ecosystem. Here’s how they compare:
| Feature | npm | Yarn | pnpm |
|---|---|---|---|
| Built into Node.js | ✓ (since v0.6) | ✗ (install separately) | ✗ (install separately) |
| Speed | Fast (especially v7+) | Very fast | Fastest (optimized disk usage) |
| Disk space | Higher (dupes packages) | Medium | Lowest (links, no dupes) |
| Installation time | ~3–5s | ~2–4s | ~1–2s |
| Backward compatible | ✓ (npm 7+) | Mostly | Mostly |
| Learning curve | Easiest | Moderate | Moderate |
| Market share | ~86% of projects | ~10% | ~4% |
| Lock file format | package-lock.json | yarn.lock | pnpm-lock.yaml |
| Monorepo support | Good | Excellent | Excellent |
For beginners: Use npm. It comes with Node.js, has the most tutorials, and is what the React + VS Code setup guide uses.
For large teams: Consider pnpm if disk space matters or Yarn if you need advanced monorepo features.
Common npm workflow in React development
Here’s how a typical day using npm looks:
Morning: Clone a project
git clone https://github.com/yourteam/react-app.git
cd react-app
npm install # Download all dependencies
npm run dev # Start dev server
Mid-morning: Add a new package
You need a date formatting library. Install it:
npm install date-fns
This adds date-fns to your package.json and downloads it to node_modules/.
Afternoon: Update packages
Quarterly security updates. Check for vulnerabilities:
npm audit # See vulnerabilities
npm audit fix # Auto-patch low/moderate issues
Evening: Ship a release
Build the production version:
npm run build # Creates optimized bundle in dist/
npm version patch # Bumps version in package.json
git push # Deploy
Dependency management best practices
1. Keep dependencies updated (but don’t break things)
Don’t let packages get stale — security issues pile up. But test before updating:
npm update # Updates to latest compatible versions
npm run test # Run your tests
If tests break, revert and debug before updating further.
2. Minimize dependencies
Every dependency is a maintenance burden. Before adding a package, ask:
- Does the standard library already do this?
- Is this package actively maintained?
- Is it bloating my bundle?
Use npm list to audit what you actually have.
3. Use lock files (you don’t have to do anything)
Your package-lock.json ensures reproducible installs. Commit it to Git.
This file guarantees that running npm install on Day 1 and Day 365 downloads identical versions.
4. Know the difference: dependencies vs devDependencies
- dependencies — Code your app needs to run (React, Axios)
- devDependencies — Code only for development (testing tools, linters, Vite)
When you deploy to production, devDependencies are excluded. So your production bundle is smaller and faster.
5. Use npm audit regularly
npm audit # Check for vulnerabilities
npm audit fix # Auto-patch what you can
npm audit fix --force # Force major updates (risky)
Make this part of your monthly routine.
Troubleshooting npm issues
“npm: command not found”
Node.js isn’t installed or PATH isn’t set. Fix:
node -v # Check if Node is installed
# If not: install from nodejs.org
# If yes: restart your terminal
“ERR! 404 Not Found — GET https://registry.npmjs.org/…”
The package name is misspelled or doesn’t exist. Check:
npm search package-name # Search npm registry
npm info package-name # Get package details
“npm ERR! code ERESOLVE unable to resolve dependency tree”
Two packages need incompatible versions of a shared dependency. Try:
npm install --force # Force the installation (risky)
# Or remove conflicting packages and reinstall one at a time
node_modules is huge and slowing me down
Delete it and reinstall:
rm -rf node_modules package-lock.json # Delete
npm install # Reinstall
FAQ
Q: Do I need to commit node_modules to Git?
A: No. Commit package.json and package-lock.json — they’re tiny. Anyone who clones your repo runs npm install to download node_modules. This keeps your repo lean and allows teammates to use different OS versions (node_modules contains OS-specific binaries).
Q: What’s the difference between npm install and npm ci?
A: npm install can update versions (respecting semver). npm ci (“clean install”) installs exact versions from package-lock.json. Use npm ci in CI/CD pipelines and Docker to guarantee reproducibility.
Q: Can I use npm in production?
A: npm itself isn’t used in production. You use npm run build to create an optimized bundle, then deploy that bundle. The production server runs the built code, not npm.
Q: What’s node_modules? Can I delete it?
A: node_modules contains all your installed packages and their dependencies. Yes, delete it anytime — npm install recreates it from package.json. It’s safe to .gitignore.
Q: How do I uninstall a package?
A: npm uninstall package-name removes it and updates package.json. Shortcut: npm un package-name.
Q: What’s npm cache and how do I clear it?
A: npm downloads packages to a cache so future installs are faster. To clear: npm cache clean --force. Rarely needed, but helpful if installations are failing mysteriously.
Q: Can I use npm with non-React projects?
A: Yes. npm works with any Node.js project — Express servers, Vue apps, Next.js, vanilla JavaScript projects, command-line tools, etc. It’s not React-specific.
Q: Why is package-lock.json so large?
A: It locks every version of every dependency (including nested ones). With React, that’s 300+ packages. It’s safe to commit — it’s text and compresses well in Git.
Next steps
You now understand what npm is and how it manages your React dependencies.
Ready to start building? Go back to the React + VS Code setup guide where you’ll use npm to create a Vite project. Then install React Developer Tools to debug your first component.
Next on your learning path:
- Complete React + Vite setup (uses npm in steps 2–3)
- React Developer Tools installation (for debugging)
- Create your first routes (install with npm)
Every React feature you build will rely on npm to manage packages. Mastering npm now will save you hours of debugging and frustration later.
Last updated: January 2026. Information current as of npm 10, Node 20 LTS, React 19.