Track your Claude API spending and token usage with a personal dashboard. Monitor monthly costs with a fire intensity indicator, see your top 3 most-used models on a trophy leaderboard, and visualize usage trends over time — all self-hosted on Cloudflare's free tier.
- Monthly Cost Tracking: Estimated API spend per month with a fire indicator that intensifies as costs rise.
- Top Models Leaderboard: Trophy-ranked top 3 models with gold/silver/bronze medals and per-model cost.
- Token Usage Stats: Real-time cards showing total, input, output, cache write, and cache read tokens — all with odometer roll-up animations.
- Prompt Caching Tracking: Tracks cache creation and cache read tokens separately from regular input tokens, with accurate per-model cost calculation.
- Time-Series Charts: Stacked area charts (input, output, cache write, cache read) with weekly navigation to browse historical data.
- Heatmap Calendar: GitHub-contribution-style 90-day grid showing daily token usage intensity with hover tooltips.
- Cost Breakdown Donut: Pie chart splitting regular vs. cached token costs.
- Cost Forecast: Projected monthly spend based on current velocity.
- Monthly Burn History: Historical monthly token totals with burn tier indicators.
- Monthly Achievements: 30 unlockable badges based on usage milestones.
- Velocity Ticker: Live token burn rate with trend indicators.
- Burn Intensity System: Ambient fire particle effects (WebGL2 + Canvas 2D) that scale with monthly token usage — from a few floating embers at 20M tokens to a full-screen nuclear meltdown at 4B+. Seven tiers: cold, spark, warm, burning, blazing, inferno, meltdown. Toggleable from the header with localStorage persistence.
- Tier Preview: Append
?flametier=meltdown(or any tier name) to preview fire effects. - Dynamic OG Image: Server-generated Open Graph image with live stats and burn tier, served at
/api/og. - PWA Support: Installable as a Progressive Web App with offline capability via service worker.
- Discord Webhooks: Notifications for sync events and burn tier changes via Discord webhook.
- Mobile Hamburger Drawer: Responsive mobile navigation with fire effects and theme controls.
- Error Boundaries: Runtime and global error handlers with fallback UI and recovery buttons.
- Glassmorphism UI: Frosted glass header and footer with backdrop blur, pill-style dark/light mode toggle, and one-click data refresh.
- Automatic Sync: Built-in sync script reads directly from Claude Code's local session data, with continuous watch mode.
- API Key Protection: Write endpoints are protected with a bearer token so only you can push data.
- Konami Code Easter Egg: Up Up Down Down Left Right Left Right B A triggers an explosive multi-wave fire animation.
- Free Tier Friendly: Designed to run entirely on Cloudflare's free plan (Workers + Pages + D1).
- Node.js 20.x or later
- pnpm 10.x
- A Cloudflare account (free tier works)
-
Clone the repository:
git clone https://github.com/MrDemonWolf/protoburn.git cd protoburn -
Install dependencies:
pnpm install
-
Copy environment variables:
cp apps/server/.env.example apps/server/.env cp apps/web/.env.example apps/web/.env cp packages/infra/.env.example packages/infra/.env
-
Generate a Drizzle migration and push the schema to local SQLite:
pnpm db:generate pnpm db:push
-
Start the development servers:
pnpm dev
- Web: http://localhost:3001
- API: http://localhost:3000
curl -X POST http://localhost:3000/api/usage \
-H "Content-Type: application/json" \
-d '{"records":[{"model":"claude-opus-4","inputTokens":15000,"outputTokens":3000,"cacheCreationTokens":5000,"cacheReadTokens":2000,"date":"2026-02-07"}]}'This project uses Alchemy to deploy the API server as a Cloudflare Worker and the web dashboard as a Cloudflare Pages site, with a D1 (SQLite) database.
pnpm cf:setupThis opens a browser to authorize Alchemy with your Cloudflare account.
Alternatively, set an API token directly:
export CLOUDFLARE_API_TOKEN=your-api-token-hereCreate a token at https://dash.cloudflare.com/profile/api-tokens with these permissions:
- Account > Workers Scripts > Edit
- Account > D1 > Edit
- Account > Cloudflare Pages > Edit
Update packages/infra/.env with a secure password for Alchemy state:
ALCHEMY_PASSWORD=your-secure-password
Optionally set an API key in apps/server/.env to protect write endpoints:
API_KEY=your-secret-api-key
Generate one with:
openssl rand -hex 32pnpm cf:deployThis will:
- Create a D1 database and run migrations
- Deploy the Hono API server as a Cloudflare Worker
- Build the Next.js dashboard as a static site
- Deploy the static site to Cloudflare Pages
- Print the URLs for both services
pnpm cf:deploypnpm cf:destroyThis removes all Cloudflare resources (Worker, Pages, D1 database).
The included sync script reads token usage directly from Claude Code's local data (~/.claude/) and pushes it to your dashboard.
Add to your ~/.zshrc (or ~/.bashrc):
export PROTOBURN_API_KEY="your-api-key-here"
alias protoburn-sync="pnpm --dir /path/to/protoburn sync"# Sync new usage since last run
protoburn-sync
# Continuous sync (push every 60m, fetch every 30m)
pnpm sync:watch
# Custom interval (push every 30m, fetch every 15m)
pnpm sync --watch --interval 30
# Re-sync all historical data
protoburn-sync --full
# Wipe the database and re-sync everything
protoburn-sync --resetTo enable Discord webhook notifications for sync events and tier changes, set:
export DISCORD_WEBHOOK_URL="https://discord.com/api/webhooks/..."The script reads from two sources:
~/.claude/stats-cache.jsonfor historical daily data (survives session rotation)- Session JSONL files in
~/.claude/projects/for current-day granular data
A .protoburn-last-sync file in ~/.claude/ tracks the last sync timestamp to avoid duplicates.
The POST /api/usage endpoint accepts token usage records via curl or any HTTP client:
curl -X POST https://your-worker.workers.dev/api/usage \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-api-key" \
-d '{
"records": [
{
"model": "claude-opus-4",
"inputTokens": 15000,
"outputTokens": 3000,
"cacheCreationTokens": 5000,
"cacheReadTokens": 2000,
"date": "2026-02-07"
}
]
}'| Field | Type | Description |
|---|---|---|
model |
string | Model identifier (e.g. claude-opus-4-6, claude-sonnet-4-5) |
inputTokens |
number | Number of input tokens |
outputTokens |
number | Number of output tokens |
cacheCreationTokens |
number | (optional) Cache write tokens (default 0) |
cacheReadTokens |
number | (optional) Cache read tokens (default 0) |
date |
string | ISO date string, day granularity (YYYY-MM-DD) |
protoburn/
├── apps/
│ ├── web/ # Next.js frontend (static export)
│ │ └── src/
│ │ ├── app/ # Pages & layout
│ │ └── components/
│ │ ├── dashboard/ # Stats cards, chart, top models leaderboard
│ │ └── ui/ # shadcn/ui components
│ └── server/ # Hono API server (Cloudflare Worker)
│ └── src/
│ └── index.ts # tRPC + REST endpoints
├── packages/
│ ├── api/ # tRPC router definitions
│ ├── db/ # Drizzle ORM schema & migrations
│ ├── env/ # Cloudflare Workers env bindings
│ ├── config/ # Shared TypeScript config
│ └── infra/ # Alchemy deployment config
└── scripts/
└── sync.ts # Claude Code usage sync script
| Command | Description |
|---|---|
pnpm dev |
Start all apps in development mode |
pnpm build |
Build all applications |
pnpm check-types |
Run TypeScript type checking |
pnpm db:generate |
Generate Drizzle migration files |
pnpm db:push |
Push schema to local database |
pnpm db:migrate |
Run database migrations |
pnpm sync |
Sync Claude Code usage to dashboard |
pnpm sync:watch |
Continuous sync (push every 60m, fetch every 30m) |
pnpm test |
Run all tests (Vitest) |
pnpm test:watch |
Run tests in watch mode |
pnpm test:coverage |
Run tests with coverage |
pnpm cf:setup |
Authenticate Alchemy with Cloudflare |
pnpm cf:deploy |
Deploy to Cloudflare |
pnpm cf:destroy |
Tear down Cloudflare resources |
- Frontend: Next.js 16, Tailwind CSS, shadcn/ui, Recharts, Montserrat + Roboto fonts
- Backend: Hono, tRPC, Drizzle ORM
- Database: Cloudflare D1 (SQLite)
- Deployment: Alchemy, Cloudflare Workers + Pages
- Monorepo: Turborepo, pnpm workspaces
- Discord: Join my server
Made with love by MrDemonWolf, Inc.