DEV Community

Brad Beggs
Brad Beggs

Posted on

A Few Interesting Bits About package-lock.json. #yesReally

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:

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 in package-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)

solotoo_48 profile image

seems odd talking about package-lock and not mentioning npm ci

brad_beggs profile image
Brad Beggs

Until you mentioned it, I didn't know about it. Seems quite helpful for getting versioning correct.

cherrydt profile image
David Trapp

Keep in mind that semver behaves differently for 0.x.x than it does for 1+.x.x