deps/npm/html/partial/doc/cli/npm-shrinkwrap.html

Summary

Maintainability
Test Coverage
<h1><a href="../cli/npm-shrinkwrap.html">npm-shrinkwrap</a></h1> <p>Lock down dependency versions</p>
<h2 id="synopsis">SYNOPSIS</h2>
<pre><code>npm shrinkwrap
</code></pre><h2 id="description">DESCRIPTION</h2>
<p>This command locks down the versions of a package&#39;s dependencies so
that you can control exactly which versions of each dependency will be
used when your package is installed. The <code>package.json</code> file is still
required if you want to use <code>npm install</code>.</p>
<p>By default, <code>npm install</code> recursively installs the target&#39;s
dependencies (as specified in <code>package.json</code>), choosing the latest
available version that satisfies the dependency&#39;s semver pattern. In
some situations, particularly when shipping software where each change
is tightly managed, it&#39;s desirable to fully specify each version of
each dependency recursively so that subsequent builds and deploys do
not inadvertently pick up newer versions of a dependency that satisfy
the semver pattern. Specifying specific semver patterns in each
dependency&#39;s <code>package.json</code> would facilitate this, but that&#39;s not always
possible or desirable, as when another author owns the npm package.
It&#39;s also possible to check dependencies directly into source control,
but that may be undesirable for other reasons.</p>
<p>As an example, consider package A:</p>
<pre><code>{
  &quot;name&quot;: &quot;A&quot;,
  &quot;version&quot;: &quot;0.1.0&quot;,
  &quot;dependencies&quot;: {
    &quot;B&quot;: &quot;&lt;0.1.0&quot;
  }
}
</code></pre><p>package B:</p>
<pre><code>{
  &quot;name&quot;: &quot;B&quot;,
  &quot;version&quot;: &quot;0.0.1&quot;,
  &quot;dependencies&quot;: {
    &quot;C&quot;: &quot;&lt;0.1.0&quot;
  }
}
</code></pre><p>and package C:</p>
<pre><code>{
  &quot;name&quot;: &quot;C&quot;,
  &quot;version&quot;: &quot;0.0.1&quot;
}
</code></pre><p>If these are the only versions of A, B, and C available in the
registry, then a normal <code>npm install A</code> will install:</p>
<pre><code>A@0.1.0
`-- B@0.0.1
    `-- C@0.0.1
</code></pre><p>However, if B@0.0.2 is published, then a fresh <code>npm install A</code> will
install:</p>
<pre><code>A@0.1.0
`-- B@0.0.2
    `-- C@0.0.1
</code></pre><p>assuming the new version did not modify B&#39;s dependencies. Of course,
the new version of B could include a new version of C and any number
of new dependencies. If such changes are undesirable, the author of A
could specify a dependency on B@0.0.1. However, if A&#39;s author and B&#39;s
author are not the same person, there&#39;s no way for A&#39;s author to say
that he or she does not want to pull in newly published versions of C
when B hasn&#39;t changed at all.</p>
<p>In this case, A&#39;s author can run</p>
<pre><code>npm shrinkwrap
</code></pre><p>This generates <code>npm-shrinkwrap.json</code>, which will look something like this:</p>
<pre><code>{
  &quot;name&quot;: &quot;A&quot;,
  &quot;version&quot;: &quot;0.1.0&quot;,
  &quot;dependencies&quot;: {
    &quot;B&quot;: {
      &quot;version&quot;: &quot;0.0.1&quot;,
      &quot;dependencies&quot;: {
        &quot;C&quot;: {
          &quot;version&quot;: &quot;0.0.1&quot;
        }
      }
    }
  }
}
</code></pre><p>The shrinkwrap command has locked down the dependencies based on
what&#39;s currently installed in node_modules.  When <code>npm install</code>
installs a package with an <code>npm-shrinkwrap.json</code> in the package
root, the shrinkwrap file (rather than <code>package.json</code> files) completely
drives the installation of that package and all of its dependencies
(recursively).  So now the author publishes A@0.1.0, and subsequent
installs of this package will use B@0.0.1 and C@0.0.1, regardless the
dependencies and versions listed in A&#39;s, B&#39;s, and C&#39;s <code>package.json</code>
files.</p>
<h3 id="using-shrinkwrapped-packages">Using shrinkwrapped packages</h3>
<p>Using a shrinkwrapped package is no different than using any other
package: you can <code>npm install</code> it by hand, or add a dependency to your
<code>package.json</code> file and <code>npm install</code> it.</p>
<h3 id="building-shrinkwrapped-packages">Building shrinkwrapped packages</h3>
<p>To shrinkwrap an existing package:</p>
<ol>
<li>Run <code>npm install</code> in the package root to install the current
versions of all dependencies.</li>
<li>Validate that the package works as expected with these versions.</li>
<li>Run <code>npm shrinkwrap</code>, add <code>npm-shrinkwrap.json</code> to git, and publish
your package.</li>
</ol>
<p>To add or update a dependency in a shrinkwrapped package:</p>
<ol>
<li>Run <code>npm install</code> in the package root to install the current
versions of all dependencies.</li>
<li>Add or update dependencies. <code>npm install</code> each new or updated
package individually and then update <code>package.json</code>.  Note that they
must be explicitly named in order to be installed: running <code>npm
install</code> with no arguments will merely reproduce the existing
shrinkwrap.</li>
<li>Validate that the package works as expected with the new
dependencies.</li>
<li>Run <code>npm shrinkwrap</code>, commit the new <code>npm-shrinkwrap.json</code>, and
publish your package.</li>
</ol>
<p>You can use <a href="../cli/npm-outdated.html">npm-outdated(1)</a> to view dependencies with newer versions
available.</p>
<h3 id="other-notes">Other Notes</h3>
<p>A shrinkwrap file must be consistent with the package&#39;s <code>package.json</code>
file. <code>npm shrinkwrap</code> will fail if required dependencies are not
already installed, since that would result in a shrinkwrap that
wouldn&#39;t actually work. Similarly, the command will fail if there are
extraneous packages (not referenced by <code>package.json</code>), since that would
indicate that <code>package.json</code> is not correct.</p>
<p>Since <code>npm shrinkwrap</code> is intended to lock down your dependencies for
production use, <code>devDependencies</code> will not be included unless you
explicitly set the <code>--dev</code> flag when you run <code>npm shrinkwrap</code>.  If
installed <code>devDependencies</code> are excluded, then npm will print a
warning.  If you want them to be installed with your module by
default, please consider adding them to <code>dependencies</code> instead.</p>
<p>If shrinkwrapped package A depends on shrinkwrapped package B, B&#39;s
shrinkwrap will not be used as part of the installation of A. However,
because A&#39;s shrinkwrap is constructed from a valid installation of B
and recursively specifies all dependencies, the contents of B&#39;s
shrinkwrap will implicitly be included in A&#39;s shrinkwrap.</p>
<h3 id="caveats">Caveats</h3>
<p>If you wish to lock down the specific bytes included in a package, for
example to have 100% confidence in being able to reproduce a
deployment or build, then you ought to check your dependencies into
source control, or pursue some other mechanism that can verify
contents rather than versions.</p>
<h2 id="see-also">SEE ALSO</h2>
<ul>
<li><a href="../cli/npm-install.html">npm-install(1)</a></li>
<li><a href="../files/package.json.html">package.json(5)</a></li>
<li><a href="../cli/npm-ls.html">npm-ls(1)</a></li>
</ul>