Originally published on the depproof blog. Measured 10 September 2026 across 24 pinned public repositories, 8,943 components, five ecosystems. Every source used is free and public.
The standard remediation for a vulnerable dependency is to upgrade it. That advice quietly assumes a maintainer exists, noticed, and shipped a release.
For most packages it holds. For some it does not, and nothing in a normal findings report tells you which kind you are looking at.
About one component in seven in our sample carries a signal that nobody is maintaining it: 1,202 of 8,943, or 13.4%.
| Where the signal comes from | Components | Share of signals | |---|---:|---:| | Somebody said so. Deprecation flag, archived repository, published end-of-support date. | 242 | 20.1% | | We inferred it. Four years since the last release, and no repository activity either. | 960 | 79.9% |
Four signals in five are an inference from silence. That is the honest shape of thismeasurement, and it is where the fair objection lives: a library can go four years without a release because it is finished, not because it was abandoned. Small, single-purpose packages do exactly that.
We think the inference still earns its place, for one reason. The question a maintenance signal answers is not is this package bad. It is if an advisory lands against this tomorrow, is a fix coming. A finished library and an abandoned one give the same answer, and it is the answer you need during an incident rather than a verdict on anybody's work.
For years this was one of the most depended-upon packages in JavaScript. Its maintainers formally deprecated it, which is a deliberate statement rather than an inference. Nobody in this project chose it: it arrives four levels down, underneath something else. The advisory against it has no fix version, because there will not be another release.
There is no upgrade to recommend. The only real options are to replace whatever pulled it in, or to write down that you accept it.
Twenty-four public repositories, pinned to fixed commits and rebuilt locally, across Maven, Gradle, npm, PyPI and Go. For every resolved component we asked three open sources what they knew: deps.dev — release history and npm deprecation OpenSSF Scorecard — project activity endoflife.date — published support windows
Those feed a ladder of five rules, applied in order, first match winning. The order matters: a maintainer's own declaration should outrank anything we merely observed.
| | Rule | Kind | Components | |---|---|---|---:| | 01 | The package is deprecated. The maintainer marked it so. | stated | 65 | | 02 | The repository is archived. A deliberate act, not a guess. | stated | 125 | | 03 | This release line is past its published end of support, even where the project thrives. | stated | 24 | | 04 | Four years since the last release, and no sign of commits. Both halves required. | inferred | 960 | | 05 | This particular release is deprecated, though newer ones are not. | stated | 28 |
Rule 4 deliberately requires both an old release and a quiet repository, because release age alone marks every finished library as abandoned. Where the Scorecard has no data the second half cannot be applied and the rule falls back to release age by itself. That affected 82 of its 960 components, so roughly 9% of the largest rule rests on the weaker evidence.
| Ecosystem | Carrying a signal | Components | Share | |---|---:|---:|---:| | npm | 852 | 5,650 | 15.1% | | Go | 226 | 1,614 | 14.0% | | Gradle | 90 | 756 | 11.9% | | Maven | 13 | 237 | 5.5% | | PyPI | 21 | 686 | 3.1% |
The npm figure reflects deep transitive trees in two large JavaScript projects. The mix here is ours, not yours.
The obvious way to dismiss all of this is to assume abandoned packages cluster in build and test dependencies, where nobody much cares. We can check that, because every resolved dependency carries the scope it was declared under.
| Reaches production | Carrying a signal | Components | Share | |---|---:|---:|---:| | Ships | 659 | 4,698 | 14.0% | | Build and test only | 372 | 2,750 | 13.5% | | Undetermined | 171 | 1,332 | 12.8% |
It does not cluster. The rate is flat. Whatever causes a package to be abandoned has nothing to do with whether you ship it. Your production dependencies are not the well-tended ones. They are tended exactly as well as your test tooling, which is to say nobody checked either.
