Scoring methodology
Every score and rating on this site — the health score and the deploy-effort tier — is computed by an open formula from public repository data. This page is the complete specification — no editorial judgement, no paid placement, no exceptions.
What the score is
The health score is a 0–100 estimate of how alive a project is: whether it is being maintained, whether people use it, and whether that is trending up or down. It is not a quality score — a small, stable, finished tool can be excellent software with a middling health score, and the score can never capture code quality, documentation, or security beyond publicly catalogued vulnerabilities.
The formula
Five components, each scored 0–100, combined as a weighted average. Weights are relative: with all five present they sum to 120, and a component without data drops out (see below).
| Maintenance recency — weight 40 | Days since the last push to the default repository. 100 within 30 days, then linear decay to 0 at 18 months. This is the strongest signal and the only mandatory one: apps with no push data get no score at all. |
|---|---|
| Community traction — weight 25 | GitHub stars on a logarithmic scale: 50 stars scores 0, 50,000+ scores 100. Log scaling stops mega-projects from flattening everything else. This measures adoption, not quality. |
| Star momentum — weight 20 | Star growth over the trailing ~90 days, from weekly samples we record. Flat growth scores 40, +15% or better scores 100, decline falls below 40 toward 0. Requires at least 60 days of samples. |
| Release cadence — weight 15 | Days since the latest published GitHub release. 100 within 90 days, linear decay to 0 at two years. Many healthy projects don't use GitHub releases at all — see redistribution below. |
| Known vulnerabilities — weight 20 | Starts at 100 and loses points for each open known vulnerability in the latest release: critical 70, high 45, medium 20, low 10, unrated 25 (floor 0). Scored only when we can match the latest GitHub release and OSV.dev has at least one advisory for the project; otherwise it drops out. See the security signal. |
Missing data is redistributed, not penalised
If a component has no data — a project with no releases, or too little sampling history for momentum — its weight is redistributed across the components that do have data. A release-less project is judged on maintenance, traction, and momentum alone; it is not marked down for workflow choices. The one exception: no push-recency data means no score, because a health score without a maintenance signal would be meaningless.
Archived projects
A project whose repository is archived is capped at 15 regardless of its other components. Archived means upstream development has stopped; no amount of past popularity outweighs that for someone choosing software to run today.
The security signal
Every GitHub-hosted app is checked nightly against OSV.dev, Google's open vulnerability database, which maps CVEs and GitHub advisories to the repositories and release tags they affect.
- Affecting the latest release: advisories OSV matches to the exact tag of the latest GitHub release.
- No fixed version on record: advisories for the repository that record no fix at all. These count as open even when OSV doesn't match the tag, because OSV can't match a tag it has never seen. They are often old records with incomplete version data, so they are listed separately.
- Severity is the CVSS v3 base score computed from the advisory's vector (critical 9.0+, high 7.0+, medium 4.0+), or the advisory's own rating when it has no v3 vector.
- Most recent fixed advisory is the newest advisory with a fix on record, by publish date. It indicates when the project last shipped a security fix that was publicly catalogued.
- Image signature (apps with a catalogued Docker image): whether a Sigstore/cosign signature is stored next to the image in its registry. Signatures kept in a separate repository can't be detected, so "none found" is not the same as unsigned. It is shown for information and not scored.
Caps. A confirmed critical vulnerability in the latest release caps the health score at 59 (at most Fair); a confirmed high one caps it at 79 (at most Good). Advisories with no fixed version on record reduce the component but never trigger a cap, because their data is often incomplete.
Why projects with no advisories aren't scored. A project OSV has never recorded is unknown, not secure: obscure software has fewer reports because fewer people look. Scoring it 100 would reward obscurity. A project with an advisory history and nothing open has shown it fixes what gets reported, which is what the component credits. Past advisories are never penalised; more scrutiny is not less security.
Current coverage: 3214 apps checked, 1151 with a scored security component, 92 with known vulnerabilities in their latest release.
Score bands
80–100 Excellent · 60–79 Good · 40–59 Fair · 0–39 At risk.
README badges
Every scored app has an embeddable badge at
/badge/<slug>.svg — for example
. Maintainers can copy
Markdown, HTML, or reStructuredText embed code from the "Health badge"
section of their app's page. Badges are regenerated on every build,
so they always show the current score. Archived projects say so on the
badge, unscored apps read "not yet rated", and apps removed from the
catalogue keep an "unlisted" badge so an embedded image never breaks.
Data collection
A nightly job queries the GitHub API for every GitHub-hosted app: stars, last push, archived state, open-issue count, and latest release. Star counts are additionally sampled weekly into a rolling one-quarter window for the momentum component. Scores are recomputed on every site build from that committed data — the entire pipeline is public.
Current coverage: 3209 of 3530 apps have a score. Of those, 2663 have release data and 0 have enough sampling history for the momentum component. Apps hosted outside GitHub (GitLab, Codeberg, sourcehut) are not scored yet.
The deploy-effort rating
Separate from the health score, every app carries a three-tier deploy-effort rating estimating the time from zero to a running instance:
| ≈5-minute setup | We verified a single-container deployment: the upstream compose file defines one service, the image exists on its registry, and no privileged access is required — or the app ships one-click packages for common self-host platforms. |
|---|---|
| Under-an-hour setup | A Docker path exists but takes assembly: a multi-service compose stack (the badge names the companion services — PostgreSQL, Redis, and so on) or a published image whose configuration you compose yourself. |
| Read-the-docs project | No published container path, a build from source, or a container needing privileged access, host networking, or device passthrough. |
The rating is deliberately conservative: "5-minute" is only awarded on verified evidence from a weekly harvest of upstream compose files, never estimated. A docker-capable app we haven't verified yet sits at "under an hour" and upgrades automatically once its compose file is harvested and checks out. Every badge's tooltip states the specific evidence.
RAM and CPU. The "Min. RAM" figure on app pages is a curated estimate. Where upstream publishes an actual memory limit in its compose file we show it as "Upstream memory limit" — a fact, labelled as such. We don't publish CPU expectations: upstream compose files almost never declare them, and we won't invent numbers.
What we deliberately don't score
Issue responsiveness. Open-issue counts conflate popularity with neglect — a project with 2,000 open issues may simply have 100,000 users. Measuring real responsiveness (median time to first maintainer reply) requires sampling individual issues at API scale we don't collect today. We show open-issue counts as a raw fact where available, but they do not move the score. If we add a responsiveness component later, this page will document it before it ships.
Search-trend data. Some directories estimate interest via Google Trends. We prefer signals that are reproducible from public APIs by anyone auditing our data.
Limitations, honestly
- Stars measure GitHub visibility, which skews toward developer tools and newer projects.
- Monorepos and mirrors can misattribute activity.
- A fork taking over from a dead upstream looks "young" until its own history accumulates.
- The weights are judgement calls. They are fixed, published, and applied identically to every app — but they are still choices.