Animate a GitHub contribution graph (and export to MP4)
The grid of green squares is the most copied chart on the internet. Here's how to animate it deterministically and ship the MP4 in a launch video.
The GitHub contribution graph — 52 weeks × 7 days of green squares — is the most-copied chart on the internet. Year-in-review videos use it. Launch announcements use it. Personal-brand portfolios use it. It is the universally readable shorthand for "I shipped a lot."
Here is the version that animates well and renders to MP4 without an After Effects file in sight.
The grid
A <svg> with 52 × 7 <rect> elements. Each rect has an x, y, and a fill driven by a per-day intensity (0-4). The intensity is your data — commits per day, deploys per day, whatever you can squeeze into a per-day integer.
<svg viewBox="0 0 730 100" id="g"></svg>
<script>
const data = /* 364 integers, 0..4, one per day */;
const COLORS = ["#ebedf0", "#9be9a8", "#40c463", "#30a14e", "#216e39"];
const svg = document.getElementById("g");
const rects = [];
for (let i = 0; i < data.length; i++) {
const week = Math.floor(i / 7);
const day = i % 7;
const r = document.createElementNS("http://www.w3.org/2000/svg", "rect");
r.setAttribute("x", week * 14);
r.setAttribute("y", day * 14);
r.setAttribute("width", 12);
r.setAttribute("height", 12);
r.setAttribute("rx", 2);
r.setAttribute("fill", COLORS[0]);
svg.appendChild(r);
rects.push(r);
}
</script>That's the static version. The animation is in how the rects light up.
The reveal pattern
Three options, ranked by visual cost:
- Left-to-right wave. Day 1 → day 365. Each square arrives in chronological order. Reads as "a year in the life." Most common.
- Intensity stagger. Day-0 to day-4 squares arrive in that order — quietest first, brightest last. Reads as "the highs are what mattered." Better for a year-in-review.
- Random sparkle. Stochastic order, fixed seed for determinism. Reads as "lots of activity, can't pin it down." Use sparingly.
Pick one. Mixing two is always wrong.
The wave version, as render(t):
function render(t) {
const u = Math.min(1, t / 4); // reveal completes in 4 seconds
const cutoff = Math.floor(u * rects.length);
for (let i = 0; i < rects.length; i++) {
rects[i].setAttribute("fill", i <= cutoff ? COLORS[data[i]] : COLORS[0]);
}
}That's the whole animation. Two more seconds of "settle" — let the eye take in the finished grid — and you have a 6-second loop ready for MP4 export.
The polish
Three details separate this from a hackathon submission:
- Round the corners. GitHub uses
rx="2". It changes the feel of the whole grid. - Use the official palette.
["#ebedf0", "#9be9a8", "#40c463", "#30a14e", "#216e39"]. Don't pick "close enough" greens. - Add the day labels.
Mon,Wed,Frialong the left edge in monospace, tracked-out. The grid looks lonely without them.
Use cases
- Year-in-review hero. Open with the user's name and a 6-second animated heatmap. End on the total commit count counting up — see animated number counter in HTML.
- Launch announcement. "We shipped X feature, here's our year of work that led up to it." The heatmap as proof-of-work.
- OG image for a developer portfolio. The animated card auto-rebuilt nightly with the latest year of contributions.
The render-from-Next.js-route version is in render video from a Next.js route. The batch-personalization play — one per user, ten thousand renders overnight — is in render 10k variants overnight.
A close
The contribution graph is data viz at its quietest. It works because it asks nothing of the viewer — green squares, dense, more is more. An animated version respects that by being equally quiet: a wave reveal, the official palette, no transitions on the labels. Resist the urge to make it fancy. The data is the fanciness.
Cite this postBibTeX · APA · Markdown
@misc{park2026animate,
author = {Ren Park},
title = {Animate a GitHub contribution graph (and export to MP4)},
year = {2026},
url = {https://hyperframes.video/blog/github-contribution-graph-animation},
note = {HyperFrames blog}
}Ren Park. (2026, May 19). Animate a GitHub contribution graph (and export to MP4). HyperFrames. https://hyperframes.video/blog/github-contribution-graph-animation
[Animate a GitHub contribution graph (and export to MP4)](https://hyperframes.video/blog/github-contribution-graph-animation) — Ren Park, 2026
Ren writes guides, runs workshops, and breaks the CLI on purpose so you do not have to. Previously dev rel at a CI company; before that, an actual filmmaker.
Animated poll results as MP4
Build a poll results animation that renders to deterministic MP4: four horizontal bars race to their final percentages, then a winner ribbon sweeps in.
Animate a stock chart with real data
A scrubbing-line stock chart from a JSON of price points. The windowing trick, the easing, and the render.
Animated newsletter header MP4s (that fall back to a still)
Build an animated newsletter header in HTML, render it to a deterministic MP4, and ship a still PNG as the fallback for clients that strip video.
Building with HyperFrames? Come hang out.
We're on GitHub, in Discord, and the playground is one click away. Bring weird ideas — we collect them.