GitHub Graph
A living GitHub contribution graph for portfolios, powered by a single username.
Give a portfolio a quiet sign of life. GithubGraph fetches a public GitHub contribution history from one handle, lays it out as a familiar calendar, and keeps the details behind a small hover tooltip.
Installation
File Structure
Usage
Add the component anywhere in a client-rendered portfolio section. A handle is all it needs — both shadcn and @shadcn work.
import { GithubGraph } from "@/components/unlumen-ui/github-graph";
export default function Portfolio() {
return <GithubGraph account="shadcn" />;
}By default, the graph shows the most recent six months, uses the GitHub palette, and keeps the legend hidden.
Make it yours
The display stays compact at short ranges and grows naturally with the selected duration. On narrow screens it scrolls horizontally, so cells remain square.
<GithubGraph
account="your-handle"
months={12}
variant="violet"
animation="cascade"
animationSpeed={1.4}
cellSize={20}
cellGap={4}
cellRadius={6}
ambientEffect="twinkle"
ambientIntensity={0.7}
showLegend
/>Use your own data
Pass data when the contribution history already comes from your own service, cache, or build step. This skips the public request completely. Dates use the YYYY-MM-DD format; the component fills the missing days for you.
import {
GithubGraph,
type GithubContribution,
} from "@/components/unlumen-ui/github-graph";
const contributions: GithubContribution[] = [
{ date: "2026-07-14", count: 3, level: 2 },
{ date: "2026-07-15", count: 8, level: 4 },
{ date: "2026-07-16", count: 0 },
];
export function Activity() {
return (
<GithubGraph
data={contributions}
showAccount={false}
months={3}
ambientEffect="drift"
/>
);
}API Reference
GithubGraph
| Prop | Type | Default | Description |
|---|---|---|---|
account? | string | "shadcn" | Public GitHub username. A leading @ is accepted and removed automatically. |
months? | number | 6 | Recent calendar months to show. Values are rounded and kept between 1 and 12. |
variant? | "github" | "graphite" | "ocean" | "violet" | "github" | Color palette for the five contribution levels. |
animation? | "wave" | "scan" | "cascade" | "wave" | Entrance choreography used when the graph loads or changes. |
animationSpeed? | number | 1 | Multiplier for the entrance choreography. Higher is faster. |
cellSize? | number | 18 | Square cell size in pixels. |
cellGap? | number | 4 | Fixed space between cells in pixels. |
cellRadius? | number | 3 | Corner radius of contribution cells in pixels. The value is capped at half the cell size. |
showLegend? | boolean | false | Shows the five-level activity legend below the graph. |
showAccount? | boolean | true | Shows the normalized account name above the graph. |
ambientEffect? | "none" | "tide" | "drift" | "twinkle" | "twinkle" | Persistent, low-key cell motion. It never changes the grid layout. |
ambientIntensity? | number | 0.65 | Strength of the ambient effect, clamped between 0 and 1. |
data? | GithubContribution[] | - | Contribution entries to render instead of fetching the public endpoint. |
className? | string | - | Additional classes applied to the root element. |
GithubContribution
| Prop | Type | Default | Description |
|---|---|---|---|
date | string | - | Contribution date in YYYY-MM-DD format. |
count | number | - | Number of public contributions for that day. |
level? | number | - | Optional visual level from 0 to 4. Invalid or missing levels are calculated from count. |
Notes
- With
account, the component requestshttps://github-contributions-api.jogruber.de/v4/{account}?y=last. There is no GitHub token, OAuth step, or server route to configure. - The endpoint only exposes public activity. Private contributions cannot be recovered by this component.
- While the request is in flight, the graph keeps its final footprint with a skeleton. Invalid accounts and network failures are shown in place; older requests are cancelled when the account changes.
- Every cell is keyboard-focusable. Hovering or focusing a cell reveals a short date and contribution-count tooltip.
prefers-reduced-motiondisables the entrance and ambient motion.
Credits
Built by leo. Public contribution data is provided through the GitHub Contributions API.
Keep in mind
Most components on this site are inspired by or recreated from existing work across the web. I'm not here to take credit; just to learn, experiment, and sometimes push things a bit further. If something looks familiar and I forgot to mention you, reach out and I'll fix that right away.