What is PopScore? The math behind GitHub's only velocity-aware trend score
PopScore weights commits and PRs above raw stars, and applies a noise penalty for awesome-* lists. Here's the formula, the rationale, and the data sources.
When we launched GitPop, we knew the trend pages on GitHub weren't enough. They sort by star velocity over 24 hours — which means a clever README that hits the top of r/programming wins, regardless of whether the project is well-engineered, actively maintained, or even real.
PopScore is our attempt to fix that. It's a 0-100 score that answers a different question than "what's hot right now" — it answers "what is gaining real momentum, from real maintainers, with real code being shipped?"
The formula
PopScore is a weighted sum of four input signals plus a noise penalty:
PopScore = 0.35 × S + 0.20 × F + 0.25 × A + 0.10 × M − 0.10 × N
Where:
- S — Star velocity (last 7 days, log-normalized within the cohort)
- F — Fork engagement (last 7 days; weighted by repo size to avoid huge-but-dormant repos dominating)
- A — Activity score (commits + merged PRs + issues-closed rate, last 7 days)
- M — Mentions (Hacker News + Reddit + Lobsters, last 7 days)
- N — Noise penalty (0-100; higher = more likely an awesome-list, tutorial, or fork farm)
Each component is normalized to 0-100 before the weighted sum, then the result is clamped to [0, 100].
Why these weights?
We benchmarked the formula against three datasets:
- Known signal — the top 20 repos on the GitHub Trending page for each of 30 days
- Known noise — a hand-labeled set of 200 awesome-* lists, tutorial repos, and fork farms
- Known engineering quality — a sample of 50 well-known mature projects (Postgres, Redis, Linux, …)
The weights above are the smallest change to the v1.0.0 formula that:
- Cuts the noise-precision rate from 34% to 7% (i.e. 93% of "trending" repos are actually good)
- Doesn't drop any known-quality mature project below 60
- Doesn't push any known-noise repo above 30
The full regression notebook is in the methodology page.
What the noise filter is doing
This is the highest-leverage piece. A repo is "noise" if it matches two or more of:
- Name pattern — matches
awesome-*,*-resources,*-tutorial,*-roadmap,*-interview-questions - Fork / archive ratio — fork count > 10× star count (a strong signal of a fork farm)
- Asset quality — README is < 1,000 chars (typical of low-effort repos)
- Activity ratio — star count > 50× commits-in-last-30-days (viral README, no code)
We assign each repo a noiseScore 0-100. The PopScore formula subtracts 10% of that. In practice, awesome-* lists with high star velocity end up at PopScore 15-25 instead of 80+.
What PopScore is not
- Not a quality verdict. A high score means "gaining momentum with real activity". It does not mean "the best library for X." Use the comparison pages for that.
- Not a stack ranking. Two projects at PopScore 80 are not equivalent. They share a velocity tier, not a verdict.
- Not a leading indicator of success. Some great projects have low PopScore because they're not in their growth phase right now. That's fine.
- Not a replacement for reading the README. We provide an AI Snapshot for that. The score is the what, the snapshot is the why.
How to use the score
The four most useful ways:
- Find rising stars before they saturate. Sort by PopScore over 14d or 30d ranges. Things at 70+ today were at 40 two weeks ago.
- Filter out noise. The
/projectsdirectory lets you toggle noise on/off explicitly. The main Pop Radar hides it by default. - Compare alternatives. The 30 curated comparison pages all surface a "winner" by PopScore. That verdict is a starting point, not a final answer.
- Audit the formula. Every detail of how we compute each input is in the methodology page, with the exact SQL, the normalization constants, and the noise classifier thresholds.
Where to go next
- Methodology page — the full math
- Comparison matrix — X vs Y for 30 high-traffic pairs
- Trending projects — the live radar
- RSS feed — get notified when we publish a new trend report
If you want to challenge the formula, the test data, or the noise filter, open an issue on github.com/getgitpop. Every input is auditable; no black boxes.