The Adoption Read Standard: When an Open-Source Trend Holds Up
You will grade any open-source adoption read against fixed criteria and return the same publish, fix, or kill verdict as a colleague grading it independently.
Key takeaways
- Stars measure attention, downloads measure access, and dependents measure integration - Anthropic SDK's 3.3K stars against 103.8M downloads a month shows a single-signal read can be off by 100x.
- The stars-to-downloads correlation is language-dependent, running from 0.47 in PHP down to 0.14 in JavaScript, so a threshold valid in one ecosystem is invalid in another.
- Around 15.8% of repos with over 50 stars in July 2024 were tied to fake-star campaigns, which makes a star-authenticity check mandatory above that threshold, not optional.
- npm does not filter automated downloads by design, and each version pull draws roughly 100 to 150 automated downloads, letting one campaign manufacture 50,000 in three days.
- Job-market skill counts are corroboration a star-buying campaign cannot move: in Refolk's index, US backend engineers listing Rust number 599 against 89 in Germany, a 6.7x gap.
- A read passes only when at least three independent signals agree, no load-bearing signal is stale, and two graders return the same verdict.
This is the acceptance standard for an open-source adoption read: the finished estimate you build on a technology or library before it enters a strategy deck. It is for strategy and research teams, talent-intelligence analysts, and operators sizing a market. It gives you fixed criteria and a checklist so two people grading the same read return the same verdict - publish, fix, or kill - instead of arguing about whether stars count.
Other guides in this library tell you how to read one signal, place a category on its adoption curve, size a pool, and spot manufactured momentum. This one defines when the finished read is done. It is the gate the number passes through, not the method for building it.
What "done" means for an adoption read
An adoption read is done when it makes a falsifiable claim, carries at least three independent signals that agree, survives a star-authenticity and download de-noising pass, contains no stale load-bearing signal, and earns the same verdict from two graders working separately. Anything short of that is a draft.
The verdict is one of three words, and they are exhaustive:
- Publish - the claim is scoped, corroborated by three independent signals, de-noised, fresh, and two graders agree. The number can go in front of leadership.
- Fix - the claim is defensible in shape but one criterion fails: a signal is stale, downloads are not de-noised, or corroboration is thin. Named, fixable work.
- Kill - the claim rests on a single signal, that signal is manufactured or contaminated, or the direction reverses once you de-noise. Do not cite it.
The whole point of a standard is that the word is reproducible. If your teammate reads the same evidence and the same criteria, they should land on the same word. Where the dossier leaves a threshold unset, I say so and tell you what to fix it at, because a standard that overclaims is worse than none.
Why one signal is never enough
Stars, downloads, and dependents measure three different things, and they diverge by orders of magnitude, so a read anchored on any one of them can be wrong by a factor of a hundred. Each signal proves something narrow, and treating it as proof of adoption is the most common way these reads fail.
Here is what each signal actually proves, and what it looks like when it lies:
- Stars prove attention. A developer noticed and bookmarked. They lie when a burst of coordinated or bot accounts inflates the count overnight, or when critical infrastructure is used without ever being starred.
- Downloads prove access. Something pulled the package. They lie when the puller is a mirror, a CI job, or a scanner rather than a human integrating the code.
- Dependent counts prove integration. Another codebase declared a dependency on it. This is the hardest signal to fake, because it requires real code that imports the package.
- Active-contributor breadth proves maintenance resilience. Enough distinct people ship that the project survives one person leaving.
The Anthropic SDK case is the clean illustration: 3.3K stars, 103.8M downloads a month, and 50.0K dependent repos. It is invisible infrastructure that other packages depend on rather than a project developers star. Anchor a read on stars and you conclude it is a minor project. Anchor on dependents and you see the truth.
What each signal proves, outermost to innermost
- StarsAttention. A developer noticed. Cheapest to manufacture.
- DownloadsAccess. Something pulled it, human or machine.
- DependentsIntegration. Real code imports it. Hard to fake.
- Active contributorsResilience. The project survives one person leaving.
The divergence is not a corner case. It is the normal state of a healthy ecosystem, where the most-used packages are dependencies of dependencies and rarely draw proportionate attention.
| Project | Stars | Downloads/month | Dependent repos |
|---|---|---|---|
| LangChain | top of set | 233M | 279.7K |
| Anthropic SDK | 3.3K | 103.8M | 50.0K |
| MetaGPT | 67.5K | 42K | not published |
Read that table across each row. LangChain and the Anthropic SDK sit close on downloads and dependents but nowhere near each other on stars. MetaGPT is the inverse warning: 67.5K stars, 42K downloads, a project that draws attention it does not convert into use. If you had graded MetaGPT on stars alone, you would have published a false positive.
The correlation is language-dependent, so set bands per ecosystem
Stars track real usage far better in some ecosystems than others, so a threshold you trust in PHP is worthless in JavaScript. Any defensible standard sets per-ecosystem acceptance bands rather than one global rule.
The NDSS 2024 study "The Fault in Our Stars" measured this across 925,978 data points in PHP, Ruby, and JavaScript and found a weak, uneven relationship.
| Language | Star-download correlation |
|---|---|
| PHP | 0.47 |
| Ruby | moderate, between the two |
| JavaScript | 0.14 |
Stars track downloads more than three times better in PHP than in JavaScript. That difference is why a fixed "stars over X means adoption" rule is indefensible: the same number of stars carries different evidentiary weight depending on the ecosystem. The study also found many low-star, high-download projects in PHP and Ruby, and only for client-side JavaScript did fingerprinting the Tranco Top 100,000 sites (202,077 fingerprints) show a moderate but significant link between downloads, stars, and deployments.
The practical rule: in ecosystems where the correlation is weak, downgrade stars to a discovery signal only and lean harder on dependents and de-noised downloads. A precise star value that flips the correlation is not established publicly, so do not invent one. Set your band, write it down, and move the weight to the harder-to-fake signals.
De-noising downloads: separating machines from humans
Registry download counts overstate real use because registries do not filter automated traffic, and the inflation is cheap, fast, and often deliberate. De-noising downloads is the load-bearing step, because downloads are usually the number leadership fixates on.
npm is explicit about this. Its own team states the counts are naive: it does not filter or discard automated downloads because bot filtering is hard and never fully accurate, and it is not an analytics company. It adds that only above 50 downloads a day can you be sure you are seeing signal rather than noise, and that every publish triggers a burst as all the mirrors download the new version.
That leaves two open doors. First, ordinary noise: mirrors and scanners. Second, deliberate pumping. Security researchers documented that each version uploaded to the npm public registry typically receives 100 to 150 downloads from automated systems, which let attackers reach more than 50,000 downloads in just three days simply by publishing versions.
PyPI is cleaner but not clean. Its cumulative counts exclude a known set of mirror applications - bandersnatch, z3c.pypimirror, Artifactory, and devpi - but downloads from CI/CD tools are included in all metrics. So a package with heavy CI can outrank a genuinely popular one.
Your de-noising pass, per ecosystem:
- npm - apply the 50-per-day floor, discard publish-day spikes, and note in the read that npm cannot separate CI from human installs. Normalize toward unique installers where you can.
- PyPI - use the mirror-excluded series or the event-level public dataset, and flag that CI/CD is still counted. Watch for the historical caveat that PyPI download logging under-reported by roughly 10x before late July 2018, which distorts any long baseline crossing that date.
Done looks like this: CI, mirror, and scanner traffic is either quantified as a share or excluded, and the download number in the read is the de-noised one, with the raw number kept for audit.
Detecting manufactured momentum
Fake momentum is now a scaled market, not an edge case, so a star-authenticity check is mandatory above a low star threshold rather than a nice-to-have. Skip it and you risk publishing a campaign as a trend.
The scale is documented. The StarScout study analyzed 20TB of GHArchive data - over 6 billion GitHub events from July 2019 to October 2024, including 610 million stars - and found roughly 4.5 to 6 million suspected fake stars, with fake starring surging in 2024. The sharpest number for your gate: about 15.8% of repos with over 50 stars in July 2024 were tied to fake-star campaigns, and that month's peak involved 3,216 repos and 30,779 users.
What the detectors look for, and what a real signal looks like by contrast:
- Minimal-activity accounts - users who starred a single repo and did little else. Real stars come from accounts with a history.
- Bot or temporary account patterns - fresh, short-lived accounts. Real communities skew toward established accounts.
- Coordination - account groups starring the same repos within a short window. Real growth is diffuse.
- Burst concentration - a large share of total stars landing in one brief spike. Real momentum accumulates over weeks.
Independent methods converge on this. Dagster's fake-account heuristic reported 98% precision and 85% recall on known fakes. Stargazer-sample checkers analyze three independent signals - account age distribution, star velocity, and stargazer activity - to catch coordinated campaigns. You do not need to build these; StarScout-style tooling, star-timing scripts, and bot-star detectors already exist.
The people-side signal is the one no star-buying campaign can move, which is why it belongs in every corroboration set. In Refolk's index, US backend engineers listing Rust number 599 against 89 listing it in Germany, and Go engineers outnumber Rust ones 4.6x in the US. Those counts sit entirely outside the registry, so they cannot be pumped. Refolk lets you pull that headcount in plain English and drop it in as an independent corroborating signal.
The grading procedure
Run these seven steps in order, capturing a source URL and date at every raw pull, and end with two graders returning a verdict independently. The order below is the default; some teams run the fake-star check first as a fast kill gate, and registry-first analysts de-noise downloads first because it is the load-bearing number.
From raw signals to a graded verdict
- Scope the claimState the exact technology, ecosystem, geography, and time window as a falsifiable sentence. Done when the claim reads "X is being adopted in Y over Z months," not "X is popular."
- Pull raw signalsCollect stars, registry downloads, dependent counts, contributor counts, and release cadence. Done when every signal carries a source URL and a capture date.
- De-noise downloadsFor PyPI use the mirror-excluded series or the event-level dataset; for npm apply the 50/day floor and discard publish-day spikes. Done when CI, mirror, and scanner traffic is quantified or excluded.
- Run star-authenticity checkRun a StarScout-style coordination check or a burst and velocity check. Done when the suspected-fake share and any burst dates are recorded.
- Corroborate with usage signalsConfirm dependents and active-contributor breadth move in the same direction as downloads. Done when at least three independent signals agree.
- Check freshnessVerify each signal falls inside its window and the project shipped recently. Done when no load-bearing signal is stale.
- Grade against fixed criteriaTwo graders independently return publish, fix, or kill. Done when verdicts match; if they disagree, log the disagreement and tighten the criteria.
The three-signal rule is a bar I am setting by fiat, because no numeric standard is established publicly. Practice converges on three independent signals, and I adopt that here. The signals must fail independently: de-noised downloads, dependent-repo counts, and a people-side headcount is a strong triad because a campaign that fakes one cannot touch the other two.
The verdict path
- ScopeTurn the claim into a falsifiable sentence
- De-noiseStrip mirror, CI, and scanner traffic from downloads
- AuthenticateRun the star burst and coordination check
- CorroborateConfirm three independent signals agree
- GradeTwo graders return the same verdict
How this goes wrong: failure modes and false positives
Most bad reads fail in one of seven predictable ways, and each has a specific false positive and a specific check that catches it. This is the section to keep open while you grade, because a standard is only as good as its ability to catch the errors it was built to catch.
| Failure mode | What the false positive looks like | The check that catches it |
|---|---|---|
| Stars as proxy for use | High stars, near-zero dependents (MetaGPT: 67.5K stars, 42K downloads) | Pull dependents and downloads before trusting stars |
| Publish-day spike as growth | 50 to 60 downloads on every version bump from mirrors | Exclude release-day bursts and mirror user-agents |
| CI-inflated downloads | A CI-heavy package outranking a widely-used one | Normalize per unique installer; note npm cannot separate CI |
| Fake-star burst as momentum | Hundreds of stars appearing overnight | Run velocity and coordination detection; flag one-window spikes |
| Bot contributors as growth | New-contributors chart spikes while the sole maintainer goes quiet | Apply the Contributor Absence Factor and bot filtering |
| Stale signal as current | Citing a project last shipped years ago | Confirm last release and active maintenance within the window |
| Single-signal confirmation | One strong metric, no corroboration | Require three independent signals to agree |
Two of these deserve extra weight because they are the newest and least intuitive.
AI agents break human-calibrated contributor metrics. A New Contributors chart can spike at the same moment the only maintainer goes silent, because agents now open pull requests from fresh accounts. So contributor-count growth needs bot filtering before it counts as adoption. Use the CHAOSS Contributor Absence Factor - the smallest number of people who make 50% of contributions - to see whether breadth is real or an artifact. A staleness anchor helps too: a package that last shipped years ago, lists no active maintainers, and fails a Maintained check is stale regardless of how its contributor chart looks.
Single-signal confirmation is the failure that masquerades as rigor. A read can cite one impressive, genuine number and still be indefensible, because a single signal cannot distinguish attention from access from integration. This is why the three-signal rule is non-negotiable.
A read that cites one real number is not rigorous. It is a single point of failure wearing a suit.
The acceptance checklist
Run this before you call any adoption read done. Every item must be true for a publish verdict. A single false item routes the read to fix or kill.
Adoption read acceptance checklist
- The claim is a falsifiable sentence naming technology, ecosystem, geography, and time window.
- Every raw signal carries a source URL and a capture date.
- Downloads are de-noised: npm 50/day floor applied, publish-day spikes dropped, or PyPI mirror-excluded series used.
- CI, mirror, and scanner traffic is quantified as a share or excluded, and the read states npm cannot separate CI.
- A star-authenticity check ran, with suspected-fake share and any burst dates recorded, for any repo above roughly 50 stars.
- The star acceptance band is set for the correct ecosystem, not carried over from another.
- At least three independent signals agree on trend direction, and they fail independently.
- A people-side or non-registry signal is one of the three where possible.
- No load-bearing signal is stale: last release and active maintenance fall inside the window.
- The Contributor Absence Factor and bot filtering were applied before contributor growth counted as adoption.
- Two graders returned the same verdict; any disagreement is logged and the criteria tightened.
Use this scoring skeleton to record a verdict so it is auditable later.
Claim (falsifiable): ______ is being adopted in ______ over ______ months. Ecosystem / star band used: ______ Signal 1 (de-noised downloads): value ______ | source ______ | date ______ Signal 2 (dependent repos): value ______ | source ______ | date ______ Signal 3 (people-side / non-registry): value ______ | source ______ | date ______ Star-authenticity: suspected-fake share ______ % | burst dates ______ Freshness: last release ______ | inside window? Y / N Signals agreeing on direction: ______ of 3 Grader A verdict: publish / fix / kill Grader B verdict: publish / fix / kill Disagreement logged / criteria tightened: ______
Fill one per read; keep it with the deck slide so any reviewer can reconstruct the grade.
Keeping the standard current
Re-check the standard's own thresholds on a schedule, because the numbers that anchor it move as the ecosystem changes. The mechanism matters more than any current value: fake starring surged in 2024, agent-driven pull requests are reshaping contributor metrics, and registries still do not filter automated traffic by design.
Three things to re-verify periodically rather than trusting the figure here forever:
- The fake-star base rate. The 15.8% figure is a July 2024 snapshot. Re-pull the current share of high-star repos tied to campaigns before you decide where to set your mandatory-check threshold.
- Per-ecosystem correlations. The 0.47-to-0.14 spread came from one study across three languages. If you work in an ecosystem it did not cover, treat stars as a discovery-only signal until you have your own correlation.
- Your download de-noising rules. npm's 50-per-day floor and PyPI's mirror list are documented policy, but registry behavior changes. Confirm the mirror-exclusion list and any logging caveats each time you build a long baseline.
The corroborating people-side signal is the most durable part of the read, precisely because it lives outside the registry. Headcount by skill and market - 599 US Rust engineers against 89 in Germany, Go outnumbering Rust 4.6x in the US - cannot be pumped by anyone buying stars or publishing empty versions. Pulling that count in plain English, and refreshing it when you re-run a read, is where Refolk removes the friction of assembling an independent signal by hand. Over 80% of the software in a typical product is open source, so these reads will keep landing on your desk. A fixed standard is what keeps two analysts from grading the same one two different ways.
Questions practitioners ask
Is GitHub stars a reliable metric for adoption?
No, not on its own. Across 925,978 data points, the correlation between stars and downloads ran from 0.47 in PHP down to 0.14 in JavaScript, and roughly 15.8% of repos with over 50 stars in July 2024 were tied to fake-star campaigns. Stars measure attention, not use. Treat them as a discovery signal you must corroborate with dependents and de-noised downloads before any number enters a deck.
How many corroborating signals does an adoption read need?
This standard requires at least three independent signals that agree on trend direction before you publish. No numeric standard is established publicly, but practice converges on three: several fake-star checkers analyze three independent signals, and academic work tests three external adoption proxies. Pick signals that fail independently, such as de-noised downloads, dependent-repo counts, and a people-side count that a registry campaign cannot move.
Why do download counts overstate adoption?
Registries do not filter automated traffic. npm states plainly that it does not discard automated downloads, and each version publish draws roughly 100 to 150 automated pulls, which let one campaign reach 50,000 downloads in three days. PyPI excludes named mirrors but still counts CI/CD traffic. De-noise by applying npm's 50-per-day floor, dropping publish-day spikes, and using PyPI's mirror-excluded series.
What counts as a stale signal?
A single fixed cutoff is not established publicly, so your team must set one per signal type and record it. Anchor freshness to the last release and active maintenance: a project whose last ship date falls outside your window, has no active maintainers, and fails a Maintained check should be graded stale. State the cutoff in the read so a second grader applies the same rule.
How do I tell a fake-star burst from real momentum?
Run velocity and coordination detection. Fake campaigns show a sudden spike where a large share of total stars land in a brief window, often from accounts that starred a single repo or act in coordination. One independent heuristic reported 98% precision and 85% recall on known fakes. Record any burst dates and the suspected-fake share; a large concentrated burst is a fix or kill, not a publish.
Try it on your own search
Stop building boolean strings. Just describe the person.
Type one sentence and I plan the search, read GitHub, public LinkedIn and Crunchbase records, and the open web live, then hand back a ranked shortlist with the reasoning behind every name. No filters to learn, no export to clean up, no sales call to sit through.
- One sentence in, a ranked shortlist out. No boolean, no filters, no seat to buy.
- Read live at search time, not from a database that went stale last quarter.
- Watch every step as it runs, and see why each name made the list.
- Staff backend engineers in NYC who shipped Rust in production
- Series A fintechs in SF under 50 people, growing headcount this year
- Maintainers of fast-growing Rust web frameworks on GitHub
500 free credits on sign-up. No card, no demo call. See real searches.