What is the difference between package.json and package-lock.json?
Understand package.json vs package-lock.json in Node.js: version ranges vs pinned versions, reproducible installs, npm ci, and why you commit the lock file.
Expected Interview Answer
package.json is the human-authored manifest that declares a project's metadata and its dependency version ranges, while package-lock.json is an auto-generated file that records the exact resolved version of every installed package, including nested dependencies.
In package.json you typically list flexible ranges like ^4.17.1, which allows npm to install any compatible newer version. package-lock.json pins the precise version, resolved URL, and integrity hash of the whole dependency tree so installs are deterministic. When you run npm install, npm reads the lock file to reproduce the exact same tree everywhere; npm ci relies on it entirely and fails if it drifts from package.json. The lock file should be committed to version control so every developer and CI machine gets identical dependencies.
- package.json is readable and hand-edited to declare intent
- package-lock.json guarantees reproducible, deterministic installs
- Records exact versions plus integrity hashes for security
- Locks the entire nested dependency tree, not just direct deps
- Speeds up installs and powers the strict npm ci command
AI Mentor Explanation
package.json is the team's playing philosophy — 'pick any fast bowler above 140 kph.' package-lock.json is the actual team sheet naming the exact eleven who took the field in the last match, so you can field precisely that side again. The manifest states a preference; the lock file records the concrete lineup that was chosen.
Step-by-Step Explanation
Step 1
Declare dependencies
You add packages with version ranges (like ^ or ~) to package.json, by hand or via npm install <pkg>.
Step 2
npm resolves the tree
npm reads the ranges, resolves compatible versions for every direct and nested dependency, and installs them.
Step 3
Lock file is written
npm generates or updates package-lock.json with the exact version, resolved URL, and integrity hash of each package.
Step 4
Commit both files
Check package.json and package-lock.json into version control so teammates and CI reproduce the same tree.
Step 5
Reproduce installs
npm install honors the lock file; npm ci installs strictly from it and errors if it disagrees with package.json.
What Interviewer Expects
- Knows package.json is hand-authored and package-lock.json is generated
- Explains version ranges vs exact pinned versions
- Understands the lock file ensures deterministic, reproducible installs
- Knows the lock file covers the full nested dependency tree with integrity hashes
- Mentions committing the lock file and the role of npm ci
Common Mistakes
- Saying package-lock.json should be gitignored
- Editing package-lock.json by hand
- Thinking package.json alone guarantees identical installs
- Confusing npm install with npm ci behavior
- Believing the lock file only records direct dependencies
Best Answer (HR Friendly)
“package.json is a project's list of the tools it needs, written by developers with flexible version rules. package-lock.json is an automatic record of the exact versions actually installed, so everyone on the team ends up with identical dependencies.”
Code Example
// package.json — declares a flexible range
{
"name": "my-app",
"version": "1.0.0",
"dependencies": {
"express": "^4.18.2"
}
}
// package-lock.json — pins the exact resolved version + integrity hash
{
"packages": {
"node_modules/express": {
"version": "4.18.2",
"resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz",
"integrity": "sha512-..."
}
}
}
// npm ci installs strictly from the lock file for reproducible buildsFollow-up Questions
- What does the caret (^) versus tilde (~) mean in a version range?
- What is the difference between npm install and npm ci?
- Should package-lock.json be committed to version control?
- What is the integrity field in the lock file for?
- How does semantic versioning (SemVer) drive dependency ranges?
MCQ Practice
1. Which file is automatically generated rather than hand-written?
package-lock.json is generated by npm to record the exact resolved dependency tree, while package.json is authored by developers.
2. What does package-lock.json primarily guarantee?
By pinning exact versions and integrity hashes for the whole tree, the lock file ensures every install reproduces the same dependencies.
3. Which command installs strictly from package-lock.json and fails on mismatch?
npm ci installs exactly what the lock file specifies and errors if package.json and package-lock.json are out of sync.
Flash Cards
Who writes package.json? — Developers — it is the hand-authored manifest of metadata and dependency ranges.
What does package-lock.json record? — The exact version, resolved URL, and integrity hash of every package in the tree.
Why commit the lock file? — So every developer and CI machine gets identical, reproducible dependencies.
npm install vs npm ci? — install may update the lock file; ci installs strictly from it and fails on drift.