package-lock.json
seems like a really, really dull file. And ideally, it is.
It is like the keys on your keyboard which you don't notice until they get crunchy (looking at you butterfly and silicon-based keyboards).
But do enough package
installs and you'll run into issues. This article is a high-level overview of the what and the why of package.json
and package-lock.json
so you can debug with understanding.
The purpose of the package-lock.json
is to let every developer on a repo have the same package tree, meaning each developer has the exact same packages and all dependencies versions as you, even if there are new packages available.
Why Should You Care?
Depending on how the package.json
is written, an npm install
command could install a more recent patch, a minor update, or the exact same package. If the packages and their dependencies are different, it might not cause an issue….or it might.
The package-lock.json
is used by NPM when you npm install
and the lock file is set in digital stone; whereas, package.json
just indicates major package dependencies, how to handle updates and is meant to be changed by a developer.
Think of package.json
as what you want to install and the lock
file as what exactly and precisely was installed.
How Package.json Controls Updates via SemVer
A key part of package version control is with SemVer specs. aka Semantic Versioning. aka v.~0.0.0
or ^a.b.c
a
is the major version, breaking backward compatibility.
b
is new features but doesn’t change current features
c
is a bug fix
So why do you care? If you run into issues on npm install
, likely you have a version issue.
For now, just know this (the relationship is explained in the next section):
The characters ~
, ^
, or lack of, dictate how and when a repo’s direct dependencies update.
- if you write ~0.13.0, you want only update patch releases: 0.13.1 is ok, but 0.14.0 is not.
- if you write ^0.13.0, you want to update patch and minor releases: 0.13.1, 0.14.0 and so on.
- if you write 0.13.0, that is the exact version that will be used, always
- Source: nodejs.dev
Relationship Between npm install
and the package
Files.
When you npm install
a repo without a package-lock.json
, NPM “knows” to install the latest version of the packages within the minor release.
That is, if a semantic version (aka semver) is ^0.13.0 for package X, NPM won’t install version 1.0.0 (assuming a developer follows semver specs), but it might install 0.15.0 as the latest version. And while 0.15.0 should be compatible with 0.13.0 features, it might introduce a bug.
This is where the package-lock.json
comes in handy.
When you npm install
a repo with a package-lock.json
, npm “knows” to install all the packages and versions dictated in the lock file. Since the lock file is committed to source control, everyone will have the same packages and package dependencies. #magic
Tip: If you are doing a tutorial from scratch and run into issues with packages, make sure you can at least use the same package.json
and package-lock.json
files from their repo.
Interesting Facts to Know about package-lock.json
- Automatically generated when NPM changes node_modules tree or the package.json file is changed.
- It should be committed into your source repo.
- It is ignored if found anywhere else other than in top-level folder structure.
- Didn’t exist before version NPM v5.
-
package.json
dictates what is inpackage-lock.json
as of PR17508.
Resources && References
NPM Official Doc on Package-lock.json
Node.js Explanation
What is SemVer?
How to Upgrade Major Version in NPM
Why You Should Code on a Mechanical Keyboard
Feedback? Suggestions? Additions?
Did I miss something? Should I add something other devs should know? Drop a comment and I'll update the article with the appropriate information (and citation).
Top comments (3)
seems odd talking about package-lock and not mentioning
npm ci
medium.com/better-programming/npm-...
Until you mentioned it, I didn't know about it. Seems quite helpful for getting versioning correct.
Keep in mind that semver behaves differently for 0.x.x than it does for 1+.x.x