npm-rot
v0.1.0
Published
Find npm packages a lot of people depend on and nobody maintains. Ranks by downloads against staleness and what users are asking for in the issue tracker — because an unclaimed name is usually an unwanted one, and a stuck audience is a measured one.
Downloads
170
Maintainers
Readme
npm-rot
An unclaimed name on npm is usually an unwanted one.
Looking for something to build by checking which names are free is backwards. It finds empty niches and unwanted ones without telling them apart, and they look identical from the registry.
The signal that means something is the opposite: a package with real downloads, a maintainer who stopped, and users saying so in the issue tracker. That is a measured audience with a measured complaint.
npx npm-rot --deps ./package.jsonpackage weekly idle asks top score
------------------------------------------------------------------
bottleneck 10,456,378 31mo 1 14 44.4
ReplyError: ERR SETTINGS_KEY_NOT_FOUND in clustering mode
idle = months since the last commit
asks = open issues asking whether it is still maintained
top = reactions on the most-wanted open issueWhat it looks at
For every package name you give it: weekly downloads, when it was last published, when the repository was last pushed, whether it is archived, how many open issues ask some form of "is this still maintained?", and how many reactions the most-wanted open issue has.
Then it ranks by reach × how stuck people are, with downloads on a log scale — the difference between ten thousand users and a hundred thousand matters far less than the difference between having a maintainer and not.
Staleness is a precondition, not a signal
The first version of the score ranked age × downloads. Its top results were
ansi-colors, acorn-jsx and abort-controller: enormously popular, years
past their last commit, and nobody stuck on any of them.
They are not abandoned. They are finished. A small package that does one thing correctly stops changing, and silence around it means it still works.
So a candidate now has to show that someone is actually stuck — an issue asking whether the project is alive, a lot of reactions on something nobody answered, or an archived repository. Old and quiet scores zero.
It says what it could not see
WARNING: 812 of 1,551 packages had an unreadable issue tracker (rate limit,
private, moved). Their signals are missing, so a short list here means
less than it looks like.This exists because the tool got it wrong on its own first real run. Scanning 1,551 packages exhausted the GitHub rate limit halfway through; every lookup after that failed, every failure was swallowed into "no issues found", and the report confidently listed two candidates. It had not found two. It had stopped looking.
A tool that cannot tell "nobody is complaining" from "I never checked" will hand you a clean result either way, and a clean result is what you were hoping for — so nobody looks twice. Failed lookups are now counted and reported, and they score zero rather than counting as evidence of quiet.
Run gh auth login first and the limit goes from 60 requests an hour to 5,000.
Use
npm-rot --deps ./package.json # your own dependencies
cat names.txt | npm-rot # a list you brought
npm-rot --deps ./package.json --json # for a script--deps <file> read names from a package.json
--min-downloads <n> ignore anything below this per week (default 1000)
--limit <n> how many to show (default 25)
--concurrency <n> parallel lookups (default 6)
--json machine-readablePointing it at your own package.json answers a different and more immediate
question than the one it was built for: which of the things you already depend
on has nobody behind it.
What it does not do
It does not tell you a package is bad. Unmaintained and broken are different things, and most of what it surfaces will be neither — a maintainer can be absent from a package that works perfectly.
It only reads GitHub. GitLab, Codeberg and self-hosted repositories come back with no issue signals at all, which the report counts as unchecked rather than quiet.
It cannot see private discussion. A maintainer handing over by email leaves no trace in the tracker, so a package can look abandoned and have a successor. Check before you act on it.
Built with Claude
Claude wrote most of this code. The design is mine, and it came out of getting the underlying question wrong first: several packages built after finding free names on npm, none of which anyone needed, and one built after finding ten million weekly downloads asking for a maintainer — which was the only one worth building.
Licence
MIT.
