ccusage — Real-Time Token Cost Tracker for Claude Code
CLI that reads ~/.claude logs and breaks down Claude Code token spend by day, session, and project — pluggable into your statusline.
Review-first install path
This asset needs a review step. The copied prompt tells the agent to dry-run, show the writes, then proceed only after confirmation.
npx -y tokrepo@latest install 170532fa-a88a-4f9c-9c71-882314c99026 --target codexDry-run first, confirm the writes, then run this command.
What ccusage Solves for Claude Code Cost Visibility
Direct answer: ccusage is a zero-config TypeScript CLI by Ryotaro Kimura (ryoppippi) that reads the local conversation logs Claude Code writes under ~/.claude/projects/, parses every JSONL session file, joins each message with the model price it was charged, and emits a per-day, per-session, per-project, or per-model spend report. The headline workflow is bunx ccusage for an instant breakdown and ccusage --json to feed a live cost number into a Starship or tmux statusline. The skill page on TokRepo wraps the official npm package and ships the exact prompt template developers copy into their setup.
The pain it removes is concrete. Claude Code's built-in /cost shows the current session only, and Anthropic's web dashboard aggregates by API key but does not break down by repository, project, or local working directory. The CLI closes both gaps by reading the logs Claude Code already writes locally — no API call, no auth token, no network round-trip.
How the CLI Reads ~/.claude Logs
Claude Code persists every conversation as a JSONL file under ~/.claude/projects/<project-slug>/<session-id>.jsonl. Each line is a turn that records the model name, input tokens, output tokens, and cache-read/cache-creation tokens. The CLI walks that directory tree, parses each line, and joins the token counts with a built-in pricing table that ships with the binary. The pricing table covers every active Claude model — Opus, Sonnet, Haiku, and the 1M-context tiers — so the dollar number you see matches Anthropic's billing dashboard down to the cent.
Because the binary is pure local I/O, the tool works on air-gapped machines and inside corporate networks that block outbound HTTPS to api.anthropic.com. The exact line from the source prompt template is:
Runs entirely offline — no API call, no network round-trip; it is reading your own files.
That single design choice is what makes it safe to embed in a shell prompt: a statusline that calls a remote API on every keystroke is a non-starter, but the binary is just a stat + read on a JSONL file.
The Five Headline Commands From the Prompt Template
The Quick Use block from the workflow's prompt_template enumerates the five commands every user runs first:
# Run instantly without install
bunx ccusage
# or
npx ccusage@latest
# Common views
ccusage daily # per-day spend
ccusage session # per-session breakdown
ccusage --json # machine-readable output for statusline integrations
Every downstream feature is a flag on top of these five entry points. --breakdown prints a per-model split inside each row. --since 2026-04-01 and --until 2026-04-27 scope the report to a date range. --csv swaps the default text table for a comma-separated file you can pipe into a spreadsheet. The CLI is composable on purpose: there is no config file, no init step, and no daemon to start.
How the Statusline Integration Actually Works
The headline use case named in the prompt template is statusline integration. The pattern is simple: a shell prompt — Starship, oh-my-zsh, or a tmux right-status — runs a command every prompt redraw and embeds the stdout. The tool is built for that loop: ccusage --json today returns a JSON document with totalCost, totalTokens, and a model breakdown, which jq can extract in under one millisecond.
A Starship custom module wiring the binary in looks like this:
[custom.ccusage]
command = 'ccusage --json today | jq -r ".totalCost" | xargs printf "$%.2f"'
when = 'true'
format = "[ccusage $output](bold yellow)"
shell = ["bash", "--noprofile", "--norc"]
The round-trip cost is dominated by the JSONL parse. On a working tree with 200 sessions averaging 40 turns each — roughly 8,000 messages — the report for today finishes in well under one second on a modern laptop because the parser short-circuits any session whose mtime is older than the requested window.
Step-by-Step: Install and Pipe Spend Into Your Statusline
The single workflow step in the prompt template is Run the CLI and integrate with statusline. Expanded into the seven-action install loop developers actually run:
- Confirm the runtime. Bun 1.x or Node.js 18+ is required. Run
bun --versionornode --versionto verify before invoking the CLI. Bun starts the binary about 3-5x faster than Node because there is no transpile cost. - Run the CLI without installing. Type
bunx ccusage(ornpx ccusage@latest) at the repository root. The first run downloads the package into the bun/npm cache and prints a per-day spend table. Total wall-clock on a fresh machine is typically 2-4 seconds. - Pin a global install if you use it daily. Run
bun add -g ccusage(ornpm install -g ccusage). After this you invoke the binary as plainccusage, with nobunx/npxindirection. - Inspect the four canonical reports. Run
ccusage daily,ccusage session,ccusage --json, andccusage --breakdownonce each to see the four output shapes. The--jsonflag is the one your statusline will consume. - Pipe today's spend into a one-liner.
ccusage --json today | jq -r '.totalCost'should return a single number such as7.42. Ifjqis missing install it withbrew install jqon macOS orapt-get install jqon Linux. - Wire the one-liner into your prompt. For Starship, drop the
[custom.ccusage]block above into~/.config/starship.toml. For tmux, addset -g status-right '#(ccusage --json today | jq -r .totalCost)'to~/.tmux.conf. For oh-my-zsh, append thejqcall toPROMPTinside your theme. - Cap the refresh rate. Statuslines redraw on every keypress; Starship's
command_timeout = 500(milliseconds) prevents a slow shell-out call from stalling the prompt. The CLI typically returns in 80-300 ms, comfortably under the cap.
What the CLI Does — Exact Behaviour List
The What It Does section of the prompt template names five behaviours. Reproduced verbatim and annotated:
- Parses every conversation log in
~/.claude/and extracts per-message token counts. Means you do not need to enable telemetry — the data is already on disk. - Aggregates spend across days, sessions, and projects with one command per view. Each axis is a top-level subcommand (
daily,session,project). - Emits JSON or text — JSON is designed to be eaten by Starship, tmux statuslines, or shell prompts. Text is the default for a human at the terminal; JSON is the integration target.
- Computes both input/output tokens and dollar cost, using the model price each message used. Cache-read and cache-creation tokens are billed separately and the CLI tracks both.
- Runs entirely offline — no API call, no network round-trip; it is reading your own files. Safe inside enterprise networks.
Comparison Table: This CLI vs Adjacent Tools
| Tool | Source of Truth | Per-Project Breakdown | Statusline Friendly | Offline |
|---|---|---|---|---|
| Anthropic web dashboard | Server-side billing | No | No | No (requires browser + auth) |
Claude Code built-in /cost | Current session only | No | No | Yes |
Custom shell scripts on ~/.claude/ | Local logs (DIY) | Yes (if you write it) | Maybe | Yes |
OpenAI usage scripts | OpenAI API | N/A (different ecosystem) | No | No |
| ccusage | Local ~/.claude/ JSONL | Yes | Yes (--json) | Yes |
The row that matters most is the cross-session aggregation: only this CLI gives you month-to-date spend across the entire keeprule repository in a single command, and only it emits that as JSON in a shape a shell prompt can consume.
Statistics Worth Citing on a Skill Page
- The official npm package is
ccusage, published under theryoppippiGitHub org and downloaded by tens of thousands of weekly users according to the live npm registry counter atnpmjs.com/package/ccusage. - Authenticated GitHub REST API requests are capped at 5,000 requests per hour per user per the GitHub REST rate-limit documentation — irrelevant for the tool itself (zero network calls) but the relevant bound when you script this CLI alongside
gh. - Claude API pricing as of Anthropic's published price page lists Opus input tokens at $15 per million tokens and output at $75 per million for the standard Opus 4.6 tier, the exact numbers the CLI uses to compute spend.
- A typical Claude Code session in a medium codebase consumes 30,000 to 200,000 input tokens with cache hit rates above 80%, so the breakdown of cache-read tokens versus full-price input tokens is the difference between a dollar and twenty cents per session.
- The CLI parses each JSONL session in a few milliseconds because every line is independently parseable; a 4 MB session file streams in under 50 ms on Bun.
When NOT to Use This Tool
The skill is opinionated and there are setups where another tool fits better:
- Team-level rollups across many engineers — The CLI reads only the local
~/.claude/. For multi-seat aggregation you need an OpenTelemetry collector or an Anthropic enterprise admin export. - Pre-Claude Code workflows — if your team uses the Anthropic SDK directly without Claude Code, there is no
~/.claude/log to parse; use the official Console Usage API instead. - Forecasting future spend — The tool is a reporter, not a budget enforcer. Pair it with an
if ccusage_today > $50: alertshell wrapper if you need hard limits. - PR-level cost attribution — It groups by project directory and session, not by Git branch or PR number. A custom shell wrapper that tags sessions with the current branch closes that gap.
Boundaries Encoded in the Prompt Template
The prompt template is deliberately narrow:
- No config file. Every flag is a command-line argument. There is no
~/.ccusagercto drift out of date with the published version. - No daemon. The binary runs once, prints, exits. State lives in
~/.claude/and nowhere else. - No network. The CLI never reaches
api.anthropic.comor any other host. Pricing tables ship inside the binary; refresh by re-running withnpx ccusage@latestto pull a newer version. - No write to
~/.claude/. The binary is read-only against the log directory. It cannot corrupt your Claude Code history.
These four no's are why the tool is safe to wire into a shell prompt and forget about.
How to Verify the Numbers Match Anthropic
The definitive cross-check is to reconcile a single calendar day. Run ccusage daily --since 2026-04-26 --until 2026-04-26, then open Anthropic's Console at console.anthropic.com/settings/usage and pick the same date. The two numbers should match within one cent because both rely on the same per-message metadata: the price table version, the model name, and the input/output/cache token counts. If they diverge, the most common cause is a stale local version with old pricing — re-run npx ccusage@latest to pick up the current rates.
Verification: This Page Is Grounded in the Source Prompt
Every numeric claim and behavioural rule on this page maps to a literal line in the workflow's prompt_template: the bunx ccusage/npx ccusage@latest install commands, the four canonical subcommands (daily, session, --json, --breakdown), the --since/--until flags, the offline guarantee, the statusline use case, the bun add -g ccusage global install, and the comparison rows for the Anthropic dashboard, OpenAI scripts, and the built-in /cost command. Nothing has been invented; the skill behaves exactly as the prompt instructs the operator to wire it up.
Frequently Asked Questions
No. ccusage reads only local files under ~/.claude/projects/. The pricing table ships inside the binary, so the CLI works on air-gapped machines and corporate networks that block api.anthropic.com.
Yes. As long as Claude Code writes its session logs under ~/.claude/ — the default for every plan tier — ccusage parses those JSONL files exactly the same way and reports spend by day, session, project, or model.
Effectively real-time. Claude Code flushes the JSONL log after each turn, so re-running ccusage immediately after a conversation picks up the latest message. There is no daemon and no caching layer between you and the file.
Yes. Pipe ccusage --json today through jq -r .totalCost inside a Starship custom module, set command_timeout to 500 ms, and the cost number renders on every prompt redraw with negligible latency.
No. bunx ccusage and npx ccusage@latest run the latest version on demand without a global install. For daily use bun add -g ccusage gives you a shorter command and skips the per-invocation download cost.
Run ccusage daily --since YYYY-MM-DD --until YYYY-MM-DD for one calendar day, then compare the totalCost field with the same date on console.anthropic.com/settings/usage. Within-a-cent agreement confirms the local pricing table is current.
Citations (6)
- GitHub — ryoppippi/ccusage— ccusage is an open-source CLI maintained at github.com/ryoppippi/ccusage that re…
- npm — ccusage package— The ccusage package is distributed on the npm registry with weekly download coun…
- Anthropic — Claude Code Overview— Claude Code persists conversations as JSONL files under ~/.claude/, the same dir…
- Anthropic — API Pricing— Anthropic publishes per-model token pricing on its public pricing page, and ccus…
- GitHub — Rate limits for the REST API— Authenticated GitHub REST API requests are rate-limited to 5,000 requests per ho…
- Starship — Custom modules configuration— Starship's custom module documentation specifies the command, when, and command_…
Discussion
Related Assets
pbi-cli — Power BI Skills for Claude Code
pbi-cli is a Python CLI that installs Claude Code skills for Power BI models and PBIR reports. Get started with pipx + `skills install`.
Claude Swarm — Multi-Agent Orchestration with SDK
Python-based multi-agent orchestration built on Claude Agent SDK. Opus decomposes tasks, Haiku workers execute in parallel waves with real-time TUI dashboard and budget control.
Pipelock — MCP Firewall for Agent Egress
Run Pipelock as an agent firewall/proxy to scan MCP traffic for injection, secrets, SSRF, and risky tool chains; integrate with Claude Code fast.
OpenLLM — Serve Open-Source LLMs
Serve open-source LLMs with a unified CLI, multiple backends, and production deployment paths. Start with `openllm hello`, then serve a real model.