package-lock.json

The lock file pins exact versions for reproducible installs.

Syntaxnpm ci

package-lock.json is generated automatically by npm. While package.json lists version ranges, the lock file records the exact version of every package (and sub-dependency) that was installed.

Why it matters

It guarantees that everyone — and every server — installs identical versions, avoiding the classic "works on my machine" problem.

Always commit package-lock.json to git.

Example

Example · bash
# npm install may update the lock file
npm install

# npm ci installs EXACTLY what the lock file says
# (deletes node_modules first — great for CI)
npm ci

When to use it

  • A staging deploy installs identical versions to production because `package-lock.json` is committed to git and `npm ci` uses it verbatim.
  • A debugging session compares `package-lock.json` between a working and a broken build to find a dependency that auto-upgraded between deploys.
  • A monorepo sync script detects when `package-lock.json` is newer than `node_modules` and re-runs `npm ci` to keep the install current.

More examples

Why package-lock.json exists

Illustrates the difference between the range in `package.json` and the exact pinned version in `package-lock.json`.

Example · json
// package.json specifies a range:
// "express": "^4.18.0"

// package-lock.json records the EXACT version installed:
// "express": {
//   "version": "4.18.2",
//   "resolved": "https://registry.npmjs.org/express/-/...",
//   "integrity": "sha512-..."
// }

npm install vs npm ci

Contrasts `npm install` (may update the lock file) with `npm ci` (strict lock file enforcement for reproducibility).

Example · bash
# npm install: resolves ranges, may update lock file
npm install

# npm ci: uses lock file exactly, fails if it mismatches package.json
# Faster for CI because it skips resolution
npm ci

Commit the lock file

Explains that apps should commit the lock file for reproducibility while libraries typically should not.

Example · bash
# Always commit package-lock.json (for apps)
git add package.json package-lock.json
git commit -m 'chore: add express 4.18.2'

# Libraries typically .gitignore the lock file
# so consumers resolve their own dependency tree

Discussion

  • Be the first to comment on this lesson.