Generate beautiful, always-fresh SVG stats cards for your GitHub profile README. Stats are fetched live on every view — no stale snapshots.
| Streak Card |
|---|
| Stats Card | Languages Card |
|---|---|
- Always current — no long-lived CDN cache; GitHub's camo proxy re-fetches on every README view
- 5 themes — dark, light, radical, tokyonight, gruvbox
- 10 stats — stars, commits, PRs, issues, forks, repos, followers, following, member since, top languages
- Contribution streak — current streak, longest streak, and total contributions in a three-panel card
- Animated SVGs — fade-in stats, growing language bars, rank ring fill (works in GitHub
<img>sandboxing) - Error SVGs — missing username, rate limit, bad token all return a styled SVG (never broken images)
- Username restriction —
ALLOWED_USERNAMEenv var prevents others from using your token on their profiles - Web UI — live preview with theme switcher and one-click markdown copy
git clone https://github.com/YOUR_USERNAME/Github-Stats-Generator.git
cd Github-Stats-Generator
npm installcp .env.example .env.localEdit .env.local:
GITHUB_TOKEN=ghp_xxxxxxxxxxxxxxxxxxxx
ALLOWED_USERNAME=your-github-usernameGenerate a token at github.com/settings/tokens/new with scopes: read:user, public_repo.
npm run devVisit http://localhost:3000, enter a GitHub username, and click Generate.
Paste any or all snippets into your GitHub profile README.md:


Replace your-deployment.vercel.app with your actual Vercel URL and YOUR_USERNAME with your GitHub login.
Returns a 495×165 SVG streak card with three panels: total contributions, current streak, and longest streak.
| Parameter | Values | Default | Description |
|---|---|---|---|
username |
any GitHub login | — | Required |
theme |
dark · light · radical · tokyonight · gruvbox |
dark |
Color scheme |
hide_border |
true · false |
false |
Hide card border |
Returns a 495×205 SVG stats card.
| Parameter | Values | Default | Description |
|---|---|---|---|
username |
any GitHub login | — | Required |
theme |
dark · light · radical · tokyonight · gruvbox |
dark |
Color scheme |
hide_border |
true · false |
false |
Hide card border |
Returns a 300×variable-height SVG language bar card.
| Parameter | Values | Default | Description |
|---|---|---|---|
username |
any GitHub login | — | Required |
theme |
same as above | dark |
Color scheme |
hide_border |
true · false |
false |
Hide card border |
Returns raw JSON stats (useful for debugging).
{
"name": "Your Name",
"login": "your-username",
"stars": 1234,
"commits": 512,
"prs": 208,
"issues": 64,
"forks": 89,
"repos": 42,
"followers": 300,
"following": 45,
"memberSince": 2019,
"rank": "A+",
"topLanguages": [
{ "name": "TypeScript", "color": "#3178c6", "percentage": 45.2 }
]
}| Name | Preview |
|---|---|
dark |
Background #0d1117 · Accent #58a6ff |
light |
Background #fffefe · Accent #2f80ed |
radical |
Background #141321 · Accent #fe428e |
tokyonight |
Background #1a1b27 · Accent #70a5fd |
gruvbox |
Background #282828 · Accent #fabd2f |
Rank is computed from a weighted score: stars×2 + commits×1.5 + PRs×3 + issues + followers×0.5
| Rank | Score |
|---|---|
| S | ≥ 5,000 |
| A+ | ≥ 2,000 |
| A | ≥ 1,000 |
| B+ | ≥ 500 |
| B | ≥ 200 |
| C | < 200 |
- Server-side cache: 60-second in-memory TTL — absorbs traffic spikes without hammering the GitHub API (which allows 5,000 authenticated requests/hour).
- HTTP response headers:
Cache-Control: public, max-age=0, s-maxage=0, must-revalidate— GitHub's camo proxy re-fetches from the server on every README page view. - Result: Stats are at most ~60 seconds old on the server; GitHub's camo has a hard minimum of ~5 minutes between re-fetches, so README visitors see stats updated within 5 minutes.
app/
api/
streak/route.ts GET /api/streak → SVG image
stats/route.ts GET /api/stats → SVG image
langs/route.ts GET /api/langs → SVG image
data/route.ts GET /api/data → JSON
page.tsx Web UI
layout.tsx
globals.css
lib/
github/
types.ts TypeScript interfaces
queries.ts GitHub GraphQL queries
client.ts Fetch wrapper + error types
fetcher.ts Stats orchestrator + data normalizer
streak-fetcher.ts Streak orchestrator (parallel year fetching + streak algorithm)
svg/
themes.ts 5 color schemes
icons.ts Inline octicon SVG paths
utils.ts escapeXml, formatNumber, computeRank, renderErrorCard
stats-card.ts renderStatsCard() → SVG string
langs-card.ts renderLangsCard() → SVG string
streak-card.ts renderStreakCard() → SVG string
cache.ts In-memory TTL cache (stats + streak)
components/
username-form.tsx
theme-selector.tsx
card-preview.tsx
copy-button.tsx
embed-instructions.tsx
.env.example Documented environment variable template
- Push your fork to GitHub
- Import the repo at vercel.com/new
- Add environment variables in the Vercel project settings:
GITHUB_TOKEN— your personal access tokenALLOWED_USERNAME— your GitHub username (prevents others from using your instance)
- Deploy — Vercel will assign a URL like
https://your-project.vercel.app - Update your README embed URLs to use that domain
| Variable | Required | Description |
|---|---|---|
GITHUB_TOKEN |
Yes | GitHub PAT with read:user and public_repo scopes |
ALLOWED_USERNAME |
No | If set, the API only serves stats for this username |
- Next.js 16 (App Router)
- TypeScript
- Tailwind CSS
- GitHub GraphQL API v4
- SVG with SMIL animations (no JavaScript, works in GitHub
<img>sandboxing)
MIT