package.json describes the project and the version ranges it accepts, while package-lock.json records the exact versions npm installed. You edit package.json yourself. It holds the project metadata and scripts, plus the dependencies and devDependencies lists.
{
"name": "my-app",
"version": "1.0.0",
"dependencies": {
"express": "^4.18.0"
},
"devDependencies": {
"nodemon": "^2.0.15"
}
}
A range like ^4.18.0 accepts any later 4.x release, so two installs months apart can differ. npm install updates the lock file whenever it changes node_modules.
The lock file maps the exact dependency tree, sub-dependencies included, with an integrity hash for each package. A tampered download then fails the check. Commit the lock file so every environment installs the same tree, and use npm ci in builds to install exactly what it lists.
This answer doesn't lend itself to a diagram - it reads best . No credits were charged.
Why there's no diagram: “”
The interactive diagram is below the answer - jump to diagram ↓ · Below it, the related concept . Jump to it ↓
The diagram below the answer is the concept . Jump to it ↓