Back to results for “Git & Project Management”
Node.js › Git & Project Management

What is the purpose of a package-lock.json file in a Node.js project, and why should it be committed to version control?

Beginner

Answer

package-lock.json records the exact resolved version of every installed dependency (including nested transitive dependencies), ensuring that running 'npm install' produces byte-for-byte identical dependency versions across every machine and CI run -- without it, package.json's version ranges (like '^1.2.0') could resolve to different actual versions over time as new compatible releases are published, potentially introducing subtle, hard-to-reproduce bugs between different installs.
// package.json allows a range of versions
"dependencies": { "express": "^4.18.0" }

// package-lock.json pins the exact resolved version and its full dependency tree
"express": {
  "version": "4.18.2",
  "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz"
}
Real-world example A team debugging a bug that only reproduced in production eventually traced it to a subtle behavior difference introduced by a transitive dependency's patch version, which had drifted between a developer's local install and the CI/production install because package-lock.json hadn't been committed to version control.

Common follow-ups: What's the difference between 'npm install' and 'npm ci' regarding how they use (or don't use) package-lock.json?;Why is it considered bad practice to manually edit package-lock.json by hand?