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?

Timeline History - Watching the Programme Grow

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.

Timeline page showing stat cards and sparkline charts

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

Top 10 leaderboard at a snapshot with rank changes

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

New contributors and difficulty distribution

New contributor chips and the shifting difficulty distribution.

All snapshots summary table

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:

  1. node generate-timeline.js reads all pr-scores-*.json from leaderboard/
  2. Extracts and computes metrics (diffs, rank changes, new users)
  3. Writes leaderboard/timeline-history.js as var timelineHistory = [...]
  4. The script tag in index.html loads it
  5. pages/Timeline.tsx reads from window.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.