If you’ve worked with Node.js or npm, you’ve definitely seen package.json and package-lock.json sitting side by side in your project. Many developers know they’re related to dependencies, but not everyone clearly understands why both exist and what makes them different.
Let’s break it down in a simple way.
📄 What is package.json?
package.json is the project manifest file. It describes your project and lists the dependencies your application needs.
It typically includes:
- Project name and version
- Scripts (
npm start,npm build, etc.) - Dependencies
- Dev dependencies
- Metadata (author, license, etc.)
Example
{
"name": "my-app",
"version": "1.0.0",
"dependencies": {
"express": "^4.18.2"
}
}
Key Point
When you write:
"express": "^4.18.2"
The ^ means npm can install any compatible version, such as:
- 4.18.2
- 4.19.0
- 4.x.x
So installs may differ over time. ⚠️
What is package-lock.json?
package-lock.json is automatically generated by npm. It locks the exact versions of every installed dependency (including sub-dependencies).
It ensures:
- Same dependency tree
- Same versions
- Same install across machines
Example (simplified)
{
"dependencies": {
"express": {
"version": "4.18.2",
"resolved": "...",
"integrity": "..."
}
}
}This file guarantees that everyone installs the exact same version, even if package.json allows flexibility.
Main Differences
| Feature | package.json | package-lock.json |
|---|---|---|
| Purpose | Defines dependencies | Locks exact versions |
| Created by | Developer | npm automatically |
| Should you edit? | Yes | No |
| Version flexibility | Yes | No |
| Included in Git? | Yes | Yes |
| Controls sub-dependencies | No | Yes |
Why Both Files Are Needed
Think of it like this:
package.json→ What you wantpackage-lock.json→ What you actually got
Example scenario:
- You install today → version 1.2.3
- Your teammate installs tomorrow → version 1.2.5
- App breaks 😱
With package-lock.json, everyone installs exactly 1.2.3 — no surprises.
When Does package-lock.json Update?
It updates when:
- You run
npm install - You add/remove packages
- You run
npm update
Should You Commit package-lock.json?
Yes – always commit it to Git.
Benefits:
- Reproducible builds
- Faster installs
- Prevents “works on my machine” issues
Quick Analogy
package.json= Shopping list 🛒package-lock.json= Receipt with exact brands and quantities 🧾
Conclusion
Both files serve different but complementary purposes:
- Use package.json to declare dependencies
- Use package-lock.json to guarantee consistency
Never delete package-lock.json unless you intentionally want to regenerate dependencies.
Happy coding!