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:

  1. Exports your contribution data (just dates and counts) to a JSON file in the repo
  2. Imports other collaborators’ contribution data
  3. 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