Skip to content
RU

The npm supply chain in 2026: what was measured, and what is spam

TL;DR. In December 2025 npm revoked every long-lived token — the measure the whole effort after that year’s attacks was built around.

In December 2025 npm revoked every long-lived token — the measure the whole effort after that year’s attacks was built around. It worked. And two of the three worm campaigns of 2026 bypassed it entirely, abusing trusted publishing via OIDC: the very control introduced in its place.

Below: the measured figures — 220,139 malicious packages in the open dataset, three quarters of last year’s turning out to be one spam campaign; the absence of classic typosquatting from the 2026 data; and our own measurement of whether what gets found actually gets removed.

Registry size and download volume

On 27 August 2026 we queried the counters directly:

MeasureValueWhat it is
Packages in the registry4,334,379documents in the replica, placeholders and unpublished included — an upper bound
Downloads in a month601,025,022,14627 Jul – 25 Aug 2026
Downloads in a day37,969,071,48125 Aug 2026

Downloads are not people or organisations. This is request volume against the registry, dominated by build pipelines re-pulling. Sonatype states the same outright: downloads are "a consumption signal, not a proxy for unique users".

Registry growth through 2026 runs at roughly 2,470 packages a day net. "Net" matters: in the second half of 2023 the counter fell by 650,000 as npm purged spam. Publishing cannot be separated from deletion in the public data.

Malicious packages: 220 thousand, but three quarters of last year’s are one spam run

The open OSV dataset holds 220,139 records of malicious npm packages. By year of publication:

YearRecordsExcluding bulk campaigns
20227,4247,424
20232,2912,291
20248,3728,372
2025191,42046,148
2026 (to 27 August)10,62710,627

The 191,420 for 2025 is a trap, and must not be quoted without the caveat. Around 140,000 records fall in four days of November and belong to a single spam campaign: packages with auto-generated names published to inflate reputation scores in a third-party token scheme. The OSV records say so themselves.

Sonatype independently describes the same campaign from a different corpus — 169,538 packages "designed to self-replicate every seven seconds". Two measurements, one campaign.

Cleared of those spikes the picture is smaller and more informative: through 2026, roughly a thousand records a month, rising within the year — 329 in February, 2,984 in August.

For scale: PyPI shows 1,298 records for 2026 against npm’s 10,627 — an eightfold gap.

Classic typosquatting is absent from the 2026 data

We analysed all 10,627 names flagged in 2026. The result is unexpected:

PropertyResult
Names without a scope (@org/)7,609 (71.6%)
Scoped names3,018 (28.4%), across 1,078 distinct scopes
One letter away from a popular package0 of 7,609
Containing a popular package name as a substring848 (7.98%)

Instead of impersonating lodash or express, the dominant pattern is seizing a whole namespace: @antv with 279 records, @servicetitan 141, @cloudplatform-single-spa 122, @mastra 89, @uipath 66.

Those scopes match the year’s known victims exactly. Which follows if the mechanism is: steal access, enumerate everything the account may publish, republish all of it.

Limits of the conclusion: the comparison list held 54 popular names, and "one letter away" is a narrow definition that misses transposition, brand impersonation and compound names. Read this as "in 2026 the threat looks different", not as "typosquatting no longer happens".

The defence worked — and was bypassed through the very control introduced to defend

After the 2025 attacks npm tightened up, and the sequence matters:

DateChange
5 Nov 2025new classic tokens blocked, granular tokens capped at 90 days
9 Dec 2025all existing classic tokens revoked; login issues a two-hour session; two-factor required for publishing
8 Jul 2026npm 12: lifecycle scripts (preinstall, postinstall) off by default

The measures work: the long-lived tokens exploited in 2025 no longer exist.

And yet two of the three worm campaigns of 2026 bypassed them entirely. The mechanism is abuse of trusted publishing via OIDC — precisely the control introduced in place of tokens. The analysis of the May campaign states it plainly: "every previous wave began with a stolen credential; this one did not". Instead of stealing an account it used a misconfigured build workflow and poisoned its cache.

