package.json anatomy, semantic versioning, package-lock.json, npm scripts, and the essential dev tools every Node.js engineer installs first.
Module F-5 — npm and the Node.js Ecosystem
What this module covers: npm is the package manager for Node.js — but it is also the command-line tool you use to run scripts, manage dependencies, and maintain your project. Understanding
package.json, semantic versioning, the lock file, and the npm CLI is not optional. Every Node.js project uses these. This module also covers the essential packages every engineer installs on day one and the most common mistakes that cost hours to debug.
What npm Is
npm stands for Node Package Manager. It ships with Node.js — when you install Node, you get npm automatically. It does three things:
- Registry: A central database of over two million open-source JavaScript packages at npmjs.com
- CLI: The
npmcommand you run to install, update, and remove packages - Package format: The conventions (
package.json,node_modules, lock files) that define a Node.js project
When you run npm install express, npm downloads the Express package and its dependencies from the registry into your project's node_modules folder.
package.json
Every Node.js project has a package.json at its root. It is the project's manifest — its name, version, dependencies, scripts, and configuration. Create one:
A typical package.json:
Key fields:
"name"— must be lowercase, no spaces. Used as the package name if you publish to npm."version"— follows semantic versioning (covered shortly)."main"— the entry point when someonerequires your package. For apps, this is your server entry file."type": "module"— makes all.jsfiles use ES Modules. Omit for CommonJS."scripts"— shortcuts for commands.npm run devruns whatever is under"dev"."dependencies"— packages required to run in production."devDependencies"— packages only needed during development (testing, linting, build tools)."engines"— declares the minimum Node.js version your project requires.
dependencies vs devDependencies
When you deploy to production, you can run npm install --omit=dev to skip devDependencies — keeping the production image smaller.
Semantic Versioning
Every npm package uses semantic versioning (semver): MAJOR.MINOR.PATCH.
| Part | When it changes | Example |
|---|---|---|
MAJOR | Breaking change — your code may need updating | 4.0.0 → 5.0.0 |
MINOR | New features, backwards compatible | 4.18.0 → 4.19.0 |
PATCH | Bug fixes, backwards compatible | 4.18.2 → 4.18.3 |
In package.json, version ranges control which updates you accept automatically:
^ (caret) is the default when you npm install express. It allows 4.19.0, 4.18.3, but not 5.0.0.
The practical rule: use ^ for most packages. Pin to an exact version only if the package is known to have breaking changes in minor versions (rare but it happens).
package-lock.json
The lock file records the exact version of every package — and every package's dependencies — that was installed. This is critical.
The problem it solves: package.json says "express": "^4.18.2". On Monday you install and get 4.18.2. On Tuesday a colleague installs and gets 4.19.0 (just released). Your environments are different. The lock file ensures everyone gets exactly the same versions.
Key rule: npm ci for CI/CD pipelines and Docker builds. npm install when you're actively developing and want to add/update packages.
Never manually edit package-lock.json. It is generated by npm.
Essential npm Commands
npx: Run Without Installing
npx runs a package without permanently installing it. Useful for one-off tools and project generators:
npm Scripts
The "scripts" field in package.json is more powerful than it looks. npm adds node_modules/.bin to the PATH when running scripts, so you can reference package binaries directly without npx:
You can also run scripts in sequence (&&) or in parallel (&):
Pre and post hooks run automatically:
node_modules
When you run npm install, every package and its dependencies are downloaded into node_modules/. This folder can be enormous — a typical project has hundreds of megabytes. Two rules:
- Never commit
node_modulesto git. Add it to.gitignore. - Always commit
package-lock.jsonto git. Your colleagues need it to get the same versions.
If node_modules gets corrupted or out of sync, delete it and reinstall:
Essential Packages for Every Project
These are the packages you will install in almost every Node.js project:
Development tools:
Runtime utilities:
Nodemon configuration — create nodemon.json at the project root to avoid typing flags:
Global vs Local Packages
Most packages should be installed locally (in your project's node_modules). This ensures every project uses its own version and colleagues get the same thing.
The rule: if the package is a dependency of your project, install it locally. If it's a CLI tool you want available everywhere on your machine (like ts-node for quick scripts), install globally. In CI/CD, always use local packages.
Workspaces (Monorepos)
If you have multiple packages in one repository (a monorepo), npm workspaces let you manage them together:
Workspaces are out of scope for Foundation — just know they exist for when you encounter them.
Common Mistakes
Installing in the wrong directory:
Committing .env:
Not pinning the Node.js version:
Also create a .nvmrc at the project root:
20
Then anyone running nvm use automatically switches to the right version.
Using npm install in CI/CD:
Summary
package.jsonis the project manifest.dependenciesfor runtime packages,devDependenciesfor dev tools."scripts"for commands.- Semantic versioning:
MAJOR.MINOR.PATCH.^(caret) allows minor and patch updates. Pin exact versions only when necessary. package-lock.jsonensures reproducible installs. Always commit it. Usenpm ciin CI/CD.npm install <pkg>for runtime,npm install -D <pkg>for dev tools. Never install project dependencies globally.npxruns packages without installing them globally — ideal for project generators and one-off tools..nvmrcpins the Node.js version..gitignoreexcludesnode_modules/and.env. Both are mandatory.
Next: building HTTP servers with Express — routing, middleware, query parameters, and the structure of a real REST API.
In a package.json file, what does the version range "express": "^4.18.2" permit npm to install?
Why is npm ci preferred over npm install in automated CI/CD environments?
What is the main use case for the npx command?
Test your knowledge with more question sets
Sign in to access a wider variety of questions and get notified when new practice sets are added to this module.
Sign in & RegisterDiscussion
0Join the discussion