Implera is currently offline. The blog stays up.
Back to insights

Insights

Keeping Your Dependency Supply Chain Healthy

In 2018 a maintainer of event-stream, an npm package with two million weekly downloads, handed the project over to a stranger who added a malicious dependency that stole cryptocurrency wallets. The compromised version sat on npm for two months before anyone noticed. The original maintainer was not paid for the work, was tired, and transferred ownership to the first person who asked.

Every team running a Node.js app was exposed. Most did not know the package existed because it was a transitive dependency pulled in via something else they actually did choose.

This is the dependency supply chain problem. You do not choose most of your dependencies. They are chosen for you by the libraries you actually picked.

The numbers

A fresh create-react-app project installs over 1,400 packages. A minimal Next.js app pulls around 300. Even a small Express API is upwards of 200. These are not outliers; this is normal.

Each package is code that runs at build time or at runtime. Each maintainer is a human who might sell the package, lose interest, be compromised, or simply make a mistake. You have extended trust to all of them the moment you installed the top-level package.

Dependency health is about managing that trust.

What a healthy supply chain looks like

  • You know what you install. Every direct dependency is chosen deliberately. Every transitive one has at least been glanced at.
  • You lock versions. package-lock.json or yarn.lock is checked in. Every install is deterministic.
  • You scan continuously. Vulnerabilities in dependencies are detected within hours, not months.
  • You update regularly. Updates happen in small batches, not six-month catchups.
  • You prune. Unused dependencies are removed, not kept "in case".
  • You know the licences. Nothing GPL-licensed snuck into a proprietary product.

That is the baseline.

The most common failures

Unused dependencies left in package.json. Every team has them. A project pinning five versions of packages it does not import costs nothing at runtime but signals that nobody owns the manifest. When someone eventually audits it, they find 30% can go.

Lockfile ignored or regenerated on every install. Without a lockfile, npm install today and tomorrow produce different package sets. Reproducibility disappears. Bug reports become non-deterministic.

Transitive vulnerabilities invisible. The team runs npm audit once, sees nothing actionable, never looks again. Six months later 40 moderate findings are accumulated, and someone is going to spend a day chasing them.

Updates done in one enormous PR. "Update all dependencies" every nine months. The PR touches 800 lines of package-lock.json, half the app breaks, someone spends a week on it. Nobody else dares to touch dependencies after.

Licence changes unnoticed. A dependency changes licence in a minor version update. The new licence is incompatible with your distribution. You find out when a customer's lawyer asks.

What works

Three practices that keep the supply chain healthy without drama.

  1. Automated scanning on every PR. Tools like Snyk, Dependabot, Renovate or OSV-Scanner run on every push. They flag new vulnerabilities as they appear, not six months later. Combine with a policy: high-severity findings block merge, medium findings get filed, low findings get batched.
  2. Small update batches. Renovate can open a PR per dependency update. The PRs are small, each is reviewable, most merge within a day. Boring maintenance, which is the point.
  3. Periodic pruning. Once a quarter, run depcheck or equivalent and remove unused deps. Review direct dependencies for "why do we have this?". Half an hour of work saves real attack surface.

Red flags in a dependency

You do not need to audit every package by hand. A few heuristics catch most problems.

  • No release in 12+ months on a security-sensitive package. Maintenance has stopped.
  • Single maintainer on a widely-used package. High bus factor. High takeover risk.
  • Package name looks like a typo of a popular package (typosquat). reqeust is not request.
  • Install scripts that run curl or eval. Vanishingly rare legitimate reason. Common in compromises.
  • Licence change across minor versions. Should never happen. If it does, investigate.

If something fails two or more of these checks, treat it with suspicion.

The principle

Your dependencies are part of your codebase. You did not write them, but you ship them. You are responsible for what they do.

Most teams treat dependencies as an invisible layer and then act surprised when one of them ships a backdoor. A healthy supply chain is not about paranoia; it is about paying the same attention to imported code as you do to code you wrote.

It is unglamorous work. It is also the thing that separates teams that get compromised from teams that do not.

FAQ

Common questions

© 2026 Implera