NPM is a popular package manager (think NuGet for JavaScript) and the information of the packages that it needs to install is stored in a file called
package.json. You run
npm install, packages are getting downloaded in a folder called
node_modules and a
package-lock.json file is generated. Since you can always delete
node_modules and
package-lock.json and rerun the package install, a common assumption is that they are redundant and they shouldn't be stored in source control. That is wrong in most cases.
The lock file not only stores the progress of the npm installation, but also the actual versions of the packages that it installs (for the entire dependency tree). As opposed to this,
package.json contains only the packages directly needed by the project and the acceptable ranges of the versions. One can allow for any version of a package to be used, or maybe anything above a version, or an interval or something that is "the best version" around a specific version. Deleting the
package-lock.json file effectively tells NPM that you trust
package.json and the developers of each package for the versions of the dependencies loaded.
Here is a common scenario: you create a new application, you need some NPM packages so you
npm install thePackage. This gets the latest version of thePackage and installs it, then marks the exact version into
package-lock.json as well as the versions of the packages thePackage uses and what they use and so on. Finally, you commit the project, including
package-lock.json. Three months later, a new developer comes and gets the project from source control. They use
npm install and see that everything works perfectly, because the packages restored are the exact same versions as the ones restored for the original developer. But now they think "who committed package-lock.json? Don't they know it's redundant?" so they remove it from source control. Three months later another developer comes and runs
npm install on the source from the code repository, only nothing works anymore. The versions that were downloaded are, depending on what is specified in
package.json, the latest version of the dependency or maybe a version similar, but with a different minor version, and with the dependencies that the developers thought best for that particular version.
There is a situation when
package-lock.json is entirely redundant and that is when
package.json only specifies exact versions. NPM works so that you cannot replace the same version of a software in their repository, so the devs will never be able to change the package versions they used for a specific version. That is why it is safe to assume that the same version of a package will use the same package dependency tree (unless some of the packages are removed, but that's another question entirely).
Summary:
If you have any version of a dependency in package.json specified as anything else than a specific version (no tilde, no caret, no asterisks, no intervals), then you also need to store package-lock.json in your source control.