Introducing Vanity: Sync Your GitHub Contributions Across Accounts
If you’ve ever had more than one GitHub account - a personal one and a work one, or an old employer’s account you can’t log into anymore - you know the feeling. Your contribution graph on each account only tells part of the story. You shipped every day last year, but your personal GitHub looks like you took three months off because that work happened on a different account.
This has bugged me for years. So I built vanity.
The Problem
GitHub’s contribution graph is tied to a single account. If you contribute from multiple accounts, each graph is incomplete. There’s no built-in way to combine them.
People have hacked around this with cron jobs that create fake commits, or scripts that rewrite git history, but those approaches are fragile, hard to share between accounts, and usually involve committing credentials somewhere uncomfortable.
I wanted something that:
- Worked across any number of accounts
- Was incremental (only sync new activity)
- Shared nothing sensitive (no code, no commit messages, no repo names)
- Was easy to set up and run
How Vanity Works
The core idea is simple. You create a shared private repository and invite all your accounts as collaborators. Each account runs vanity sync, which:
- Exports your contribution data (just dates and counts) to a JSON file in the repo
- Imports other collaborators’ contribution data
- Creates mirror commits - empty commits backdated to match the contribution dates
GitHub counts a commit toward your graph if you authored it and it lives in a repo you have access to. So once the mirror commits exist in the shared repo, every collaborator’s graph shows the combined activity.
Shared Private Repo
┌──────────────────────────────────────┐
│ .vanity/ │
│ alice.json ── date/count pairs │
│ bob.json ── date/count pairs │
│ │
│ + empty mirror commits │
│ (backdated to contribution dates) │
└──────────────┬───────────────┬───────┘
│ │
vanity sync vanity sync
│ │
Alice's Bob's
Account Account
Quick Start
# Create a shared private repo
gh repo create vanity-sync --private --clone
cd vanity-sync
# Initialize and sync
vanity init
vanity sync
Then from your other account:
git clone https://github.com/you/vanity-sync.git
cd vanity-sync
vanity sync
That’s it. Both accounts now show combined contribution activity.
Importing Old Accounts
The feature I use most is import. If you have an old work account you can’t log into anymore, you can still pull its public contribution data:
vanity import old-work-username
vanity sync
If the account had private contributions enabled on their profile, you can scrape those too:
vanity import --scrape old-work-username
This fetches the contribution counts from the HTML of the GitHub profile page, which includes private activity that the API doesn’t expose.
Privacy
This was a hard design constraint from the start. The only data shared between accounts is dates and counts: “2024-03-15: 7 contributions.” No repository names, no commit messages, no code, no diffs, no file names. The JSON files in .vanity/ are the entire data model, and they contain nothing about what you worked on.
The mirror commits themselves are empty - no file changes, just a generic message like vanity: mirror from alice.
Batch Pushing and Rebuild
Two features that came from real usage:
Batch pushing (--batch-size N) exists because GitHub’s contribution indexer can drop older backdated commits when too many are pushed at once. If you’re importing years of history, pushing in batches of 100 avoids this edge case.
Rebuild (--rebuild) wipes the commit history and re-mirrors everything from scratch. Useful when contributions are missing from the graph or when you want a clean slate.
Install
# Homebrew
brew install wdm0006/tap/vanity
# Or grab a binary
# https://github.com/wdm0006/vanity/releases
# Or Go install
go install github.com/wdm0006/vanity/cmd/vanity@latest
Vanity requires the GitHub CLI (gh) to be installed and authenticated. All API calls go through gh, so there’s no separate token setup.
Check out the repo: github.com/wdm0006/vanity
Stay in the loop
Get notified when I publish new posts. No spam, unsubscribe anytime.