Every time our scoring engine runs, it saves a timestamped pr-scores-{timestamp}.json file. We'd been accumulating these files for a week but never doing anything with them. They were just backups.
Then we asked: what if we read them all and told the story of how this programme grew?

From 68 PRs to 693 in one week. The Timeline page tells the full story.
The Numbers Tell a Story
| Date | PRs | Points | Active Contributors |
|---|---|---|---|
| Jun 3 | 68 | 1,810 | 36 |
| Jun 4 | 168 | 4,760 | 67 |
| Jun 6 | 449 | 13,160 | 134 |
| Jun 8 | 624 | 18,820 | 157 |
| Jun 9 | 693 | 20,860 | 163 |
In one week: 10x PRs, 11.5x points, 4.5x contributors. That's the exponential early growth of an open source programme done right.
What We Built
A generator script (generate-timeline.js) that reads all historical snapshots and extracts compact metrics from each:
- Growth metrics - total PRs, points, and active contributors at each point in time
- Top 10 leaderboard - who was leading at each snapshot
- New contributor detection - who joined between runs
- Rank changes - who climbed, who dropped, who's new to the top 10
- Difficulty distribution - the Easy/Medium/Hard split and how it's shifting
- Project velocity - which repos attracted the most contributions at each point
The output is a lightweight timeline-history.js file (same pattern as our other data files - a var declaration loaded via script tag). The full historical JSONs are 1-2MB each; the compiled timeline is a fraction of that.
The Frontend
The Timeline page at /timeline (unlisted, not in the main navigation) lets you step through every snapshot:
- Snapshot navigator - prev/next buttons and clickable dots for each point in time
- Stat cards - PRs, points, contributors, and active projects with delta badges showing change from the previous snapshot
- Sparkline charts - SVG line charts for PRs, points, and contributors over time, with the current snapshot highlighted
- Top 10 at each snapshot - with GitHub avatars, scores, and rank change indicators (green arrows for climbers, "NEW" badges for first appearances)
- New contributor chips - clickable GitHub profile links for everyone who joined between snapshots
- Difficulty distribution - bar chart showing the Easy/Medium/Hard/Beginner/Intermediate/Advanced split
- Top projects - which repos were most active at each point
- Summary table - all snapshots in one view, click any row to jump there
No chart library. Pure CSS and SVG. Keeps the bundle lightweight and consistent with the rest of the platform.

Stat cards with delta badges and SVG sparklines tracking growth over time.

The top 10 at each snapshot - green arrows for climbers, "NEW" for first appearances.

New contributor chips and the shifting difficulty distribution.

The full snapshot table - click any row to jump to that point in time.
What We Learned From the Data
New contributor onboarding peaked around June 5-6. 67 new contributors appeared in the June 6 snapshot alone. Understanding when people join helps us time onboarding communications and know when to push awareness campaigns.
The top of the leaderboard is volatile early on. Rank changes were dramatic in the first few days - someone who was #1 on June 3 might be #5 by June 6. The leaderboard is stabilising now as score gaps widen, but early on it was anyone's race.
Easy PRs dominate early, but the mix is shifting. As contributors get comfortable with their projects, they're taking on Medium and Hard issues. The difficulty distribution bars are slowly evening out.
One snapshot had fewer PRs than the previous one. The June 8 07:25 snapshot showed 396 PRs vs 449 on June 6. This wasn't a bug - it was a partial run against a different project list. The 07:30 snapshot (5 minutes later, full run) jumped to 624. This is why having the full history matters: it catches anomalies that a single "current state" view would hide.
How It Fits the Architecture
The SSoC 2026 platform follows a consistent pattern: Node.js scripts generate data files, which are loaded as global var declarations via <script> tags in the HTML. No API calls, no databases, no server-side rendering.
The timeline generator follows the same pattern:
node generate-timeline.jsreads allpr-scores-*.jsonfromleaderboard/- Extracts and computes metrics (diffs, rank changes, new users)
- Writes
leaderboard/timeline-history.jsasvar timelineHistory = [...] - The script tag in
index.htmlloads it pages/Timeline.tsxreads fromwindow.timelineHistory
Run it after each scoring engine execution to keep the timeline current.
What's Next
- Automatic daily snapshots via CI - no more manual runs
- Per-user growth trajectories - your personal score over time, not just the global view
- Project health indicators - merge time trends, contributor diversity ratios
- Weekly automated reports - posted to Discord with the week's highlights
The leaderboard isn't just a scoreboard. It's a living document of how a community grows.
