DEV Community

adam klein
adam klein

Posted on

package-lock.json - in GIT or not?


  1. Put it in GIT
  2. Commit it every-time it changes
  3. Never delete it

What is version locking and why we need it?

You write your software, commit it, push it, test it and if everything works well - deploy it to production.

But how do you know that what you tested locally is the same code that is tested on the CI, and is the same code that is being deployed to production?

Your code is inside GIT (or some other version control). If you pull the repository at the exact same commit, you will have the same code.

But your application does not consist only of your own code. It uses external packages as well. One solution for this problem is to commit the node_modules folder to GIT, which includes all of the code your application uses. This creates a problem by itself because then every npm install will create thousands and more changes, and will make it impossible to maintain your repository.

BUT, you don't really need the entire code of the packages you are using, only their versions. Every time you pull the same version from NPM repository you will get the same code.

So, a lock file keeps the version of all our dependencies, and whenever someone runs npm install, they will get the exact same version of your application, including external dependencies.

Why not just keep exact versions in package.json?

Your package.json only points to the versions of your direct dependencies. If they have dependencies too (and they do), these versions won't be locked.

Why not delete package-lock.json?

Think about it, if you delete package-lock and re-install, you are forcing the latest versions of all packages in the dependency tree. Meaning, you are changing the behavior of (potentially) the entire application.

What are you really trying to do? If you have some weird npm-related problem, simply remove node_modules and run npm install again. Removing package-lock.json is never the solution.

Why commit package-lock.json?

If you don't commit it, then the version of the application everyone else will get is different than what you are running locally. This means that things might work for you, but break on the CI/production/other local machines

Hope it helps to understand. And if you are still not certain about the explanation, just follow the 3 rules in the tl;dr section blindly. That's better than nothing

Top comments (3)

professortom profile image
Tomas Gallucci

you are forcing the latest versions of all packages in the dependency tree.

I do not believe this is quite right. You can pin versions in package.json. If a package your project depends on depends on another package, that second layer of dependency can also be pinned by the package your project depends on.

Now, there are no guarantees, of course–it's possible the package you depend on depends on latest for one or more of its dependencies. I'm sure you can find many examples of this. However, that is a bad practice and I would assume that, by and large, responsible package maintainers pin their dependencies to something sane and not latest.

hristiancarabulea profile image
Hristian Carabulea

I only left the package-lock.json, and it did not work. I still had to install express and body-parser manually. It seems that package-lock.json does not have any advantages whatsoever. I will not upload it to remote depository any longer. I will just specify in README what needs to be install to be able to run the program.

stephencora profile image
Stephen Speakman

Hristian, the lock file is like a snapshot of the exact module versions last installed / updated and tested by the developer including dependencies. The package.json file often only defines rough semver guidelines on a range of versions to install - not an exact specific version.

For this reason if you do not use the lock file like this article suggests, whilst you may have last tested your project was working with module 3.5.7, by the time you deploy to production, 3.5.8 may have released and accidentally introduced breaking changes - you can't know to expect this so when you deploy it uses that latest version... now production is broken because you chose not to use a lock file.

Commit your lock file and install from it on deployment...