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.
Facilitate greater visibility of tree changes through readable source control diffs.
Optimize the installation process by allowing npm to skip repeated metadata resolutions for previously-installed packages.
As of npm v7, lockfiles include enough information to gain a complete
picture of the package tree, reducing the need to read
files, and allowing for significant performance improvements.
Both of these files have the same format, and perform similar functions in the root of a project.
The difference is that
package-lock.json is that it cannot be published,
and it will be ignored if found in any place other than the root project.
In contrast, npm-shrinkwrap.json allows publication, and defines the dependency tree from the point encountered. This is not recommended unless deploying a CLI tool or otherwise using the publication process for producing production packages.
npm-shrinkwrap.json are present in the
root of a project,
npm-shrinkwrap.json will take precedence and
package-lock.json will be ignored.
In order to avoid processing the
node_modules folder repeatedly, npm as
of v7 uses a "hidden" lockfile present in
node_modules/.package-lock.json. This contains information about the
tree, and is used in lieu of reading the entire
provided that the following conditions are met:
node_moduleshierarchy that are not listed in the lockfile.
That is, the hidden lockfile will only be relevant if it was created as part of the most recent update to the package tree. If another CLI mutates the tree in any way, this will be detected, and the hidden lockfile will be ignored.
Note that it is possible to manually change the contents of a package
in such a way that the modified time of the package folder is unaffected.
For example, if you add a file to
node_modules/foo/lib/bar.js, then the
modified time on
node_modules/foo will not reflect this change. If you
are manually editing files in
node_modules, it is generally best to
delete the file at
As the hidden lockfile is ignored by older npm versions, it does not
contain the backwards compatibility affordances present in "normal"
lockfiles. That is, it is
lockfileVersion: 3, rather than
When npm detects a lockfile from npm v6 or before during the package
installation process, it is automatically updated to fetch missing
information from either the
node_modules tree or (in the case of empty
node_modules trees or very old lockfile formats) the npm registry.
The name of the package this is a package-lock for. This will match what's
The version of the package this is a package-lock for. This will match
An integer version, starting at
1 with the version number of this
document whose semantics were used when generating this
Note that the file format changed significantly in npm v7 to track
information that would have otherwise required looking in
the npm registry. Lockfiles generated by npm v7 will contain
1: The lockfile version used by npm v5 and v6.
2: The lockfile version used by npm v7, which is backwards compatible to v1 lockfiles.
3: The lockfile version used by npm v7, without backwards compatibility affordances. This is used for the hidden lockfile at
node_modules/.package-lock.json, and will likely be used in a future version of npm, once support for npm v6 is no longer relevant.
npm will always attempt to get whatever data it can out of a lockfile, even if it is not a version that it was designed to support.
This is an object that maps package locations to an object containing the information about that package.
The root project is typically listed with a key of
"", and all other
packages are listed with their relative paths from the root project folder.
Package descriptors have the following fields:
version: The version found in
resolved: The place where the package was actually resolved from. In the case of packages fetched from the registry, this will be a url to a tarball. In the case of git dependencies, this will be the full git url with commit sha. In the case of link dependencies, this will be the location of the link target.
sha1 Standard Subresource
string for the artifact that was unpacked in this location.
link: A flag to indicate that this is a symbolic link. If this is present, no other fields are specified, since the link target will also be included in the lockfile.
dev, optional, devOptional: If the package is strictly part of the
devDependencies tree, then
dev will be true. If it is strictly part
optionalDependencies tree, then
optional will be set. If it
is both a
dev dependency and an
optional dependency of a non-dev
devOptional will be set. (An
optional dependency of
dev dependency will have both
inBundle: A flag to indicate that the package is a bundled dependency.
hasInstallScript: A flag to indicate that the package has a
hasShrinkwrap: A flag to indicate that the package has an
bin, license, engines, dependencies, optionalDependencies: fields from
Legacy data for supporting versions of npm that use
This is a mapping of package names to dependency objects. Because the
object structure is strictly hierarchical, symbolic link dependencies are
somewhat challenging to represent in some cases.
npm v7 ignores this section entirely if a
packages section is present,
but does keep it up to date in order to support switching between npm v6
and npm v7.
Dependency objects have the following fields:
version: a specifier that varies depending on the nature of the package, and is usable in fetching a new copy of it.
sha1 Standard Subresource
string for the artifact that was unpacked in this location. For git
dependencies, this is the commit sha.
resolved: For registry sources this is path of the tarball relative to the registry URL. If the tarball URL isn't on the same server as the registry URL then this is a complete URL.
bundled: If true, this is the bundled dependency and will be installed by the parent module. When installing, this module will be extracted from the parent module during the extract phase, not installed as a separate dependency.
dev: If true then this dependency is either a development dependency ONLY of the top level module or a transitive dependency of one. This is false for dependencies that are both a development dependency of the top level and a transitive dependency of a non-development dependency of the top level.
optional: If true then this dependency is either an optional dependency ONLY of the top level module or a transitive dependency of one. This is false for dependencies that are both an optional dependency of the top level and a transitive dependency of a non-optional dependency of the top level.
requires: This is a mapping of module name to version. This is a list of
everything this module requires, regardless of where it will be
installed. The version should match via normal matching rules a
dependency either in our
dependencies or in a level higher than us.
dependencies: The dependencies of this dependency, exactly as at the top level.