Pick the maintenance signal you can get in one second: days since the last release.
I pulled it from the npm registry for 18 ESLint plugins on 2026-08-12. The three with the deepest install base are the three that have gone quietest.
| plugin | days since release | releases in 12mo |
|---|---|---|
| eslint-plugin-jsx-a11y | 655 | 0 |
| eslint-plugin-react | 495 | 0 |
| eslint-plugin-import | 417 | 0 |
| eslint-plugin-promise | 107 | 1 |
| eslint-plugin-security | 61 | 2 |
| eslint-plugin-sonarjs | 28 | 9 |
| eslint-plugin-unicorn | 8 | 17 |
| eslint-plugin-n | 3 | 12 |
| eslint-plugin-jest | 0 | 35 |
Nine of the eighteen I measured shipped nothing at all in the last twelve months. Nearly two years of silence on the plugin that half the accessibility tooling in React depends on.
Dormant is not dead
Before drawing the obvious conclusion, the honest caveat: a plugin that stops releasing may simply be finished. jsx-a11y encodes WAI-ARIA rules. ARIA does not change every quarter. A stable spec produces a stable plugin, and "no releases" is the correct output for a package with nothing left to do.
So days-since-release is a prompt, not a verdict. Three signals actually separate finished from abandoned, and all three are free:
1. The npm deprecation flag. eslint-plugin-standard carries one. That is the maintainer telling you directly, and it is machine-readable — no interpretation required.
2. Supersession. eslint-plugin-node last shipped 2,328 days ago — over six years — because it was replaced by eslint-plugin-n, which shipped 3 days ago. One of those numbers is alarming and the other explains it. A rename is invisible to anyone reading only the old package's page.
3. Whether it still works on your ESLint. This is the one that matters and the one nobody checks until it breaks. A plugin frozen before flat config became the default is not "stable," it is on a countdown.
The genuinely dead tier
Sorted by silence, these are the ones where no reading rescues the number:
eslint-plugin-scanjs-rules 3,296 days (9 years)
eslint-plugin-node 2,328 days superseded by eslint-plugin-n
eslint-plugin-standard 2,088 days npm-deprecated
eslint-plugin-flowtype 1,748 days Flow itself receded
eslint-plugin-xss 1,507 days
eslint-plugin-security-node 951 days
Every one of these still installs cleanly today. npm will not warn you, your lockfile will not warn you, and a config that references them keeps passing — because a plugin whose rules never fire looks exactly like a codebase with no problems. That is the same failure shape as a CI check that was disabled rather than failing: silence reads as success.
The one that came back
eslint-plugin-security is the interesting row. It went 3.0.1 in June 2024 → nothing for 20 months → 4.0.0 in February 2026, and shipped again in June. If you had measured it in January you would have called it abandoned, correctly, and been wrong by March.
That is why a claim needs an expiry date rather than a verdict. "Unmaintained" is not a property of a package. It is a measurement with a date on it, and this one moved.
Measure your own config
Do not use time.modified for this. It is the obvious field and it is the wrong one: npm bumps it on any metadata change, so deprecating a package or transferring ownership makes a dead package look freshly touched. eslint-plugin-flowtype reports time.modified of 2026-01-24 — seven months ago, apparently maintained. Its last actual release was 2021-10-29. That is the 1,748-day row above, and the gap between the two fields is 1,548 days of false reassurance.
Read the publish date of the current version instead:
npm view <plugin> version # e.g. 8.0.3
npm view <plugin> time.8.0.3 # the date that version shippedOr resolve the whole set at once:
node -e "for (const p of Object.keys(require('./package.json').devDependencies ?? {})) \
fetch('https://registry.npmjs.org/'+p).then(r=>r.json()) \
.then(j => console.log(p, j.time[j['dist-tags'].latest].slice(0,10)))"Then apply the three checks above to anything past a year. Most will be fine. The point is knowing which ones you are betting on — eslint-plugin-import at 417 days is a dependency worth having an opinion about, given what it does on every lint run.
All figures resolved from the npm registry on 2026-08-12 and already drifting — eslint-plugin-jest was at 0 days when I measured it. Re-run the one-liner rather than citing mine.
Source at github.com/ofri-peretz/eslint · packages at npmjs.com/~ofriperetz · more at dev.to/ofri-peretz.
What's the oldest plugin in your lockfile — and did you know it before you looked?
