dependencies vs devDependencies vs peerDependencies, and what is a lockfile?

3 minintermediatenodejsnpmdependencieslockfilepeer-dependencies

Quick Answer

`dependencies` are needed at runtime; `devDependencies` are only for development/build/test and aren't installed by consumers with `--production`; `peerDependencies` declare a compatible version a host app must provide (common for plugins). The lockfile (`package-lock.json`) pins the exact resolved dependency tree for reproducible installs.

Detailed Answer

Answer:

dependencies — packages your code needs to run in production (e.g., express, pg). Installed by default for anyone using your package.

devDependencies — packages needed only during development/build/test (e.g., jest, eslint, typescript, bundlers). Skipped when installing with npm install --omit=dev (formerly --production), which keeps production images lean.

peerDependencies — a compatible version your package expects the host to provide, rather than bundling its own copy. Typical for plugins/libraries that must share a single instance with the host:

// a React component library
"peerDependencies": { "react": ">=17" }

This avoids two copies of React and the "invalid hook call" class of bugs.

optionalDependencies — installs are attempted but failures don't abort (e.g., platform-specific binaries).

Lockfile (package-lock.json, or yarn.lock/pnpm-lock.yaml):

  • Records the exact version and integrity hash of every package in the entire tree (including transitive deps).
  • Guarantees reproducible installs — everyone and every CI machine gets the identical tree, regardless of when they install.
  • Commit it. Use npm ci in CI, which installs strictly from the lockfile and fails if package.json and the lock disagree — faster and deterministic.

Interview tip: package.json says what ranges are acceptable; the lockfile says what was actually installed.