Skip to content
GavinnnTannPublic

About

Transform your GitHub activity into an RPG-inspired developer character sheet. Level up, unlock legendary classes, and showcase your dev journey with zero config.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Latest commit

 

History

48 Commits

Folders and files

Repository files navigation

⚔️ GitLevel

Turn your GitHub profile into an RPG character card.

An animated SVG stats card for your GitHub profile README — class, level, XP, fame, and combo streak, generated from your public activity. No token, no config, nothing to install. Just an <img> tag.

Deploy with Vercel License: MIT Zero dependencies Cards served

gitlevel.vercel.app

GitLevel character card — class, level, XP, fame and combo streak

Traditional GitHub stats cards answer "what have you done?" GitLevel answers a more fun question: "who are you becoming as a developer?"

Use it in your README

Paste this in and swap in your GitHub username — that's the only change:

[![GitLevel](https://gitlevel.vercel.app/api/card?username=YOUR_GITHUB_LOGIN)](https://gitlevel.vercel.app/u/YOUR_GITHUB_LOGIN)

The link wraps the image so the card opens your character sheet — /u/YOUR_GITHUB_LOGIN — where the XP breakdown, the full class ladder, your season standing and every badge's next rung live. A bare ![...](...) still works, it just goes nowhere when clicked.

Already embedded a card? Cards used to be plain images, and a plain image in a README opens the image when clicked — not your sheet. The link lives in your markdown, so no update on our side can fix an embed that's already out there. Wrap what you have in [...](https://gitlevel.vercel.app/u/YOUR_LOGIN) and it becomes clickable:

- ![GitLevel](https://gitlevel.vercel.app/api/card?username=YOU&theme=volt)
+ [![GitLevel](https://gitlevel.vercel.app/api/card?username=YOU&theme=volt)](https://gitlevel.vercel.app/u/YOU)

Or with sizing and a theme — size it with card_width, not a fixed height: the card grows a row taller as you earn more badges, so a hardcoded height squashes it.

<a href="https://gitlevel.vercel.app/u/YOUR_GITHUB_LOGIN">
  <img src="https://gitlevel.vercel.app/api/card?username=YOUR_GITHUB_LOGIN&theme=volt&card_width=560" alt="GitLevel card" />
</a>

Running your own deployment? Swap gitlevel.vercel.app for your domain — see SETUP.md.

What's on the card

  • Class — your most-used language becomes an RPG profession (Python → Oracle, Rust → Sentinel, C++ → Warlord, …), with a crest glyph.
  • Subclass — your second language, drawn beneath your class as a matching mini crest with a glyph and accent colour of its own (Python Oracle, then C++ Warlord) — so the card shows both halves of what you actually write.
  • Level & XP — earned from craft, consistency, and a dampened dash of reach. Early levels come fast; the top tiers take real work.
  • Rarity — five bands (Common → Rare → Epic → Legendary → Mythic), shown by the stars, frame colour, and a crown at Legendary+.
  • Fame — followers + stars. Lifts your level without dominating it, and at truly elite reach sets a rarity floor.
  • Combo — your contribution streak in days. Consistency is craft, so a long streak lifts your level too.
  • Season rank — one line (S3 ’26 · SILVER) for the current quarter. Level is a career and barely moves once you're established; this moves weekly. See Seasons.
  • Achievement badges — earned independent of level, so a newer dev still has something to show off. Most evolve as you grow (On a Roll → Ablaze → Inferno → Eternal Flame), and a few rare pins are inferred from the shape of an account rather than any single number. The card shows your best four so the crest keeps top billing; the rest — and what each one's next rung costs — live on your character sheet. ?badges=N if you want more.

A GitHub username is the only required input; everything else is inferred. Click the card and it opens your character sheet at /u/YOUR_LOGIN.

All 14 badge families

Nine are ladders — you only ever display the highest rung you've reached, so a family is worth at most one badge and the card never fills up with near-misses:

Family Signal Rungs
🔥 Streak contribution streak On a Roll 7d → Ablaze 30d → Inferno 100d → Eternal Flame 365d
🌐 Languages languages shipped Polyglot 3 → Hyperpolyglot 6 → Babel 10
🤝 Reviews PR reviews (past yr) Collaborator 10 → Gatekeeper 100 → Guardian 500
📦 Repos repos created Founder 5 → Architect 20 → Worldbuilder 50
⭐ Stars stars earned Starstruck 100 → Constellation 1k → Supernova 10k
⏳ Tenure account age Veteran 5y → Elder 10y → Ancient One 15y → Day One 17y
⚓ Merged PRs merged PRs Shipwright 25 → Fleetmaster 150 → Armada 500
📡 Followers followers Beacon 100 → Luminary 1k → Icon 10k
🐛 Issues issues closed Bug Hunter 25 → Exorcist 150 → Purifier 500

Plus 🌱 Rising — under a year old with 30+ commits. It expires, on purpose: it exists to give a brand-new account something on day one.

Four are rare and inferred from the shape of an account. Each is a conjunction, which is what makes them uncommon and what lets them say something no single count can:

Badge Earned when
✨ Mentor 50+ reviews and 2× your own merged PRs — you review more than you ship
🐺 Lone Wolf 10+ repos, 300+ commits, almost no reviews — you build alone
🎭 Renaissance 6+ languages and 100+ stars and 25+ reviews
⚡ Prolific 2,000+ commits in the last 12 months alone

Rare badges — the bold top rungs plus all four inferred ones — render with a brighter fill, a stronger rim and a glass sheen, and always sort to the front so they're the ones that survive if a row runs out of space.

Streak, reviews and commits are last-12-months; stars, followers, repos, merged PRs, closed issues and tenure are lifetime. Thresholds account for the difference. Single source of truth: src/achievements.js.

Classes

Your most-used language becomes your class, promoted through five tiers as you level — shown here at Legendary rank, with full regalia (emblem, rune ring, crown, 4 of 5 stars):

Python — Archoracle TypeScript — High Arbiter
Rust — Eternal Guardian Go — Wayfinder
All 30 class ladders, across 31 languages, and their five tiers
Language Common Rare Epic Legendary Mythic
Python Adept Oracle Seer Archoracle Godseer
TypeScript Scribe Arbiter Justicar High Arbiter Lawgiver
JavaScript Wanderer Maverick Outrider Legend Mythmaker
Rust Watchman Sentinel Guardian Eternal Guardian Undying
Go Explorer Pathfinder Trailblazer Wayfinder Worldwalker
Java Steward Chancellor Magistrate Grand Chancellor Sovereign
C++ Soldier Warlord Conqueror Overlord Warbringer
C# Enchanter Spellsmith Spellmaster Archsmith Runelord
Ruby Performer Virtuoso Maestro Grand Maestro Luminary
PHP Tinkerer Artificer Inventor Master Artificer Demiurge
Kotlin Disciple Ascendant Exemplar Paragon Ascended
Swift Fencer Duelist Champion Grand Duelist Blademaster
C Operator Machinist Systemwright Kernel Lord Machine God
Zig Kindler Voltmage Tempest Stormlord Thunderking
Lua Moonling Lunar Adept Moon Sage Selenarch Moonlord
Verilog / VHDL Drafter Circuitwright Logic Architect Chip Lord Silicon Sovereign
Elixir Brewer Alchemist Potion Sage Grand Alchemist Philosopher
Haskell Scholar Lambda Adept Monadic Sage Category Archon The Pure
Shell Scripter Shellbinder Daemoncaller Terminal Lord Root Sovereign
Dart Thrower Marksman Sharpshooter Deadeye Truesight
Scala Climber Ridgewright Summit Sage Peak Lord Skybreaker
R Analyst Statmage Data Augur Grand Statistician Numbermancer
SQL Clerk Archivist Query Weaver Grand Archivist Data Warden
Assembly Bitsmith Ironhand Forgewright Anvil Lord Worldforger
Julia Stargazer Starcaller Astral Sage Celestial Magus Cosmarch
Ada Loomhand Patternwright Threadbinder Grand Weaver Fatespinner
Fortran Reckoner Tabulator Elder Numerist Ancient Reckoner Progenitor
COBOL Bookkeeper Auditor Vault Keeper High Auditor Eternal Ledger
Perl Sigilist Glyphbinder Scriptmage Arch-Sorcerer Wordbender
Erlang Nodekeeper Supervisor Crashbinder Lord of Nines The Unbroken

Any other language falls back to a generic path (Novice → Adept → Expert → Master → Grandmaster) so every developer still gets classed.

Your class comes from language bytes across your own, non-fork repos. If a data dump or vendored code skews it, drop those languages with exclude_langs.

Easiest way: enter your username on gitlevel.vercel.app and the forge lists the languages you actually ship as clickable chips — drop one and the preview and snippet update as you go, so you can't misspell a language into doing nothing. Or write it by hand:

[![GitLevel](https://gitlevel.vercel.app/api/card?username=YOU&exclude_langs=HTML,Jupyter%20Notebook,CSS)](https://gitlevel.vercel.app/u/YOU)

Exclusions only change which class you resolve to — XP never comes from language bytes, so dropping a language never costs you a level.

XP & levelling

XP blends craft, consistency, and a heavily dampened dash of reach — so what you built dominates, showing up daily counts, and a genuine legend whose work GitHub under-counts still gets recognized.

Contribution XP Multiplier Cap
Repo created 120 Tenure — per year on GitHub +75%
Merged pull request 65 Combo — per day of current streak +25%
Pull-request review 40
Closed issue 30
Commit 10
tenureMult = 1 + min(years, 15) × 0.05
comboMult  = 1 + min(streak, 365) / 365 × 0.25
fameXP     = min(40000, 48 × sqrt(followers + stars))   # √-damped, hard cap
totalXP    = craftXP × tenureMult × comboMult + streak × 8 + fameXP
level      = floor( sqrt( totalXP / 100 ) )             # XP for level L = 100 × L²

Tenure and combo amplify craft rather than adding flat XP, so an old but empty account still scores ≈ 0. Fame is added flat and sqrt-scaled: it tops out around Epic on its own, and Legendary+ still needs real craft underneath.

Level bands are front-loaded, so most active devs climb quickly and Mythic stays a rare summit:

Tier Levels Craft XP to reach¹ Stars
⚪ Common 1 – 5 0 ★
🔵 Rare 6 – 14 3,600 ★★
🟣 Epic 15 – 28 22,500 ★★★
🟢 Legendary 29 – 54 84,100 ★★★★
🔴 Mythic 55 + 302,500 ★★★★★

¹ Before tenure, combo, and fame — a long-tenured or famous dev reaches each tier with proportionally less raw craft.

Reach can also raise rarity directly. Elite Fame sets a tier floor — ≥120k → Legendary, ≥400k → Mythic — so a platform legend (Linus: Linux and Git) gets the frame, stars, and title to match, while the level number stays craft-honest. Thresholds this high can't be faked by one viral repo.

Single source of truth for these numbers: XP_WEIGHTS, BASE_XP, TENURE, COMBO, FAME in src/engine.js, and FAME_TIER_FLOORS in src/classes.js. This doc mirrors them.

Seasons

Level is a career. Season rank is this quarter.

The level curve is quadratic, which is honest but means an established dev's card effectively stops moving — Lv 30 → 31 is around 350 commits. So there's a second axis that runs on a weekly timescale: every calendar quarter is a season, and season XP counts only what you shipped inside that window.

Rank Season XP
Iron 0
Bronze 1,500
Silver 5,000
Gold 12,000
Mythril 30,000

Two deliberate rules:

  • Season rank is purely additive. A quiet quarter shows a low rank. It never touches your level, class, tier or badges, and nothing decays — rank decay is how a tool meant to flatter people starts making them resent it.
  • No multipliers. Tenure, combo and fame exist to make a career legible. A season is just "what did you make in these 90 days", and it reads the same for a newcomer and a fifteen-year veteran.

Finished seasons accumulate on the shelf on your character sheet. A season's mark can only be earned while that season is running — there is no way to go back and collect Season 1, which is the point.

Season XP uses PRs opened in the window, not merged: a windowed contributionsCollection is the only per-period signal GitHub exposes, and it counts openings. Lifetime XP still uses merged PRs. The two ladders are only ever compared to themselves. See src/seasons.js.

API

GET /api/card — the character card. /api is an alias, so both URLs work.

Param Type Default Notes
username string — required
theme enum volt volt · midnight · sunset · matrix · ice · transparent
exclude_langs string — comma-separated languages to ignore when picking your class (e.g. HTML,CSS)
hide_border bool false
title_color color theme hex without # (3/4/6/8) or CSS name
text_color color theme
bg_color color theme 00000000 = transparent, or a gradient deg,c1,c2
border_color color theme
glow_color color theme drives the neon glow filter
border_radius number 14 clamped 0–60
card_width int 500 clamped 440–800
badges int 4 how many earned badges the card shows, rarest first; 0 hides the strip. The full set (and each one's next rung) lives on your character sheet
cache_seconds int 21600 clamped 3600–86400 (6h default)
animation bool true false renders a static card
creator bool true false shows a creator's real class instead of the sigil

The card accent is tinted by your class colour automatically; theme params control the surrounding chrome.

GET /api/profile?username=… — the same character as JSON: level, class and its full five-title ladder, rarity + division, the XP breakdown (every contribution row, the tenure/combo multipliers, the flat streak and fame bonuses), every badge family with its next rung and how far off it is, plus the tunable config so a client can re-run the model itself. Accepts exclude_langs and creator like the card. Unlike the card this answers real status codes (404 unknown user, 429 rate-limited, 503 upstream) — the always-200 rule exists to protect a README <img>, and there isn't one here.

GET /u/USERNAME — the character sheet the linked card opens: the card itself, where the XP came from, the class ladder, the season standing and shelf, and every badge's next rung.

It's a public record, not a control panel. Anyone can open anyone's sheet, so it describes its subject rather than addressing whoever's reading, and it takes no settings — configuration happens once, at embed time, in the forge. The one interactive piece is What if?, which configures nothing: it runs the real XP model client-side from the config block /api/profile returns (not a second copy of the formula) so you can see what twenty more merged PRs would be worth. That serves a curious visitor as much as the person on the card.

Built on /api/profile, so the page is a static asset and the data is cached once for both it and the card.

GET /api/stats — returns { enabled, uniqueUsers, cardsServed } for a deployment. Requires the optional Upstash env vars (SETUP.md); without them it answers enabled: false with both counters at 0 rather than erroring. The cards served badge above and the counter on the landing page both read this endpoint, so they go live the moment Upstash is configured — and show nothing at all until then.

Themes

volt
volt theme — electric blue
midnight
midnight theme — violet
sunset
sunset theme — orange/red
matrix
matrix theme — green
ice
ice theme — cyan
transparent
no background — blends into any README

All motion runs once on load and settles (plus a soft glow pulse on the level), and cards respect prefers-reduced-motion.

How it works

README <img> → GitHub Camo → /api/card (Vercel serverless, holds the token)
             → per-user cache → GitHub GraphQL → stat engine → animated SVG
             → Cache-Control headers so Camo/CDN absorb repeat views
  • Zero runtime dependencies — fetch and template strings, nothing else.
  • Layered caching. The CDN caches each rendered URL; beneath it a per-instance cache keyed on username alone holds the raw GraphQL payload, so one user in six themes is six CDN keys but one API call. With Upstash configured, a durable third layer survives cold starts.
  • Errors never break the image slot — unknown user, rate limits, and bad tokens all render a small error SVG with HTTP 200.
  • All query params are validated and escaped before touching SVG markup.

Deploy your own

You don't need to — anyone can use the public deployment above. But it's ~2 minutes if you want your own domain and rate-limit budget:

→ SETUP.md — one-click deploy, environment variables, and local development.

Credits

License

MIT

About

Transform your GitHub activity into an RPG-inspired developer character sheet. Level up, unlock legendary classes, and showcase your dev journey with zero config.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages