Chapter 16: Node NPM
1. What is npm really? (The honest explanation)
npm = Node Package Manager
It is two things at the same time:
- A huge online registry → the biggest collection of open-source JavaScript packages in the world → currently (2026) > 2.5 million packages → you can find almost anything: express, lodash, axios, prisma, zod, dotenv, jest, typescript, etc.
- A command-line tool → installed together with Node.js → used to download, install, manage, publish, and run scripts related to those packages
So when people say “npm install express”, they mean:
“Please go to the npm registry, download the express package and its dependencies, and put them in my project so I can use them.”
2. How npm is connected to your project
Every Node.js project usually has three important npm-related files/folders:
| File / Folder | What it is | Created by whom? | Very important? |
|---|---|---|---|
| package.json | The identity card of your project | You (npm init) | ★★★★★ |
| package-lock.json | The exact version lockfile | npm (automatically) | ★★★★★ |
| node_modules/ | The folder where all downloaded packages live | npm install | ★★★★☆ |
package.json — the heart of everything
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
{ "name": "my-cool-api", "version": "1.0.0", "description": "My first real Node.js API", "main": "src/index.js", "type": "module", "scripts": { "start": "node src/index.js", "dev": "nodemon src/index.js", "test": "jest", "lint": "eslint .", "format": "prettier --write ." }, "dependencies": { "express": "^4.19.2", "dotenv": "^16.4.5", "zod": "^3.23.0", "prisma": "^5.20.0" }, "devDependencies": { "nodemon": "^3.1.7", "eslint": "^9.9.0", "prettier": "^3.3.3", "jest": "^29.7.0" }, "engines": { "node": ">=20.0.0" } } |
Very important fields explained:
| Field | Meaning | You should always… |
|---|---|---|
| name | Unique name of your project / package | Choose carefully (no uppercase usually) |
| version | Semantic version (semver) | Follow semver rules |
| type | “module” = use ESM, “commonjs” = use require | Set to “module” for new projects |
| scripts | Custom commands you can run with npm run <name> | Add dev, start, test, lint… |
| dependencies | Packages your app needs to run in production | Only runtime packages |
| devDependencies | Packages only needed during development / testing | Tools, linters, testers |
| engines | Which Node.js versions are supported | Good practice for teams |
3. Most important npm commands (real-world usage)
| Command | What it does | When you use it |
|---|---|---|
| npm init | Creates package.json (interactive) | First time in new project |
| npm init -y | Creates package.json with default values (very common) | Quick start |
| npm install | Installs all dependencies from package.json | After git clone, or when package.json changed |
| npm install express | Installs express + saves it to dependencies | Adding runtime dependency |
| npm install nodemon –save-dev | Installs nodemon only for development | Adding dev tool |
| npm install –save-dev or -D | Short way to install as devDependency | Very common |
| npm run dev | Runs the script called “dev” from package.json | Your daily development command |
| npm start | Special shortcut — runs “start” script | Production / simple start |
| npm update | Updates packages to latest compatible versions | Rarely used |
| npm outdated | Shows which packages are outdated | Before updating |
| npm uninstall lodash | Removes lodash from project | Cleaning up |
| npm ci | Clean install from package-lock.json (CI/CD favorite) | In GitHub Actions, Docker, pipelines |
| npm cache clean –force | Clears npm cache when you have strange errors | When npm behaves crazy |
4. Real example – creating a small project from scratch
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
# 1. Create project folder mkdir my-first-npm-project cd my-first-npm-project # 2. Initialize npm init -y # 3. Install runtime dependencies npm install express dotenv # 4. Install development dependencies npm install --save-dev nodemon # 5. Update package.json scripts # (you can do this manually or with editor) |
package.json now looks something like:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
{ "name": "my-first-npm-project", "version": "1.0.0", "type": "module", "scripts": { "start": "node index.js", "dev": "nodemon index.js" }, "dependencies": { "dotenv": "^16.4.5", "express": "^4.19.2" }, "devDependencies": { "nodemon": "^3.1.7" } } |
index.js
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
import express from 'express'; import dotenv from 'dotenv'; dotenv.config(); const app = express(); app.get('/', (req, res) => { res.json({ message: "Hello from npm-powered project!", environment: process.env.NODE_ENV || 'development' }); }); const PORT = process.env.PORT || 4000; app.listen(PORT, () => { console.log(`Server running → http://localhost:${PORT}`); }); |
Run:
|
0 1 2 3 4 5 6 |
npm run dev |
5. Understanding package-lock.json vs yarn.lock vs pnpm-lock.yaml
| File | Tool | What it does | Why it’s important |
|---|---|---|---|
| package-lock.json | npm | Locks exact versions of every dependency | Prevents “works on my machine” problems |
| yarn.lock | Yarn | Same idea, different format | Used if you use Yarn |
| pnpm-lock.yaml | pnpm | Very efficient (hard links) | Used with pnpm |
Best practice 2026:
- Commit package-lock.json to git (yes — always!)
- Use npm ci instead of npm install in CI/CD pipelines
- Never commit node_modules/
6. Common patterns & tips used by professionals
- Use npm run <script> instead of node directly
- Prefer npm run dev over nodemon directly
- Add .npmrc file for private registries or settings
- Use npx for one-time commands Example: npx create-vite@latest
- Understand semver: ^4.19.2 → allows 4.x updates ~4.19.2 → allows patch updates only 4.19.2 → exact version
- Run npm audit regularly (security check)
Summary – Quick cheat sheet
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# New project npm init -y npm install express dotenv npm install --save-dev nodemon # Daily commands npm run dev npm start npm test # Add / remove npm install zod npm install prettier --save-dev npm uninstall lodash # Clean & safe install npm ci npm cache clean --force |
Which part would you like to explore deeper next?
- Understanding semantic versioning (semver) in detail
- How package-lock.json really works
- Difference between npm, yarn, pnpm, bun
- Publishing your own package to npm
- Using private registries or GitHub Packages
- Common npm errors and how to fix them
Just tell me what interests you most — I’ll continue with concrete examples and explanations. 😄
