claude-count-tokens
v1.2.0
Published
GitHub-style heatmap widgets showing Claude, Codex, and combined local AI token usage.
Maintainers
Readme
claude-count-tokens
A GitHub-style contribution heatmap for local AI token usage. The Claude widget counts Claude Code plus Conductor Claude API usage; the Codex widget counts local Codex/OpenAI usage.
┌─────────────────────────────────────────────────────────────┐
│ Your Claude Code Token Usage 2026 │
│ │
│ Mon ░░▒▒░░▓▓░░▒▒░░██▒▒░░▓▓░░▒▒░░██░░▒▒░░▓▓░░▒▒░░██░░ │
│ Wed ▒▒░░▓▓░░██░░▒▒░░▓▓░░██▒▒░░▓▓░░▒▒░░██░░▒▒░░▓▓░░██ │
│ Fri ░░██▒▒░░▓▓░░▒▒░░██▒▒░░▓▓░░▒▒░░██░░▓▓░░▒▒░░██░░▒▒ │
│ │
│ Less ░░▒▒▓▓██ More 1.2M tokens │
└─────────────────────────────────────────────────────────────┘Quick start
npx claude-count-tokens login # 1. log in with GitHub
npx claude-count-tokens sync # 2. upload your token data
npx claude-count-tokens sync --install # 3. auto-sync every hourThen add the Claude widget to your website:
<script src="https://unpkg.com/claude-count-tokens/widget/claude-token-heatmap.js"></script>
<claude-token-heatmap user="YOUR_GITHUB_USERNAME" palette="spring"></claude-token-heatmap>Or add the Codex widget:
<script type="module" src="https://unpkg.com/claude-count-tokens/widget/codex-token-heatmap.js"></script>
<codex-token-heatmap user="YOUR_GITHUB_USERNAME" palette="signal"></codex-token-heatmap>Or add one combined Claude + Codex widget:
<script type="module" src="https://unpkg.com/claude-count-tokens/widget/ai-token-heatmap.js"></script>
<ai-token-heatmap user="YOUR_GITHUB_USERNAME" palette="duo"></ai-token-heatmap>That's it. Your heatmap stays up to date automatically.
How it works
Your Mac Cloud Your Website
┌────────────────┐ ┌──────────────┐ ┌──────────────────┐
│ │ sync │ │ fetch │ │
│ local usage │ ────────> │ Supabase │ <────────── │ token heatmap │
│ sources │ (hourly) │ Storage │ (on load) │ widgets │
│ │ │ │ │ │
│ ~/.claude/ │ │ yourname │ │ Renders the │
│ ~/.codex/ │ │ .json │ │ heatmap widget │
│ │ │ │ │ │
└────────────────┘ └──────────────┘ └──────────────────┘
│ │
│ launchd runs │
│ sync every hour │
└── automatically ─────────────────────────────────────────>│
keeps your widget up to date- Login — authenticates you via GitHub so we know your username
- Sync — reads local Claude and Codex aggregate usage, then uploads small JSON files
- Auto-sync — a background job on your Mac re-syncs every hour so your widget is always current
- Widget — a self-contained web component that fetches your JSON and renders the heatmap
No data leaves your machine except the aggregated token counts (no prompts, no code, no conversation content).
Step-by-step setup
1. Log in
npx claude-count-tokens loginThis opens your browser for GitHub login. Once authenticated, you'll see:
Opening browser for GitHub login...
✓ Logged in as vitoria
Your Claude widget embed:
<claude-token-heatmap user="vitoria" palette="spring">
Your Codex widget embed:
<codex-token-heatmap user="vitoria" palette="signal"></codex-token-heatmap>
Your combined AI widget embed:
<ai-token-heatmap user="vitoria" palette="duo"></ai-token-heatmap>2. Sync your data
npx claude-count-tokens sync Parsing local token data...
Found 1.2M Claude tokens across 84 days
Found 800K Codex tokens across 12 days
Uploading to cloud...
✓ Synced to cloud. Widget is live.3. Set up auto-sync (recommended)
npx claude-count-tokens sync --installThis installs a background job that syncs every hour. You never have to think about it again.
✓ Installed background sync (runs every hour)
Logs: ~/.claude-count-tokens/sync.log
To uninstall: npx claude-count-tokens sync --uninstall4. Add the widget to your site
Add these two lines anywhere in your HTML:
<script src="https://unpkg.com/claude-count-tokens/widget/claude-token-heatmap.js"></script>
<claude-token-heatmap user="YOUR_GITHUB_USERNAME" palette="spring"></claude-token-heatmap>For Codex:
<script type="module" src="https://unpkg.com/claude-count-tokens/widget/codex-token-heatmap.js"></script>
<codex-token-heatmap user="YOUR_GITHUB_USERNAME" palette="signal"></codex-token-heatmap>For Claude + Codex combined:
<script type="module" src="https://unpkg.com/claude-count-tokens/widget/ai-token-heatmap.js"></script>
<ai-token-heatmap user="YOUR_GITHUB_USERNAME" palette="duo"></ai-token-heatmap>Works with any site — plain HTML, Next.js, Astro, Hugo, Jekyll, WordPress, anything. No build step, no dependencies, no framework required.
Dark mode
The widget automatically follows your site's theme. No extra code needed.
It detects dark mode from:
prefers-color-scheme(system preference)class="dark"on<html>or<body>data-theme="dark"on<html>or<body>
To force a specific theme:
<claude-token-heatmap user="vitoria" theme="dark"></claude-token-heatmap>Color palettes
The Claude default palette is spring. The Codex default palette is signal. To pick a different one, add a palette attribute:
<claude-token-heatmap user="vitoria" palette="mint"></claude-token-heatmap>Available palettes:
Claude palettes:
fern · sage · moss · mint · spring · eucalyptus · pistachio · clover · jade · matcha · tea · basil
Codex palettes:
signal · orbit · babyblue · sky · azure · ocean · cerulean · harbor · cloud · aqua · turquoise · lagoon · glacier · cyan · frost
Combined palettes:
duo · softDuo · meadowSky · sageIris · mintCloud · pearlDuo
Or define your own with CSS custom properties:
claude-token-heatmap {
--cth-cell-l1: #d4e4c8;
--cth-cell-l2: #b5cda3;
--cth-cell-l3: #94b47e;
--cth-cell-l4: #6e9a56;
}Sizing
The widget fills its container by default. To make it smaller or larger, use CSS:
claude-token-heatmap {
max-width: 600px; /* constrain overall width */
--cth-cell-s: 10px; /* smaller cells (default 13px) */
--cth-cell-g: 2px; /* tighter gaps (default 3px) */
--cth-cell-r: 2px; /* border radius (default 3px) */
}The widget automatically shrinks on screens narrower than 700px.
Promo link
The widget includes a small animated link in the corner. To hide it:
<claude-token-heatmap user="vitoria" promo="false"></claude-token-heatmap>You can also style it from outside using ::part(promo-link):
claude-token-heatmap::part(promo-link) {
opacity: 0.2;
}On mobile, the link automatically moves to the top-right to avoid overlapping the legend.
Live dashboard
Want to see your usage locally while you code?
npx claude-count-tokensOpens live dashboards at http://localhost:7890/claude-code-tokens, http://localhost:7890/codex-code-tokens-live, and http://localhost:7890/combined-code-tokens-live that update as local usage files change.
CLI reference
npx claude-count-tokens # live dashboards on port 7890
npx claude-count-tokens --port 3000 # custom port
npx claude-count-tokens --days 90 # last 90 days only
npx claude-count-tokens login # log in with GitHub
npx claude-count-tokens logout # log out, clear credentials
npx claude-count-tokens sync # upload token data to cloud
npx claude-count-tokens sync --install # auto-sync every hour (macOS)
npx claude-count-tokens sync --uninstall # remove auto-sync
npx claude-count-tokens sync --status # check if auto-sync is running
npx claude-count-tokens export # export Claude data to ./claude-token-data.json
npx claude-count-tokens export --codex # export Codex data to ./claude-token-data.json
npx claude-count-tokens export --combined # export Claude + Codex data to ./claude-token-data.json
npx claude-count-tokens export -o out.json # custom output pathWhat gets counted
The Claude widget reads:
- Claude Code JSONL logs from
~/.claude/projects/ - Conductor Claude API result usage from
~/Library/Application Support/com.conductor.app/conductor.db - Zed thread token usage when available
For each Claude response, it sums:
| Type | What it is | |------|-----------| | Input | tokens in your prompt | | Output | tokens Claude generated | | Cache write | tokens written to context cache | | Cache read | tokens read from context cache |
This is different from your Claude account's usage page, which tracks billing across Claude products. This widget shows local Claude Code usage plus Conductor's Claude API usage from this machine.
The Codex widget reads Codex thread metadata from ~/.codex/state_5.sqlite and per-request token events from ~/.codex/sessions/. Cached input is shown separately but not double-counted; the total follows OpenAI's reported input plus output tokens for each request.
The combined widget merges the Claude and Codex aggregate JSON locally, uploads {username}-combined.json during sync, and renders it with <ai-token-heatmap>.
Privacy
Only aggregated token counts are synced to the cloud — no prompts, no code, no conversation content. The sync uploads small JSON files with daily/hourly token totals. Everything else stays on your machine.
Requirements
- Node.js 18+
- Claude Code installed (creates
~/.claude/projects/) - macOS for auto-sync (Linux users can use a cron job instead)
License
MIT
