English-only SVG GitHub stats cards for profile READMEs.
This project is a smaller, modern alternative inspired by GitHub Readme Stats. It focuses on reliable self-hosted README cards, simple URLs, typed TypeScript internals, and a deliberately small feature surface.
- Features
- Quick Start
- Live Demos
- GitHub Stats Card
- Top Languages Card
- Themes and Styling
- Renderer and Fonts
- Private Stats
- Caching
- Self-Hosting
- Local Development
- Environment Variables
- What v0.4.0 Does Not Support
- Original-inspired profile stats card as SVG, inside this project's rounded frame.
- Top languages card as SVG.
- English-only labels.
- Built-in themes:
default,dark,github,tokyonight,radical,merko,gruvbox,onedark, andcobalt. - Hex color overrides for title, text, icons, rank ring, background, and border.
- Optional hidden title and border.
- Public stats by default.
- Private-visible stats only when explicitly requested and allowlisted by the deployment owner.
- GitHub GraphQL API access through a server-side
GITHUB_TOKEN. - Vercel-friendly cache headers.
- SVG error cards instead of JSON errors for README embeds.
- Resvg-backed SVG measurement with bundled Google Sans Flex fonts.
Use the hosted deployment URL, replacing D-Naveenz with the GitHub username you want to display:

Use standard Markdown image syntax, or wrap the image in a link:
[](https://github.com/D-Naveenz)The hosted Vercel app can be used directly in GitHub profile READMEs.
Endpoint:
/api/stats.svg?username=<github-login>Example:
The stats card displays:
- Total stars across owned non-fork repositories.
- Total commits from the GitHub GraphQL contribution commit count.
- Total pull requests.
- Total issues.
- Contributed repository count.
- Rank circle, visible by default.
The v0.4.0 stats card uses original-inspired stat content inside this project's cleaner rounded frame. Rows are rendered through the internal SVG compiler and StackPanel gap layout, while the rank circle is placed as a right-side column. The outer card auto-sizes from measured SVG bounds.
| Parameter | Required | Values | Default | Description |
|---|---|---|---|---|
username |
Yes | GitHub login | none | User to render stats for. |
theme |
No | default, dark, github, tokyonight, radical, merko, gruvbox, onedark, or cobalt |
default |
Built-in card theme. |
title_color |
No | 6-digit hex | theme value | Header text color. |
text_color |
No | 6-digit hex | theme value | Main text color. |
icon_color |
No | 6-digit hex | theme value | Stat icon color. |
ring_color |
No | 6-digit hex | theme value | Rank circle color. |
bg_color |
No | 6-digit hex | theme value | Card background color. |
border_color |
No | 6-digit hex | theme value | Card border color. |
hide_border |
No | true, false |
false |
Hides the border when true. |
hide_title |
No | true, false |
false |
Hides the card title when true. |
show_icons |
No | true, false |
true |
Shows or hides stat icons. |
hide_rank |
No | true, false |
false |
Shows or hides the rank circle. |
line_height |
No | integer from 16 to 40 |
25 |
Vertical spacing between stat rows. |
hide |
No | stars, commits, prs, issues, contribs |
none | Comma-separated stat keys to hide. |
include_private |
No | true, false |
false |
Requests private-visible data, only for allowlisted usernames. |
Endpoint:
/api/languages.svg?username=<github-login>Example:
The languages card aggregates language byte sizes from owned, non-fork repositories and sorts languages by total size. The default bar layout shows each language with a progress bar, while compact gives a denser two-column summary.
Bar layout, the default:
Compact layout:
| Parameter | Required | Values | Default | Description |
|---|---|---|---|---|
username |
Yes | GitHub login | none | User to render languages for. |
layout |
No | bar, compact |
bar |
Language card layout. |
limit |
No | integer from 1 to 12 |
6 |
Maximum number of languages to show. |
theme |
No | default, dark, github, tokyonight, radical, merko, gruvbox, onedark, or cobalt |
default |
Built-in card theme. |
title_color |
No | 6-digit hex | theme value | Header text color. |
text_color |
No | 6-digit hex | theme value | Main text color. |
bg_color |
No | 6-digit hex | theme value | Card background color. |
border_color |
No | 6-digit hex | theme value | Card border color. |
hide_border |
No | true, false |
false |
Hides the border when true. |
hide_title |
No | true, false |
false |
Hides the card title when true. |
include_private |
No | true, false |
false |
Requests private-visible data, only for allowlisted usernames. |
Use the theme query parameter:


Supported themes:
| Theme | Description |
|---|---|
default |
Light GitHub-inspired card. |
dark |
Dark card using GitHub dark-style colors. |
github |
Soft GitHub panel style with green accent. |
tokyonight |
Dark blue/purple Tokyo Night-style palette. |
radical |
Pink and cyan original-inspired palette. |
merko |
Green-on-dark original-inspired palette. |
gruvbox |
Warm Gruvbox dark palette. |
onedark |
One Dark-inspired palette. |
cobalt |
Blue Cobalt-inspired palette. |
You can override theme colors with 6-digit hex colors, with or without #:
GitHub README images can use theme fragments for light and dark mode:

v0.4.0 includes a local SVG renderer compiler that converts higher-level card nodes into svg-builder-compatible SVG output. Card renderers describe content using reusable keyed style resources and container components; the Card component measures the foreground SVG and derives the final root size and background surface.
Measurement uses @resvg/resvg-js and bundled Google Sans Flex static fonts from fonts/. There is no URL parameter or environment switch for measurement engines; resvg is the canonical renderer measurement path. If exact text metrics drift in a deployment environment, check that the bundled font files are deployed with the app.
StackPanel provides WinUI-like vertical or horizontal flow with a numeric gap, so repeated rows do not need trailing margins.
Public stats are the default and are safe for any requested username.
Private-visible stats require all of the following:
- The deployment has a
GITHUB_TOKEN. - The requested URL includes
include_private=true. - The requested username is listed in
PRIVATE_STATS_USERS. - The configured token can actually see the requested private data.
Example:
Important behavior:
- Your PAT cannot read another user's private repositories or private contributions unless GitHub grants that token access.
- If
include_private=trueis requested for a username not inPRIVATE_STATS_USERS, the endpoint returns an SVG error card. - This project does not accept PATs in query parameters.
SVG cards are designed for README embeds and CDN caching.
Success responses use:
Cache-Control: public, max-age=0, s-maxage=86400, stale-while-revalidate=86400Error responses use shorter CDN caching:
Cache-Control: public, max-age=0, s-maxage=600, stale-while-revalidate=86400In NODE_ENV=development, caching is disabled.
GitHub may also proxy and cache README images through its own image infrastructure, so updates may not appear instantly in profile READMEs.
The project is designed for Vercel, but it is a standard Express app and can run anywhere Node.js is supported.
- Fork or clone this repository.
- Import it into Vercel.
- Add
GITHUB_TOKENin the Vercel project environment variables. - Optionally add
PRIVATE_STATS_USERS. - Deploy from the main branch.
The exported Express app lives in src/app.ts, which Vercel can use as the server entry. src/index.ts re-exports the same app for local server startup.
Use a fine-grained or classic GitHub Personal Access Token as the server-side GITHUB_TOKEN.
Recommended minimum:
- Read-only access.
- Public repository data for public-only cards.
- Private repository read access only if you want private-visible stats for allowlisted usernames.
Do not expose the token in README URLs, frontend code, screenshots, or committed files.
Install dependencies:
pnpm installCreate a local .env from .env.example:
GITHUB_TOKEN=github_pat_your_token_here
PRIVATE_STATS_USERS=D-Naveenz
PORT=3000Run locally:
pnpm devpnpm dev uses tsx watch, so source changes restart the local Express server automatically. Use pnpm dev:compiled when you specifically want to test the compiled .dev-dist runtime path.
Open:
http://localhost:3000
http://localhost:3000/healthz
http://localhost:3000/api/stats.svg?username=D-Naveenz
http://localhost:3000/api/languages.svg?username=D-NaveenzValidate:
pnpm build
pnpm typecheck
pnpm test
pnpm format:checkVS Code tasks are included for development, testing, formatting, and full validation.
The renderer depends on @resvg/resvg-js, which ships native Node bindings through prebuilt packages. The project keeps SVG output as SVG; resvg is used only for compile-time measurement.
| Variable | Required | Example | Description |
|---|---|---|---|
GITHUB_TOKEN |
Yes for live GitHub data | github_pat_... |
Server-side GitHub token used for GraphQL API calls. |
PRIVATE_STATS_USERS |
No | D-Naveenz,octocat |
Comma-separated usernames allowed to request include_private=true. |
PORT |
No | 3000 |
Local dev server port. |
NODE_ENV |
No | development |
Disables cache headers when set to development. |
v0.4.0 intentionally does not support:
- Multilingual labels.
- Repo pin cards.
- Gist cards.
- WakaTime cards.
- Legacy
github-readme-statsroute or parameter compatibility. - Passing GitHub tokens through query parameters.
- Per-request private stats for arbitrary users.
- Public URL/query styling for internal renderer layout resources.
These limits keep the implementation smaller, safer, and easier to operate.