npm@5 has been published, it has a new feature package-lock.json
file (after npm install
) which confuses me. I want to know, what is the effect of this file?
-
4package-lock. json to keep track of exact dependency trees at any given time. It will ensure that all clients that download your project and attempt to install dependencies will get the exact same dependency tree.– ManojCommented May 26, 2021 at 13:55
8 Answers
It stores an exact, versioned dependency tree rather than using starred versioning like package.json
itself (e.g. 1.0.*). This means you can guarantee the dependencies for other developers or prod releases, etc. It also has a mechanism to lock (hence the name package-lock
) the tree but generally will regenerate if package.json
changes.
From the npm docs:
package-lock.json is automatically generated for any operations where npm modifies either the node_modules tree, or package.json. It describes the exact tree that was generated, such that subsequent installs are able to generate identical trees, regardless of intermediate dependency updates.
This file is intended to be committed into source repositories, and serves various purposes:
Describe a single representation of a dependency tree such that teammates, deployments, and continuous integration are guaranteed to install exactly the same dependencies.
Provide a facility for users to "time-travel" to previous states of node_modules without having to commit the directory itself.
To facilitate greater visibility of tree changes through readable source control diffs.
And optimize the installation process by allowing npm to skip repeated metadata resolutions for previously-installed packages."
To answer jrahhali's question below about just using the package.json
with exact version numbers. Bear in mind that your package.json
contains only your direct dependencies, not the dependencies of your dependencies (sometimes called nested or transitive dependencies). This means with the standard package.json
you can't control the versions of those nested dependencies, referencing them directly or as peer dependencies won't help as you also don't control the version tolerance that your direct dependencies define for these nested dependencies.
Even if you lock down the versions of your direct dependencies you cannot 100% guarantee that your full dependency tree will be identical every time. Secondly you might want to allow non-breaking changes (based on semantic versioning) of your direct dependencies which gives you even less control of nested dependencies plus you again can't guarantee that your direct dependencies won't at some point break semantic versioning rules themselves.
The solution to all this is the package-lock.json
file which as described above locks in the versions of the full dependency tree. This allows you to guarantee your dependency tree for other developers or for releases, whilst still allowing testing of new dependency versions (direct or indirect) using your standard package.json
.
NB. The previous npm-shrinkwrap.json
did pretty much the same thing, but the lock file renames it so that its function is clearer. If there's already a shrink wrap file in the project, then this will be used instead of any lock file.
2023
Since NPM v8.3.0 (2021-12-09), package.json
has a property overrides
which might help you not to touch package-lock.json
file.
To make sure the package foo is always installed as version 1.0.0 no matter what version your dependencies rely on:
{
"overrides": {
"foo": "1.0.0"
}
}
https://docs.npmjs.com/cli/v9/configuring-npm/package-json#overrides
-
136If having an exact version of dependencies is so sought after, why not enforce specifying the exact version in package.json and forgoe a package-lock.json file?– jmrahCommented Jun 9, 2017 at 16:52
-
32
-
3How gets this dependency tree from pacakge.json.lock applied for other developers? Automatically? Commented Jul 20, 2017 at 11:00
-
90Please note that this answer is no longer correct! The
package-lock.json
file is being updated every single time you call npm install since NPM 5.1. (change in github.com/npm/npm/issues/16866, example in github.com/npm/npm/issues/17979) It therefore can no longer be used to set the same versions for all developers, unless you specify exact versions like1.2.3
instead of1.2.*
in yourpackage.json
file. Commented Aug 18, 2017 at 9:28 -
28You should add a reference to
npm ci
asnpm install
will update the package-lock.json whereas ci uses its content. Only withnpm ci
will you get repeatable robust builds. Commented Sep 10, 2019 at 15:42
It's an very important improvement for npm: guarantee exact same version of every package.
How to make sure your project built with same packages in different environments in a different time? Let's say, you may use ^1.2.3
in your package.json
, or some of your dependencies are using that way, but how can you ensure each time npm install
will pick up same version in your dev machine and in the build server? package-lock.json will ensure that.
npm install
will re-generate the lock file.
When on build server or deployment server, do npm ci
(which will read from the lock file, and install the whole package tree)
-
26Note that this is kinda outdated now. In 5.1.0 onward, "npm install" does not read from the
package-lock.json
file at all. It just installs frompackage.json
like it used to. To make use of thepackage-lock.json
file, you have to use the new "npm ci" command, which will install the exact versions listed inpackage-lock.json
instead of the version-ranges given inpackage.json
.– VenryxCommented Jul 20, 2018 at 2:21 -
19I'm afraid Venryx is incorrect.
npm install
does read frompackage-lock.json
. To reproduce, do the following. using this package.json, runnpm install
{ ... "devDependencies": { "sinon": "7.2.2" } } Now copy/pastepackage.json
andpackage-lock.json
to a new directory. Changepackage.json
to: "sinon": "^7.2.2" runnpm install
. npm reads from package-lock.json and installs 7.2.2 instead of 7.3.0. Without package-lock.json, 7.3.0 would be installed.– zumafraCommented Mar 23, 2019 at 19:45 -
3And not only that, but if you want to do something like add the caret ^ to
package-lock.json
, the only reasonable way to do that is to deletepackage-lock.json
and regenerate it usingnpm install
. (You don't want to manually editpackage-lock.json
). Changing the value of the "version" property (near the top) ofpackage.json
will change the same inpackage-lock.json
onnpm install
, but adding a caret to a dependency will not do the same topackage-lock.json
.– zumafraCommented Mar 23, 2019 at 20:07 -
3Think of
package.json
as something that you can manually modify, andpackage-lock.json
as something that you never manually touch. You always version control BOTH files - especiallypackage-lock.json
. Open both files, manually edit the project name inpackage.json
, runnpm install
and watch how the project name changes inpackage-lock.json
.license
doesn't seem to be recorded inpackage-lock.json
.– zumafraCommented Sep 4, 2019 at 2:31 -
3@zumafra package-lock.json file will be use when doing
npm ci
,npm install
will just use package.json, even though the lock file is provided– XinCommented Sep 4, 2019 at 22:55
package-lock.json
is written to when a numerical value in a property such as the "version" property, or a dependency property is changed in package.json
.
If these numerical values in package.json
and package-lock.json
match, package-lock.json
is read from.
If these numerical values in package.json
and package-lock.json
do not match, package-lock.json
is written to with those new values, and new modifiers such as the caret and tilde if they are present. But it is the numeral that is triggering the change to package-lock.json
.
To see what I mean, do the following. Using package.json
without package-lock.json
, run npm install
with:
{
"name": "test",
"version": "1.0.0",
...
"devDependencies": {
"sinon": "7.2.2"
}
}
package-lock.json
will now have:
"sinon": {
"version": "7.2.2",
Now copy/paste both files to a new directory. Change package.json
to (only adding caret):
{
"name": "test",
"version": "1.0.0",
...
"devDependencies": {
"sinon": "^7.2.2"
}
}
run npm install
. If there were no package-lock.json
file, [email protected] would be installed. npm install
is reading from package-lock.json
and installing 7.2.2.
Now change package.json
to:
{
"name": "test",
"version": "1.0.0",
...
"devDependencies": {
"sinon": "^7.3.0"
}
}
run npm install
. package-lock.json
has been written to, and will now show:
"sinon": {
"version": "^7.3.0",
One important thing to mention as well is the security improvement that comes with the package-lock file. Since it keeps all the hashes of the packages if someone would tamper with the public npm registry and change the source code of a package without even changing the version of the package itself it would be detected by the package-lock file.
This file is automatically created and used by npm to keep track of your package installations and to better manage the state and history of your project’s dependencies. You shouldn’t alter the contents of this file.
-
2
The goal of package-lock.json
file is to keep track of the exact version of every package that is installed so that a product is 100% reproducible in the same way even if packages are updated by their maintainers.
This solves a very specific problem that package.json
left unsolved. In package.json you can set which versions you want to upgrade to (patch or minor), using the semver notation.
package-lock.json
: It contains the exact version details that is currently installed for your Application.
-
3Hi, and welcome. This question has already been answered. You have to verify if the question has marked as answered seeing if any of the answers has a green ckeck in front of it.– NéstorCommented Jun 3, 2020 at 19:15
-
5@Néstor Don't get it wrong. One can answer to already answered question given that the answer is new and useful. (although it's not the case in this answer). Commented Oct 17, 2020 at 6:54
-
3The answer you provided has already been given! Consider improving the quality of the information to make this a valuable answer! Commented Jan 3, 2021 at 14:07
package.json
file contains the main names of packages & libraries which you installed and you can edit it, but package-lock.json
contains the details of each package and the link of repository of each package (consider it as the details of the packages which came from package.json
).
Reference: package-lock