Confused about whether to commit package-lock.json when publishing to npm? Here's the standard practice for public repositories.
When maintaining an open source project or reusable package on npm, it’s easy to run into uncertainty:
- Should you commit
package-lock.json
? - How do you ensure consistent dependency resolution?
- What do end users get when they install your package?
This post breaks down the standard industry practice for open-source npm packages — especially regarding lock files, dependency pinning, CI, and secure publishing.
🔒 Should I Commit package-lock.json
?
Yes, commit package-lock.json
to your Git repo — but know that:
package-lock.json
is ignored when you publish a package to the npm registry.
This means it benefits you and your contributors, but has no direct effect on your package consumers.
Benefits of committing it:
- ✅ Consistent installs during development
- ✅ Reproducible CI environments
- ✅ Easier debugging & auditing
- ✅ Clear diffs when dependencies are upgraded
📦 What Gets Published to npm?
By default, npm publishes:
- Your
package.json
- Files not listed in
.npmignore
(or included in thefiles
field) -
But not
package-lock.json
(unless you publish anpm-shrinkwrap.json
— more on that below)
TL;DR:
Consumers install dependencies based on your
package.json
semver ranges, not your lock file.
🛠 How to Pin Dependencies for Safety
Even though you can’t ship a lock file, you can prevent surprises:
✅ Use exact versions in package.json
:
"dependencies": {
"lodash": "4.17.21" // Not ^4.17.21
}
Avoid semver ranges like ^ or ~ if you want deterministic installs.
📄 What About npm-shrinkwrap.json?
npm-shrinkwrap.json is published with your package and locks the entire dependency tree.
But:
⚠️ It can conflict with your consumers' dependencies
⚠️ It makes updating harder for downstream projects
✅ Useful for CLI tools or apps where you want full control of the install
For libraries, it's not standard to use shrinkwrap.
🧪 CI & Testing Best Practices
Use npm ci in CI — this installs from the lock file and ensures reproducible builds.
Test the final output using:
npm pack
This shows you exactly what your users will get before you publish.
Automate checks before publishing:
"scripts": {
"prepublishOnly": "npm test && npm run lint && npm run build"
}
🤝 Use Peer Dependencies Wisely
If your library is designed to plug into another framework (e.g. React, Next.js, ESLint):
Declare those as peerDependencies in package.json.
Don’t bundle them in your dependencies.
This avoids version conflicts and duplication.
Example:
"peerDependencies": {
"react": "^18.0.0"
}
🔐 Security Practices
Run npm audit regularly
Use tools like:
Dependabot
Snyk
GitHub security alerts
Keep your dependencies updated — responsibly!
✨ Final Thoughts
Committing your lock file doesn’t harm your npm package — it helps your team. And while npm won’t publish it, you can still enforce reliable builds and secure installs by pinning versions, using CI properly, and testing your tarballs.
If you’ve ever been burned by a subtle dependency upgrade breaking your users — you’re not alone. Following these practices can save you (and your users) hours of debugging.
Top comments (0)