An unwelcome but important conclusion: killing long-lived tokens did not remove the threat but moved it one floor up — into the build systems that now hold the trust.

The June campaign took that logic to its limit: the substituted versions were published carrying valid provenance attestations. The signature was genuine, because a compromised pipeline signed it.

A 2026 timeline with verified dates

Every event below was cross-checked against OSV records.

  • 30–31 March, axios. The compromised version was live for about three hours. The vector was not account phishing: per the maintainers’ own post-mortem, access was gained to the lead developer’s computer through targeted social engineering and remote-access malware.
  • 11–12 May. The worm was published on GitHub under a permissive licence — becoming available to anyone. It bypassed the defences via OIDC.
  • 1 June, 32 Red Hat packages. The vector was account compromise through a malicious code editor extension. Red Hat’s bulletin names 32 packages, and OSV holds exactly 32. Two independent sources agreeing to the unit.
  • 4 August, keyv and related. Package counts differ across sources — "over 400" from some, "over 1,300 versions" from others. They must not be added: one counts packages, the other versions.

And a sobering detail from 2025. The loudest attack of September 2025, reaching packages with hundreds of millions of weekly downloads, was live about two hours and earned its operators, by independent measurement, roughly five cents of ETH plus twenty dollars of a memecoin. The write-up is titled "Oops, No Victims".

Separately on historical events that are routinely retold wrongly: left-pad (2016) was an availability failure, not an attack — no malicious code was ever involved; and xz-utils (2024) has nothing to do with npm — it is a Linux compression library.

Why vendor figures differ by an order of magnitude

For calendar 2025, on npm:

SourceMalicious packages
ReversingLabs10,819
Datadog13,994
OSV, spam removed~14,000–46,000
OSV, as published191,420
Sonatype (all ecosystems)454,648

The first three agree within a third — the spread to the rest is definitional, not empirical. OSV counts packages, Datadog counts versions; some include spam and others do not; Sonatype blends all registries.

On the headline "malware grew 75%": that is growth of the cumulative total between two report editions fifteen and a half months apart, not year-on-year growth of new detections, which on a comparable base is about 6%. And by Sonatype’s own taxonomy, 83.4% of that 454,648 is spam and junk rather than an attack payload.

The general rule: every such figure is one vendor’s detection capability on that vendor’s corpus. It is a lower bound, not a rate. Nobody publishes a rate, because the denominator is unknown.

Who actually finds them: in the open 2026 dataset, Amazon Inspector (18,026 reports) and GitHub (6,094). Socket, Snyk and Sonatype contribute nothing to it.

Is what gets found actually removed — our measurement

We took 200 packages flagged malicious in 2026 and queried each in the registry. 194 answer 200 and six answer 404. But a 200 does not mean the malware is still there: inspecting sixty of them gives:

StatePackagesMeaning
npm placeholder26 (43%)content replaced with a security-holding marker
Unpublished24 (40%)no versions remain
Live legitimate package10 (17%)a compromised project cleaned and restored

We found no case where the malware is still installable. The ten "live" ones are exactly the affected namespaces such as @qlik and @antv, restored after cleanup.

Caveat: sixty of two hundred were inspected, and we did not diff version histories to confirm the specific infected versions are gone. The claim is "removal appears complete", not "removal is guaranteed complete".

The adjacent subject — dependency depth — is covered in a separate article.

Sources: the OSV/OpenSSF open dataset, the npm registry replica, the download counter, the npm 12 changes.

Frequently Asked Questions

Is npm audit enough?

Minimum. Snyk / Socket.dev / GitGuardian add behavioral analysis + zero-day detection.

How to defend against typosquatting?

package.json reviews in PR, npm install --ignore-scripts (block post-install hooks), allowlists in a registry proxy.

Is SBOM mandatory?

US federal contracts — yes (EO 14028). Enterprise SaaS — often requested. 2026 best practice.

Try the live tool that powered this guide

Free plan — 10 monitors, checks every 5 min, no card required. Upgrade for 1-minute interval and multi-region monitoring.