The White Score for Open Source Projects
The White Score is a five-part framework for evaluating open source repositories using GitHub-derived metrics over time. Each score is on a 0–100 scale and captures an independent dimension. A project can be popular but unhealthy, mature but unknown, or healthy today but unsustainable; separating the dimensions avoids judging a project by stars alone.
| Score | Measures | Answers |
|---|---|---|
| Maturity | Structural readiness and governance | Is the project professionally maintained? |
| Health | Current activity and responsiveness | Is the project alive and functioning well? |
| Popularity | Adoption and community traction | Is it widely used or gaining attention? |
| Risk | Dependency and abandonment risk (higher is worse) | What could go wrong if we rely on it? |
| Sustainability | Long-term viability | Can the project keep going over time? |
The leaderboard's default ranking uses the Overall White Score, a weighted blend of all five dimensions:
Overall = 0.25 × Maturity + 0.25 × Health + 0.25 × Popularity + 0.15 × Sustainability + 0.10 × (100 − Risk)
The core suite carries three quarters of the weight. Sustainability and risk enter at reduced weight because several of their inputs (maintainer count, commit and release recency, contributor concentration, governance) are already scored by maturity and health; counting them in full would double-weight activity and maintainer signals. Risk is inverted so that higher is better throughout. An archived project has its risk pinned at 90 or above, which on its own removes up to nine points from its overall score. Every dimension is also shown on its own and can be sorted on.
How projects are found
The catalog is built by sweeping GitHub's repository search across 170 AI-related topics (from llm and ai-agents to gaussian-splatting and speech-synthesis). Topics with more than 1,000 matches are split into star bands to get past GitHub's per-query cap. A second pass searches repository names and descriptions for AI terms, which catches well-known projects that carry no topics, and a seed list is fetched directly. Only non-fork, non-archived repositories with at least 200 stars are kept.
Each repository gets an AI signal: two points per specific AI topic it matched, one point at most for generic tags such as ai or chat, and up to two for AI terms in its description. Repositories scoring below two are shown as AI-adjacent and excluded from the leaderboard. Awesome-lists, courses and paper collections are detected from names, topics and descriptions and kept in their own category. Categories are assigned by scoring each repository's topics (specific topics weigh 2, generic ones 0.25) and description keywords (1, or 2 when the keyword appears in the opening words) against sixteen category rules; the highest total wins.
The leaderboard then tracks the top catalog projects by stars (2,000 by default) that have a recognised open source license and at least 500 stars, merged with a seed list. Metrics come from the GitHub GraphQL and REST APIs and use a rolling 90-day window (180 days for maintainer metrics, 12 months for releases).
Normalisation helpers
N_log(x, b) = 100 × min(1, ln(1 + x) / ln(1 + b)) log-normalised count against a benchmark b N_ratio(x) = 100 × clamp(x, 0, 1) a ratio already in [0, 1] N_recency(d, τ) = 100 × e^(−d / τ) days since an event, decay constant τ
White Maturity Score
WMS = 0.10·A + 0.15·R + 0.15·D + 0.15·G + 0.15·C + 0.10·M + 0.10·V + 0.10·B A = N_log(age in months, 60) R = 0.7 × N_log(releases in last 12 months, 12) + 0.3 × N_recency(days since last release, 90) D = 20 × (README + INSTALL + EXAMPLES + API_DOCS + TROUBLESHOOTING) G = 20 × (LICENSE + CONTRIBUTING + CODE_OF_CONDUCT + SECURITY + ISSUE_TEMPLATES) C = 40 × CI_PRESENT + 30 × TESTS_PRESENT + 30 × CI success rate (last 90 days) M = N_log(active maintainers in last 180 days, 8) V = 40 × SEMVER_TAGS + 30 × CHANGELOG + 30 × release cadence consistency B = 100 − N_log(breaking-change signals in last 12 months, 10)
Documentation and governance flags are detected from the repository tree, README text and GitHub's community-profile fields. Active maintainers are commit authors with at least three commits on the default branch in the window (bots excluded). Cadence consistency is 1 minus the coefficient of variation of the intervals between the last twelve releases. Breaking-change signals combine merged PRs with "breaking" in the title and major version bumps.
White Health Score
WHS = 0.15·CA + 0.15·IR + 0.15·PRR + 0.15·ICR + 0.10·PMR + 0.10·BP + 0.10·CD + 0.05·RF + 0.05·CI CA = 0.7 × N_log(commits in last 90 days, 100) + 0.3 × N_recency(days since last commit, 30) IR = 100 × e^(−median issue first-response hours / 72) PRR = 100 × e^(−median PR first-response hours / 72) ICR = N_ratio(issues closed / issues opened, last 90 days) PMR = N_ratio(PRs merged / PRs closed, last 90 days) BP = 100 × e^(−open issues / (2 × max(1, issues closed in last 90 days))) CD = N_log(active contributors in last 90 days, 20) RF = N_recency(days since last release, 90) CI = 100 × successful workflow runs / total workflow runs (last 90 days)
First response is the first comment or review by someone other than the author (bots excluded), or the close/merge event, measured over the 40 most recent issues and PRs. Unanswered items older than seven days count as their current age so silence is penalised. Where a signal is unobservable (no issues, no workflow runs) the component is neutral at 50.
White Popularity Score
WPS = 0.25·S + 0.20·SG + 0.15·F + 0.10·FG + 0.10·W + 0.10·CR + 0.10·EA S = N_log(total stars, 50,000) SG = N_log(new stars in last 90 days, 5,000) F = N_log(total forks, 10,000) FG = N_log(new forks in last 90 days, 1,000) W = N_log(watchers, 1,000) CR = N_log(total contributors, 500) EA = N_log(issues + PRs opened by non-maintainers in last 90 days, 1,000)
Benchmarks are tuned for the AI ecosystem, where star counts run high. Star and fork growth are measured from the 100 most recent stargazers and forks; when all 100 fall inside the window, the 90-day figure is extrapolated from the observed rate and marked as estimated.
White Risk Score
WRS = 0.20·BUS + 0.15·CONC + 0.15·CS + 0.10·RS + 0.10·SEC + 0.10·STALE + 0.10·OWN + 0.10·ARCH BUS = 100 × e^(−(bus factor − 1) / 1.5) bus factor = authors covering 50% of recent commits CONC = 100 × share of commits by the top contributor (180 days) CS = 100 − N_recency(days since last commit, 90) RS = 100 − N_recency(days since last release, 180) SEC = 100 if no security policy, else 0 STALE = 100 × open issues untouched for 180 days / open issues OWN = 100 if owned by an individual account, else 0 ARCH = 100 if archived, else 0 (archived projects score at least 90)
Interpret inversely: 0–24 low risk, 25–49 moderate, 50–74 high, 75–100 critical.
White Sustainability Score
WSS = 0.20·MAINT + 0.15·DIV + 0.15·RET + 0.10·SPON + 0.10·ORG + 0.10·GOV + 0.10·RELC + 0.10·LOAD MAINT = N_log(active maintainers in last 180 days, 8) DIV = 100 × (1 − top contributor share) RET = N_ratio(contributors active in the last 90 days who were also active in the prior 90 days) SPON = 100 if funding links or a sponsors listing exist, else 0 ORG = 100 if owned by an organization, else 0 GOV = governance completeness (G from maturity) RELC = 0.5 × N_log(releases in last 12 months, 12) + 50 × release cadence consistency LOAD = 100 × e^(−(issues + PRs opened in 90 days) / (60 × active maintainers))
Interpretation bands
| Score | 0–24 | 25–49 | 50–69 | 70–84 | 85–100 |
|---|---|---|---|---|---|
| Maturity | Experimental | Early-stage | Usable | Mature | Highly mature |
| Health | Unhealthy | Weak | Moderate | Healthy | Very healthy |
| Popularity | Low visibility | Niche | Notable | Popular | Widely recognized |
| Sustainability | Fragile | At risk | Moderate | Sustainable | Highly sustainable |
Limitations
- People metrics use up to 500 of the most recent default-branch commits in the 180-day window; very active repositories are sampled.
- Documentation flags are heuristic (file names and README keywords), not an assessment of quality.
- CI reliability only sees GitHub Actions. Projects using other CI get a neutral score for that component.
- Dependency vulnerability data requires repository admin access and is not included; the risk score uses the presence of a security policy instead.
- External engagement is estimated from the maintainer share among the most recent issue and PR authors.
Colour coding
Every score meter on the leaderboard is coloured by its band so that areas of concern stand out: strong (70–100) is green, adequate (50–69) is the neutral blue, weak (25–49) is amber and concern (0–24) is red. Risk is read the other way round, because a high risk score is the bad outcome: 0–24 is green (low risk), 25–49 blue (moderate), 50–74 amber (high) and 75–100 red (critical). The number itself always stays in the text colour; the colour is carried by the meter, and the band name appears when hovering a score.
All weights, benchmarks and windows are defined in whitescore/config.py and exported with each data file. OpenScores is run by the Open Intelligence Foundation.