Generate beautiful, animated SVG badges with your GitHub statistics - including private repository data!
- Beautiful Design: Modern, animated SVG with smooth entrance effects
- Dark/Light Mode: Automatically adapts to user's system preferences
- Private Repo Support: Include statistics from your private repositories
- Minimal Dependencies: Only requires Jinja2 for SVG template rendering
- 6 Key Metrics:
- 📦 Public Repositories
- 🔒 Private Repositories
- 🤝 Contributed Repositories
- ✅ Merged Pull Requests
- 📝 Total Commits
- ➕ Lines Added
- Automated Updates: Runs on GitHub Actions schedule
- Customizable: Configure output path, markers, and more
Add the stats markers to your README.md where you want the badge to appear:
<!-- stats:start -->
<p align="center">
<img src="./gh_stats.svg" alt="jansitarski's GitHub Stats" />
</p>
<!-- stats:end -->Create .github/workflows/update-stats.yml in your repository:
name: Update GitHub Stats Badge
on:
schedule:
- cron: '0 0 * * 1' # Weekly on Monday at midnight UTC
workflow_dispatch:
permissions:
contents: write
jobs:
update-stats:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Generate stats badge
uses: jansitarski/gh-activity-badge@v1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
- name: Commit updated stats
uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: 'chore: update GitHub stats badge'
file_pattern: 'gh_stats.svg README.md'The default GITHUB_TOKEN works for public repos. For private repository statistics, you need to create a Personal Access Token (PAT):
- Go to GitHub Settings → Developer settings → Personal access tokens → Tokens (classic)
- Click "Generate new token (classic)"
- Give it a name like "GitHub Stats Badge"
- Select scopes:
- ✅
repo(Full control of private repositories) - ✅
read:user(Read user profile data)
- ✅
- Click "Generate token" and copy it
- Go to your repository → Settings → Secrets and variables → Actions
- Create a new secret named
STATS_TOKENand paste your token - Update the workflow to use your token:
github_token: ${{ secrets.STATS_TOKEN }}
- Manual Run: Go to Actions tab → Update GitHub Stats Badge → Run workflow
- Automatic: Runs on the schedule you configured
That's it! Your badge will be generated and automatically updated.
| Input | Description | Required | Default |
|---|---|---|---|
github_token |
GitHub token with repo and read:user scopes |
✅ Yes | - |
username |
GitHub username to generate stats for | No | ${{ github.repository_owner }} |
output_path |
Path where the SVG badge will be saved | No | gh_stats.svg |
readme_update |
Whether to automatically update README.md | No | true |
readme_path |
Path to the README file to update | No | README.md |
stats_start_marker |
HTML comment marker for stats injection start | No | <!-- stats:start --> |
stats_end_marker |
HTML comment marker for stats injection end | No | <!-- stats:end --> |
- name: Generate stats badge
uses: jansitarski/gh-activity-badge@v1
with:
github_token: ${{ secrets.STATS_TOKEN }}
username: octocat
output_path: assets/github-stats.svg
readme_update: 'true'
readme_path: profile/README.md
stats_start_marker: '<!-- BEGIN STATS -->'
stats_end_marker: '<!-- END STATS -->'Customize when the badge updates by modifying the cron expression:
on:
schedule:
# Every day at midnight UTC
- cron: '0 0 * * *'
# Every Monday at 2:00 AM UTC
# - cron: '0 2 * * 1'
# Every 6 hours
# - cron: '0 */6 * * *'
# First day of every month
# - cron: '0 0 1 * *'Cron expression generator can help you create custom schedules.
The simplest setup - just add markers and run the workflow:
# Hi there, I'm @username
<!-- stats:start -->
<!-- stats:end -->See examples/basic/ for full example.
Save the badge to a specific folder:
- name: Generate stats badge
uses: jansitarski/gh-activity-badge@v1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
output_path: assets/stats.svgThen reference it in your README:
See examples/advanced/ for full example.
Disable automatic README updates and place the badge manually:
- name: Generate stats badge
uses: jansitarski/gh-activity-badge@v1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
readme_update: 'false'Then add to your README:
<div align="center">
<img src="./gh_stats.svg" alt="My GitHub Stats" width="500"/>
</div>You can run the script locally or on self-hosted runners:
# Clone the repository
git clone https://github.com/jansitarski/gh-activity-badge.git
cd gh-activity-badge
# Install the package
pip install -e .
# Set environment variables
export GITHUB_USERNAME="your-username"
export GITHUB_TOKEN="your-personal-access-token"
export OUTPUT_PATH="gh_stats.svg"
# Run the script
python3 -m badge.mainSee examples/self-hosted/ for full example.
- Python: 3.8 or higher (requires Jinja2 — installed automatically in GitHub Actions)
- GitHub Token: With
repoandread:userscopes for private repo access - Permissions: Workflow needs
contents: writeto commit badge back to repo
-
Collects Metrics: Uses GitHub's GraphQL and REST APIs to fetch:
- Repository counts (public/private/contributed)
- Pull request and commit statistics
- Lines of code added across all merged PRs
-
Generates SVG: Creates a custom animated SVG with:
- Responsive dark/light mode theming
- Smooth entrance animations
- Grid pattern background with noise filter
- Timestamp showing last update
-
Updates README: Optionally injects the badge between your markers
-
Commits Changes: The workflow commits the updated badge and README
- ✅ Check that workflow has
contents: writepermission - ✅ Verify markers exist in README:
<!-- stats:start -->and<!-- stats:end --> - ✅ Check workflow runs in the Actions tab for errors
- ✅ Ensure token has
repoandread:userscopes
- ✅ You must use a Personal Access Token (PAT), not the default
GITHUB_TOKEN - ✅ PAT must have
reposcope selected - ✅ Pass the PAT as
github_token: ${{ secrets.YOUR_PAT_NAME }}
- GitHub API has rate limits (5,000 requests/hour for authenticated requests)
- The script makes approximately 10-20 API calls per run
- Recommended: Don't run more frequently than hourly
- ✅ Ensure the SVG path is correct (relative to README location)
- ✅ If README is in a subfolder, adjust
output_pathor image path - ✅ Verify the SVG file was committed to the repository
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
git clone https://github.com/jansitarski/gh-activity-badge.git
cd gh-activity-badge
# Run locally for testing
pip install -e ".[dev]"
export GITHUB_USERNAME="testuser"
export GITHUB_TOKEN="your-token"
python3 -m badge.mainThis project is licensed under the MIT License - see the LICENSE file for details.
- Inspired by various GitHub profile badge generators
- Built with Python and Jinja2
- Uses GitHub's GraphQL and REST APIs
If you find this project useful, please consider:
- ⭐ Starring the repository
- 🐛 Reporting issues
- 🔀 Contributing improvements
- 📢 Sharing with others
Made with ❤️ by Jan Sitarski