Methodology
Every RepoRadar report comes from fixed rules applied to public data. No language model writes any claim. This page states each rule with its exact numbers. Method version 2026.10.2.
Anyone can buy stars for any repo. The star section describes a star history. It is never a verdict on the project, and it never says why anyone starred a repo.
Data sources
- GitHub, through one zero-permission GitHub App: repo metadata, commits, releases, issues, pull requests, forks, licenses and the README.
- GitHub's stargazers history endpoint, which gives weekly star counts for stars that are still active.
- deps.dev for package names, deprecation, latest version and the OpenSSF Scorecard. OSV for advisory details.
- Hacker News stories through Algolia's HN Search, for launch coverage only.
- For the historical star backfill only: GH Archive events from 2015-01-04 to 2025-05-18, read from a public ClickHouse endpoint and stored as weekly counts of distinct accounts.
Maintenance
Human commits
Commits on the default branch are counted for the last 30, 90 and 365 days. Bot commits are left out. A login ending in [bot] is a bot, and so are known bot names and logins or names that end in a separate "bot" or "robot" word (release-bot, ci-robot, PR Bot). Accounts that push other people's work, such as translation platforms and exports from a company's internal repository, count as human activity but not as one person: the People section and author counts leave them out. If the sample stops before the 365-day window starts, the human count is GitHub's total scaled by the sampled bot share.
Label
The first rule that matches gives the label:
- Archived: GitHub marks the repo as archived.
- Dormant: no human commit in 365 days, and either fewer than 50 % of sampled issues got a maintainer reply (at least 5 issues sampled), or at least 5 pull requests are open.
- Stable: no human commit in 365 days, and no dormant condition holds: the sample is smaller than 5 issues or at least 50 % were answered, and fewer than 5 pull requests are open.
- Slowing (information only): at least 12 human commits in 365 days, and the 90-day pace is under half the 365-day pace.
- Active: at least 1 human commit in the last 30 days and at least 6 in the last 90 days.
- Steady: anything else.
Responsiveness
The sample is issues created 30 to 120 days ago. If the repo has no human commit in the last year, the window widens to 30 to 365 days. Issues opened by maintainers are left out. A response is the first comment, label, close or assignment by an OWNER, MEMBER or COLLABORATOR, or by one of the top 5 committers. We need at least 5 issues. Below that, the report gives no median and no answered share. The median first response is shown in hours and days. Repos with issues turned off get no responsiveness figures.
Recent issues are not sampled. A busy repo's newest issues have not had time to get a reply yet, so they would make every project look slow.
Releases and pull requests
The report shows the last commit, the last release, the number of authors in the last 90 days and the median time from opening to merging a pull request, from the last 50 merged pull requests.
People
The people section uses human commits in the last 365 days. If there are none, it uses the newest 100 commits and says so. It reports:
- the top 2 authors and their shares of those commits;
- how many authors it takes to cover 50 % and 80 % of the commits;
- whether the owner is a user or an organization;
- the contributor count, or "too large" when GitHub refuses to count.
Bus factor 1 applies when the sample has at least 10 commits and the top author wrote at least 70 % of them. The section is partial when the sample has fewer than 5 human commits.
Top committer change is an information note only. It fires when the 90-day leader differs from the 365-day leader and both have at least 10 commits.
Stars
Star series and the analysis start
Weekly counts from GitHub's stargazers history endpoint are expanded to days. Today and later days are dropped. Analysis starts at F, the later of created + 7 days and 2013-02-10. Stars that GitHub dates to the creation day of a repo created before 2013 are reported as "N undated stars". They are not counted as a burst. A run of 26 weeks or more with no stars is a history reset. F then moves to the end of the run plus 28 days, and the report says the history was reset. If the archive saw at least 1,000 stars in that run, a later spike that is at least the larger of 1,000 stars and half of the archived stars is counted as restored stars, not a burst. Those stars came back with a new date after the gap.
Bursts
Only days from F + 28 onward are checked.
- Each day's count d becomes y = 2 × √(d + 3/8), the Anscombe transform.
- The baseline b is the median of y over the previous 28 days, leaving out days already flagged.
- The spread s = max(1, 1.4826 × MAD) of those same days.
- The expected rate λ = max(0, (b/2)² − 3/8).
- A day is flagged when (y − b) / s is at least 5 and d − λ is at least 10 stars.
- Flagged days with gaps of 2 days or fewer form one group. A group longer than 42 days is split into pieces of at most 42 days, and each piece is its own episode.
- An episode extends while d stays above λ_ref + 3 × √(λ_ref + 1), where λ_ref is the rate at the first flagged day. The extension runs at most 7 days past the latest flagged day, and an episode never spans more than 42 days. A later flagged group is absorbed only when it fits within that 42-day limit.
- excess = the sum of max(0, d − λ_ref) over the episode.
- An episode is kept when its excess is at least 50 stars or at least 1 % of the stars at that time.
Shape
- Flat block: lasts at least 3 days, has a coefficient of variation of 0.35 or less, ends abruptly, and has a lift L under 1.3. The day after the episode keeps at most 20 % of the last day's excess, and the last day keeps at least 50 % of the peak excess.
- Viral: the peak falls in the first 2 days and the excess 3 days after the peak is at most 50 % of the peak excess, or L is at least 1.5.
- Indeterminate: anything else.
The lift L is the median daily count from 8 to 35 days after the episode ends, divided by the median from 35 to 8 days before it starts. That denominator is floored at 0.5 stars a day.
Corroboration
The corroboration window runs from 2 days before the episode to 2 days after it. The baseline runs from 90 to 8 days before the episode, and needs at least 30 usable days. Two counts are compared with their expected values from the baseline. Expected E = X_B × stars in the window ÷ stars in the baseline.
- Issues and pull requests opened in the window.
- Forks created in the window, counted only when the repo has at most 30,000 forks.
- A count is informative when E is at least 4. It corroborates when the count in the window is at least the larger of 3 and 25 % of E.
- A Hacker News story with at least 20 points whose URL is the repo itself or its homepage host, posted between 3 days before the episode and its end.
- A release published between 3 days before the episode and 1 day after it, counted only when L is at least 1.2.
An episode is corroborated when any of these holds. It is uncorroborated when at least one count is informative and none corroborates. Otherwise it is unknown.
Engagement
Forks, watchers, issues plus pull requests, and contributors are each divided by the star count. Each ratio's percentile is taken within a peer cell: one of five star brackets (200–1k, 1k–5k, 5k–20k, 20k–100k, 100k+), split into code and non-code. The composite is the mean of the four percentiles. The engagement is lowwhen the composite is below the cell's 5th percentile. A cell with fewer than 50 peer repos is not used. Repos under 200 stars are not compared.
A repo is non-code when it has no root manifest and less than 10 KB of programming-language code. Lists, books and model-release repos are often non-code. Engagement is not applied to non-code repos or to mirrors.
Survival against the organic baseline
This runs only for repos with an archive backfill. For each week w, a_w is the number of distinct accounts whose last star event is in that week, and h_w is the current history. G_w is the organic baseline from reference repos, smoothed with a 9-week rolling median. R_w = h_w ÷ (a_w × G_w), for weeks with at least 50 archived accounts.
- History reset: at least 80 % of eligible weeks have R under 0.3. The history was wiped, not trimmed.
- Archived episodes: a weekly burst detector runs on the archive counts with a 12-week baseline, a robust z of 5 or more, a weekly excess of at least 10, and episodes with at least 100 stars of excess. Weeks where the archive sample fell by more than 50 % are left out, as archive outages. Archived weeks before the analysis start F are left out too, so a repo with a history reset is only compared after its reset.
- Missing stars are the net shortfall over each burst window. A window is an episode widened by one week on each side, and overlapping windows are merged. Over the usable weeks of a window, missing = max(0, Σ(a × G) − Σh), and removedShare = missing ÷ Σ(a × G) over the same weeks. Stars dated a week apart in the archive and the current history therefore cancel out instead of counting as missing.
- Hard signal: removedShare is at least 30 %, missing is at least the larger of 200 stars and 2 % of the repo's stars, the history was not reset, and the median R outside the episodes is at least 0.85.
Forward removals
Each week the stars of tracked repos are snapshotted. A week older than 14 days that shrinks counts as removals, by the drop in its count. The removal signal needs at least 8 snapshots. It is a hard signal when removals reach the larger of 200 stars and 2 % of all stars, and at least 50 % of them fall within 4 weeks.
Label
| Label | Rule |
|---|---|
| Not enough data | Under 200 stars, or under 120 analyzable days. |
| Likely inflated | A hard signal plus soft bursts or low engagement, or both hard signals. |
| Unexplained bursts | Soft bursts, or exactly one hard signal alone. |
| Mostly organic | Low engagement alone; uncorroborated excess of at least 2 % of stars; or unknown-corroboration excess of at least 5 % of stars. |
| Organic | None of the above. |
Soft bursts means uncorroborated excess of at least the larger of 200 stars and 15 % of stars. A hard signal is either survival or forward removals. Confidence counts the signal families computed: bursts, engagement, survival and removals. 3 or more families give high confidence, 2 medium, and 1 low.
Stars can move a repo's verdict from Healthy to Caution, and no further.
Risk
The risk section lists facts and flags, each linked to its source:
- Archived or disabled by GitHub.
- Main package deprecated on deps.dev.
- Advisories on the latest package version, from OSV through deps.dev. CRITICAL and HIGH are high severity; MODERATE, LOW or unrated are a warning. Withdrawn OSV records are ignored. A package whose latest release lags a newer GitHub release of the project (see Stale package) raises none of these rules; the stale package note names its advisories instead.
- License. GitHub reporting no license counts as no license. NOASSERTION, a license GitHub could not classify, does not. A license change counts only when the classified license differs between the LICENSE file a year ago and today. The classifier covers MIT, Apache, BSD, GPL, LGPL, AGPL, MPL, BSL, SSPL, ELv2 and FSL.
- Successor. README or description links that say a project moved, is deprecated, or should be replaced are checked first. Fork comparison is the second source. A strong notice ("moved to", "superseded by", "no longer maintained, use ...") counts anywhere in the README; a weaker pointer ("replaced by", "consider using") counts only in its first 1,500 characters, where notices about the project itself sit. A README with 20 or more repository links is a catalogue: only a strong notice in its first 1,500 characters counts.
- Fork takeover. A fork is ahead by at least 50 commits, was pushed in the last 365 days and after the upstream's last commit, has at least the larger of 50 stars and 5 % of the upstream stars, and the upstream is archived, or dormant or stable (no human commit in 365 days). On a non-code repository (documentation, data or model files), a fork takeover is capped at caution.
- Renamed or moved, from the GitHub redirect.
- Stale package. The latest release is more than 24 months old, while the repo has at least 10 human commits in the last year. When the repo has also published a GitHub release more than 30 days newer than that release, the package lags the project: the old release's known security advisories are named here, and they do not show whether the current code is affected. Otherwise the advisories keep their own rules, because the old release is still what people install.
- OpenSSF Scorecard below 4 out of 10, from deps.dev. Shown as information.
- Mirror and fork, labelled as such.
Verdict
The verdict is the most severe level that fires. Each fired rule is written as one sentence with its evidence links, followed by what would change the verdict.
| Verdict | Fires when (any) |
|---|---|
| Avoid | The repo is archived or disabled. · The main package is deprecated. · Dormant, and fewer than 20 % of sampled issues got a maintainer reply (at least 5 issues). · A CRITICAL advisory affects the latest version. |
| At risk | Dormant. · Bus factor 1, and no human commit in 90 days. · A successor is declared, or a fork has taken over. · The license moved from OSI-approved to not approved within 12 months. · A HIGH advisory affects the latest version. |
| Caution | Stable. · Bus factor 1. · Median first response over 30 days. · No license file. · A package with no release in 24 months, despite at least 10 human commits in the last year. · Stars labelled Unexplained bursts or Likely inflated. |
| Too new | The repo was created less than 60 days ago, and no Avoid or At risk rule fired. |
| Healthy | None of the above. |
For a non-code repo (defined under Engagement), the dormant, dormant with unanswered issues, stable, bus factor 1, slow response and fork takeover rules fire at most at Caution. Each such rule says the repository holds mostly documentation, data or model files. The other risk rules are not changed.
Method changes
2026.10.2 (October 14, 2026), after a review of all 2,811 precomputed reports:
- More automation accounts are recognised as bots: known names from the precomputed repos, and logins or names ending in a separate "bot" or "robot" word.
- Accounts that push other people's work (translation platforms, exports from an internal repository) count as activity but are left out of the People section, so they no longer look like one person writing most commits.
- A weak successor pointer ("replaced by", "consider using") counts only near the top of the README, and "now at", "now on" or "now in" counts only right before a link.
- A repo whose sampled commits include no human commit now reads "No human commits in the last year", and the no-license rule says "content" for a non-code repo.
2026.10.1 (October 13, 2026), after a review of the first 863 precomputed reports:
- A star burst lasts at most 42 days and extends at most 7 days past its last flagged day, so steady growth is no longer one long burst.
- Stars restored after a gap in the star history are recognised and are not counted as a burst.
- Survival compares only the weeks after a history reset, measures the net shortfall over each burst window widened by one week, and needs at least 2 % of all stars missing for a hard signal.
- Unexplained bursts need at least 15 % of all stars (was 5 %). Our sources cannot see social media or newsletters, so smaller unexplained shares are reported as mostly organic.
- Withdrawn OSV advisories are ignored, and advisories on a package that lags the project's newer GitHub releases are named in the stale package note.
- Catalogue READMEs only count a strong successor notice near the top, and a fork takeover of a non-code repository is capped at Caution.
What we deliberately don't do
- No stargazer profiling. We do not record or show who starred a repo, or what else they starred.
- No reconstruction of stargazers from the Events API. GitHub's June 30, 2026 change hid stargazer lists from anyone who is not an admin of the repo. We use the stargazers history endpoint, which returns weekly counts only, and we do not work around the change.
- No language-model-written claims. Every sentence comes from a rule above.
- No use of ecosyste.ms data.
- No per-person data beyond the public commit author logins shown in the People section.
Limits
- A report is a snapshot of public data at the time it was computed. The page shows when.
- A provisional report is shown before the star analysis finishes. A "final" report includes it, and so does every section that is computed. A lite report skips the star analysis.
- Thresholds are tuned by calibration against a reference set. A star label is a signal, and confidence says how many signals were computed.
- Sections that fail are marked unavailable, and the verdict says what it did not check.