title: Best Practices for Maintaining and Updating Large, Private NPM Package Ecosystem
body: <h2>What is the easiest/best way to maintain and keep up-to-date NPM packages in a large, internal ecosystem?</h2>
  <p>Say we have a number of different private NPM packages, each a project with its own repository, that are consumed in a tree-like fashion. Note that this diagram is a very simplified version of the problem for discussion purposes. The actual dependency tree is easily 10x this complex. <strong>If you need to make a change to a low-level package, what is the best/easiest way to update the rest of the tree?</strong></p>
  <p><a href="https://i.stack.imgur.com/PGfm2.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/PGfm2.png" alt="Nested Dependencies Example" /></a></p>
  <ul>
  <li>The top-level green boxes represent our front-end websites.</li>
  <li>The mid-level blue boxes represent intermediate packages which are
  consumed by the top-level websites, and also consume other low-level
  packages.</li>
  <li>The low-level orange boxes represent packages which get
  consumed by other packages and websites.</li>
  </ul>
  <h2>Example: Breaking Change to a Low-Level Package</h2>
  <p>We'll assume all of these packages are currently on v1.0.0 for the sake of this example. To update @adc/package-1, one must:</p>
  <ul>
  <li>Make the changes in @adc/package-1 and publish the new version (v2.0.0)</li>
  <li>Update the mid-level packages to consume @adc/package-1@^2.0.0.</li>
  <li>Publish new versions of the mid-level packages (i.e. @adc/package-2@1.0.1, @adc/package-3@1.0.1, @adc/package-4@1.0.1)</li>
  <li>Update the top-level websites to consume all new versions of the packages.</li>
  </ul>
  <p>This in total requires six PRs, since each package is its own repository. Most of these updates are just updating the version numbers. It also requires that the PRs are merged in a particular order. This is a lot of overhead for a simple change, and again this is very simplified in comparison to the actual package ecosystem that may exist.</p>
  <h3>What happens if we don't update the mid-level packages?</h3>
  <p>The top-level websites will now be using two different versions of @adc/package-1.</p>
  <ul>
  <li>@adc/package-1@^2.0.0 via its package.json direct dependency</li>
  <li>@adc/package-1@^1.0.0 via a transient dependency through the mid-level packages.</li>
  </ul>
  <p>I believe this can lead to non-deterministic behavior, and it also makes it difficult for the next developer to know what versions they can/should use if they need to make an update. The mid-level packages would become out-of-date and eventually it would require us to update all @adc/ package versions to the latest. In a world where you try to mitigate risk, this would mean regression testing the entire package and all consuming packages/websites.</p>