A single SVG widget you drop into your GitHub profile README. It scores
your account, charts your contribution timeline, highlights your top
collaborators, breaks down your languages, tracks your commit streaks,
and earns you tags like Backend, ML, or Founder #42.
That card is live, not a screenshot. Swap in your own username:
Table of contents (click to expand)
-
Sign in with GitHub. Signing in is how you prove ownership of the username, and it unlocks the editor.
-
Pick a theme, reorder widgets, add any custom tags or achievements.
-
Click Generate.
-
Paste this one line into your profile README:

The image URL is stable. Once it's in your README you can change themes, tags, or widget order in the editor at any time without touching the markdown.
Note
Only public GitHub activity is counted. Private repos, private commit counts, and contributions to org-restricted repos are never visible to the fetcher.
Pass ?theme=<name> on the URL, or pick one in the editor.
| Theme | Preview |
|---|---|
midnight (default) |
|
onyx |
|
nord |
|
clean |
|
paper |
Add GitHub's theme suffix to serve a different image to dark vs. light viewers:

Or use <picture> for precise prefers-color-scheme control:
<picture>
<source srcset="https://gh-stats.com/api/YOUR_USERNAME?theme=onyx"
media="(prefers-color-scheme: dark)" />
<source srcset="https://gh-stats.com/api/YOUR_USERNAME?theme=clean"
media="(prefers-color-scheme: light)" />
<img src="https://gh-stats.com/api/YOUR_USERNAME" />
</picture>Every widget is independently addressable at
https://gh-stats.com/api/<username>/<widget>.svg. Embed one, two, or all
of them.
Overall score (0 to 100), letter grade, and your top role tags.
Your contribution volume over the last 6 months, drawn as a smooth area chart.
Current and longest contribution streaks.
The people you actually work with, filtered down to repos of a
reasonable size so a drive-by PR to react does not put the React team
on your card.
What you have actually been working on lately, grouped by topic.
Your language mix, weighted by bytes in repos you authored. Forks with no meaningful contribution are ignored.
Hand-entered lines for hackathons, talks, awards, and certifications.
GitHub strips inline CSS, so an HTML table is the simplest way to put two widgets next to each other.
<table><tr>
<td><img src="https://gh-stats.com/api/YOUR_USERNAME/grade.svg" /></td>
<td><img src="https://gh-stats.com/api/YOUR_USERNAME/languages.svg" /></td>
</tr></table>anuraghazra/github-readme-stats
is the card most profile READMEs use, and it is a good project. Its README now
carries a deprecation notice pointing at a successor, so if you are looking to
move, the common URL shapes work here with only the domain changed.
| Your current URL | Change it to |
|---|---|
github-readme-stats.vercel.app/api?username=U |
gh-stats.com/api?username=U |
github-readme-stats.vercel.app/api/top-langs?username=U |
gh-stats.com/api/top-langs?username=U |
github-readme-streak-stats.herokuapp.com/?user=U |
gh-stats.com/api/streak/U |
Nothing else in your README changes.
Note
theme= is honoured on the composite card (/api/<user>). On the
compatibility and single-widget URLs above it is currently ignored and the
default theme is served.
If you would rather replace several badges with one image, use the composite card instead and delete the rest:
Every URL accepts query parameters. They override the owner's saved settings on a per-embed basis, so viewers can tweak the look without changing anything the owner has stored.
Values with special characters must be URL-encoded: #a78bfa becomes
%23a78bfa, a space becomes %20.
| Parameter | What it does | Example |
|---|---|---|
theme |
Built-in theme name. | ?theme=onyx |
widgets |
Which widgets to show on the composite card. | ?widgets=grade,streaks,languages |
order |
Render order on the composite card. | ?order=grade,streaks,languages |
hide |
Languages to exclude from the languages widget. | ?hide=HTML,CSS,Makefile |
tags |
Extra custom role tags on the grade widget. | ?tags=ML,Systems |
Use dot notation: <widget>.<key>=<value>.
| Parameter | What it does | Type | Default |
|---|---|---|---|
grade.max_tags |
Max role tags shown (1 to 20). | int | all tags |
impact.line_color |
Accent color for the area curve. | hex color | theme accent |
streaks.color |
Accent color for the current-streak text. | hex color | theme accent |
collaborators.max_count |
Max collaborators shown (1 to 10). | int | 5 |
collaborators.bar_color |
Accent color for the commit bars. | hex color | theme accent |
focus.max_categories |
Max focus clusters shown (1 to 10). | int | 6 |
languages.max_languages |
Max languages shown (1 to 10). | int | 5 |
achievements.max_items |
Max achievement rows shown (1 to 10). | int | 5 |
Some tags on the grade card are earned from real activity. No query parameter will add them if you have not earned them:
Founder #Nis your enrollment number, fixed when you first sign in.- Role tags like
Backend,Frontend,ML,Mobile,DevOps,Cloud,Systems,Database,Securityare derived from your language mix and repo topics.
The refresh cron re-pulls GitHub data every 15 minutes, so new commits usually appear in your widget within that window. GitHub's image CDN may add another minute or two on top.
If you need an immediate update (for example right after merging something big), click Refresh now in the editor. It is a one-shot per account, so save it for when it matters.
The public instance at gh-stats.com is free and you do not need to run your
own. Self-host if you want your own rate limit, private repository data staying
on your hardware, or control over when cards rebuild.
You need Docker and a GitHub token. The token needs no scopes for public data; it exists to raise your GitHub API rate limit.
git clone https://github.com/ShayManor/github-readme-stats
cd github-readme-stats
cp .env.example .env # put your token in GITHUB_PAT
docker compose up -d --buildThen open http://localhost:5002 and embed from your own host:
Three services come up behind docker compose: fetcher talks to GitHub and
owns the token, generator renders the SVGs and serves the web UI on 5002, and
edge is a caching proxy on 5003 that serves cards at /<username>. Data lives
in ./data. Set GHSTATS_PORT to move the web UI off 5002.
Can I use a private GitHub account? No. The service only reads public activity. Private repos, private commit counts, and contributions to org-restricted repos are not visible to GitHub's public API, so they are never part of the widget.
How fresh is the data? Every 15 minutes, automatically. You can also click Refresh now once per account for an immediate update.
How do I edit my widget? Sign in with GitHub at https://gh-stats.com/api/. Only the account whose login matches the username can edit that widget's settings.
Can I change the widget without re-embedding? Yes. The image URL is stable. Edit in the editor, click Generate, and the next fetch serves the new version. GitHub's image cache may delay propagation by a few minutes.
Can I embed someone else's widget with my own theme or filters? Yes, use the query parameters. The owner's saved settings are not affected.
I am getting a placeholder card. What is wrong?
building means the first render is still in progress, give it a
minute. not_found means GitHub does not know that username.
Why does my languages card look wrong?
It counts bytes in repos you authored. Forks with little commit
activity are dropped. Add ?hide=HTML,CSS,Makefile if generated files
dominate the breakdown.
Can I reorder widgets?
Yes, either in the editor (drag and drop) or by passing
?widgets=...&order=... on the URL.
| midnight |
onyx |
| nord |
clean |
| paper |
custom (onyx, 3 widgets) |
| Grade |
Grade (max_tags=3) |
| Impact |
Impact (purple line) |
| Streaks |
Streaks (green) |
| Languages |
Languages (hide Shell, Dockerfile) |
| Collaborators |
Focus |
| Achievements |
Embed two widgets side by side with an HTML table:
<table><tr>
<td><img src="https://gh-stats.com/api/YOUR_USERNAME/grade.svg" /></td>
<td><img src="https://gh-stats.com/api/YOUR_USERNAME/languages.svg" /></td>
</tr></table>Stack a custom composite with only three widgets:
Recolor the impact line:
