Module F-5·18 min read

package.json anatomy, semantic versioning, package-lock.json, npm scripts, and the essential dev tools every Node.js engineer installs first.

JJS
Written by Jatin Jain Saraf · Senior Software Engineer

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:

  1. Registry: A central database of over two million open-source JavaScript packages at npmjs.com
  2. CLI: The npm command you run to install, update, and remove packages
  3. 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:

bash

A typical package.json:

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 someone requires your package. For apps, this is your server entry file.
  • "type": "module" — makes all .js files use ES Modules. Omit for CommonJS.
  • "scripts" — shortcuts for commands. npm run dev runs whatever is under "dev".
  • "dependencies" — packages required to run in production.
  • "devDependencies" — packages only needed during development (testing, linting, build tools).
  • "engines" — documents the Node.js version(s) your project is intended to run on. By default npm does not enforce this — it will still install and run on the "wrong" version, just with a warning. It becomes a hard block only if you also set engine-strict=true in .npmrc.

dependencies vs devDependencies

bash

When you deploy to production, you can run npm install --omit=dev to skip devDependencies — keeping the production image smaller.

peerDependencies

There's a third dependency field you'll run into once you start using plugin-style packages: "peerDependencies". It declares "this package needs a compatible version of X to already be installed by whoever uses me" — instead of bundling its own copy of X. React component libraries do this with react itself; ESLint plugins do it with eslint.

json

This is the source of a warning almost every beginner hits and is confused by: npm install reports something like npm WARN some-eslint-plugin@1.0.0 requires a peer of eslint@>=8.0.0 but none is installed. It's not an error — npm is telling you the plugin expects you to also have eslint installed at a compatible version, because it assumes you already do (as the thing it's plugging into). Install the peer dependency yourself and the warning goes away.


Semantic Versioning

Every npm package uses semantic versioning (semver): MAJOR.MINOR.PATCH.

PartWhen it changesExample
MAJORBreaking change — your code may need updating4.0.05.0.0
MINORNew features, backwards compatible4.18.04.19.0
PATCHBug fixes, backwards compatible4.18.24.18.3

In package.json, version ranges control which updates you accept automatically:

json

^ (caret) is the default when you npm install express. It allows 4.19.0, 4.18.3, but not 5.0.0.

Analogy: The caret (^) is a bouncer who lets in anyone from the same major-version family as long as they don't break the dress code — patch and minor releases are safe guests, a major bump is a completely different party.

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.

Sign in to keep reading

The rest of this module is free — sign in with Google to unlock it and track your progress.

Sign in & Register

Discussion

0

Join the discussion

Loading comments...

© 2026 Jatin Jain Saraf (JJS). All rights reserved.