Stack Signal.
Technical news & guides across AI, programming and the open-source world
MONDAY, SEPTEMBER 28, 2026 · 60 articles · RSS

Programming & Web DevSep 28, 2026685 words
🕰 Archive · covers 2016

Left-pad and the day 11 lines of code broke the JavaScript ecosystem

Left-pad and the day 11 lines of code broke the JavaScript ecosystem

Some supply-chain incidents are quiet and technical. The left-pad incident of March 2016 was neither. In the space of a few hours, one developer removing a handful of tiny packages from npm caused fresh installs and build pipelines to fail for thousands of JavaScript projects around the world — not because the code was malicious, but because it simply stopped existing.

What actually happened

The trigger was a package-name dispute, not a bug. Azer Koçulu, a prolific author of small single-purpose npm modules, had published a package called kik. The messaging company Kik Interactive wanted the name for its own open-source work and complained to npm. npm applied its dispute policy and transferred the kik package name to Kik Interactive. Koçulu disagreed and, on March 22, 2016, unpublished all 273 of his packages from the registry in protest.

One of those packages was left-pad — a roughly 11-line function that pads the left-hand side of a string with spaces or zeroes. It was trivial, practically a single line of logic any engineer could write, and exactly because of that it had crept deep into the dependency tree of widely used tooling. Babel brought it in through a package called line-numbers, and from there it propagated into countless projects built on Babel, Webpack, React, and Node.

When left-pad vanished, every fresh npm install and every build that tried to resolve it hit a 404 error and failed.

The fallout

The blast radius was enormous for such a small package. It had been downloaded millions of times in the month before the removal, and companies including Facebook, PayPal, Netflix, and Spotify found it in their dependency chains. npm reported observing hundreds of failures per minute shortly after 2:30 PM Pacific on March 22.

The recovery exposed a second problem. Within about ten minutes another developer, Cameron Westland, stepped in and republished a functionally identical left-pad as version 1.0.0. But many dependency chains pinned version 0.0.3 explicitly, and npm's rules at the time forbade republishing a version that had been unpublished. Those pinned chains stayed broken. npm eventually took what its own CTO called the "unprecedented" step of restoring left-pad@0.0.3 from backup to stop the bleeding.

What changed afterward

npm tightened the exact mechanism that made this possible. Newer packages could still be unpublished within a grace period, but npm stopped allowing an automated unpublish of a package older than 24 hours once other projects depended on it — removal from that point required review, and removal that would break dependent installs was blocked.

The incident also changed how the industry thought about dependencies. It became a reference point for debates about tiny single-purpose packages, about "shadow" dependencies that projects inherit without realizing it, and about relying on a registry to keep a critical dependency alive. It reinforced the value of pinning exact versions and committing lockfiles, and it made many teams look more carefully at how much of their supply chain they actually understood.

The bigger lesson

Today left-pad is routinely cited alongside later supply-chain events — the 2021 compromise of Codecov's Bash Uploader, where an attacker exfiltrated credentials from CI environments for months, and the recurring PyPI typosquatting campaigns that slip malicious packages in under names similar to trusted ones. What links them is a shared truth that the left-pad incident made vivid in 2016: the health of almost any modern product depends on a long, mostly invisible chain of code written and maintained by people you have never met.

Nothing about left-pad was a vulnerability in the traditional sense — there was no flaw in the code, only its absence. That is what made it instructive. It showed that a dependency does not have to be attacked to become a risk. It can simply vanish, and everything built on top of it falls with it. Trusting a dependency responsibly, it turns out, means understanding not just what it does, but how easily it could be taken away.

A look at how the JavaScript ecosystem keeps learning these lessons