Rich terminal status bar for Claude Code sessions — model usage, context window, costs, git state, and cumulative spend tracking.
Demo images are auto-generated from test fixtures. Run
make demoto regenerate after changing output format.
Downloads pre-built binaries for your platform:
curl -fsSL https://raw.githubusercontent.com/ridjex/claude-code-statusline/main/install-remote.sh | bashbrew install jq # bc and git are pre-installed on macOS
git clone https://github.com/ridjex/claude-code-statusline.git
cd claude-code-statusline
make install # auto-detects best engine (rust > go > python > bash)make verify # or: ~/.claude/statusline.sh --helpThen open a new Claude Code session.
make uninstall # removes scripts, caches, and settings.json entryThe statusline ships with multiple engine implementations. The installer auto-detects and installs the best available one.
| Engine | Status | Subprocesses | Render time | Requirements |
|---|---|---|---|---|
| Rust | Stable | 0 | ~6ms | rustc 1.70+ (3MB binary) |
| Go | Stable | 0 (hot path) | ~80ms | go 1.23+ (15MB binary) |
| Python | Stable | 5-8 (git only) | ~400ms | python3 (stdlib only) |
| Bash | Stable | 27-35 (jq+bc+git) | ~155ms | jq, bc, git |
All engines produce identical output for the same input. The engine-agnostic test suite verifies this.
~/.claude/statusline.sh is always the entry point. For Go/Rust/Python, it's a thin wrapper that calls the engine binary. Users never need to know which engine is running.
Edit ~/.claude/statusline.env to toggle sections (created by make install):
STATUSLINE_SHOW_MODEL=true # Model name
STATUSLINE_SHOW_MODEL_BARS=true # Mini bars (█▅▃)
STATUSLINE_SHOW_CONTEXT=true # Context window bar
STATUSLINE_SHOW_COST=true # Session cost
STATUSLINE_SHOW_DURATION=true # Wall clock time
STATUSLINE_SHOW_GIT=true # Branch + dirty
STATUSLINE_SHOW_DIFF=true # Lines +/-
STATUSLINE_LINE2=true # Show Line 2
STATUSLINE_SHOW_TOKENS=true # Token counts
STATUSLINE_SHOW_SPEED=true # tok/s throughput
STATUSLINE_SHOW_CUMULATIVE=true # ⌂/Σ cost trackingSet any value to false to hide that section. Changes apply on next render (no restart needed).
Pass --no-<section> flags to hide sections:
~/.claude/statusline.sh --no-git --no-cumulativeTo use with Claude Code, edit ~/.claude/settings.json:
{
"statusLine": {
"type": "command",
"command": "~/.claude/statusline.sh --no-git --no-cumulative",
"padding": 0
}
}Run ~/.claude/statusline.sh --help for all options.
Config precedence: CLI args > env vars > ~/.claude/statusline.env > defaults (all on)
make # show all targets
make test # run bash engine tests (80 assertions)
make test-python # run engine-agnostic tests against Python
make test-go # build + run engine-agnostic tests against Go
make test-rust # build + run engine-agnostic tests against Rust
make test-all # run all four engine test suites
make test-verbose # shows rendered output for each scenario
make build-go # build Go binary (engines/go/statusline)
make build-rust # build Rust binary (engines/rust/target/release/statusline)
make bench # benchmark all engines (requires hyperfine)
make bench-bash # benchmark bash only
make bench-python # benchmark python only
make bench-go # benchmark Go only
make bench-rust # benchmark Rust only
make bench-report # run benchmarks + generate RESULTS.md
make profile # detailed bash subprocess profiling
make demo # regenerate demo SVGs
make check # verify dependencies
make diagnose # check installation healthOpus 4.6 █▅▃ │ ▓▓▓░░░░░░░ 38% │ $8.4 │ 15m │ ✦edit-link ● │ +127 -34
\_model_/ ^^^ \__context__/ cost dur \___git___/ \_diff_/
│││
│││ Mini bars — model mix by output tokens
││└─ Haiku (green)
│└── Sonnet (cyan)
└─── Opus (magenta)
| Segment | Example | Description |
|---|---|---|
| Model | Opus 4.6 |
Active model, Claude prefix stripped |
| Mini bars | █▅▃ |
Bar height = relative output tokens. · = not used |
| Context | ▓▓▓░░░░░░░ 38% |
10-char bar. Yellow ⚠ at 70%, red ⚠ at 90% |
| Cost | $8.4 |
Session cost. $12.0k for >= $1000 |
| Duration | 15m |
Wall clock. 4h0m for >= 60min |
| Git | ✦edit-link ● |
Branch with icon, ● dirty, ↑↓ ahead/behind, ⊕ worktree |
| Diff | +127 -34 |
Lines added/removed |
Branch icons: ★ feature, ✦ fix, ⚙ chore, ↻ refactor, § docs
O:549k/41k S:180k/25k H:45k/15k │ 69 tok/s │ ⌂ $374/$4.0k/$7.1k │ Σ $552/$4.7k/$12.0k
\______per-model tokens________/ speed \__this project__/ \___all projects__/
day / week / month day / week / month
| Segment | Example | Description |
|---|---|---|
| Tokens | O:549k/41k S:180k/25k |
Per-model in/out. Only used models shown |
| Speed | 69 tok/s |
Output throughput. Green >30, yellow 15-30, red <15 |
⌂ |
$374/$4.0k/$7.1k |
This project: day/week/month cost |
Σ |
$552/$4.7k/$12.0k |
All projects: day/week/month cost |
Claude Code pipes JSON to statusline.sh via stdin on every render cycle.
stdin JSON ──> statusline.sh ──> 2 formatted lines (stdout)
│
├── reads cached model stats (models-{session}.json)
├── reads cached cumulative costs (proj-*.json, all.json)
├── reads git state (branch, dirty, ahead/behind)
│
└── spawns 2 background jobs (non-blocking):
├── parse transcript → update model cache
└── cumulative-stats.sh → update cost caches
- Render: ~6ms (Rust) / ~80ms (Go) / ~155ms (Bash) / ~400ms (Python) — full benchmarks
- Background model parse: ~50-100ms
- Background cost scan: ~2-14s (depends on transcript volume, cached 5min)
~/.claude/
statusline.sh # entry point (wrapper for engine binary, or bash directly)
statusline-rust # rust engine binary (if installed)
statusline-go # go engine binary (if installed)
statusline.py # python engine (if installed)
cumulative-stats.sh # background cost aggregator
~/.cache/claude-code-statusline/
models-{session}.json # per-session model tokens (auto-created)
proj-{hash}.json # per-project cost cache (auto-created)
all.json # all-projects cost cache (auto-created)
| Type | Range | Format | Example |
|---|---|---|---|
| Cost | >= $1000 | $X.Xk |
$12.0k |
| Cost | >= $10 | $X |
$374 |
| Cost | >= $1 | $X.X |
$8.4 |
| Cost | < $1 | $X.XX |
$0.12 |
| Tokens | >= 1M | X.XM |
1.2M |
| Tokens | >= 10k | Xk |
45k |
| Tokens | >= 1k | X.Xk |
1.6k |
| Tokens | < 1k | raw | 184 |
- First render — no mini bars, no per-model breakdown. Shows
in:288k out:41kfallback. Background job populates cache for next render. - Single model — one letter in Line 2 (
O:549k/41k). Mini bars: one bar + two dim dots. - No git repo — git section omitted.
- No cumulative cache —
⌂andΣsections omitted until first background run. - macOS vs Linux — uses
md5/stat -fon macOS,md5sum/stat -con Linux. - Branch truncation — names > 20 chars truncated with
…. - Worktree —
⊕prefix when working inside a git worktree.
| Problem | Solution |
|---|---|
| Statusline blank | Set export NO_COLOR=1 in your shell profile — works around a known Claude Code ANSI rendering bug |
| Renders vertically | Widen terminal to > 120 columns; known Claude Code bug with narrow terminals (#27849) |
| Not showing after install | Restart Claude Code session; verify with make verify |
| Missing colors | Ensure terminal supports 256 colors (echo $TERM should show xterm-256color or similar) |
claude-code-statusline/
engines/
bash/ # v1 — bash engine
statusline.sh # main renderer
cumulative-stats.sh # background cost aggregator
statusline.env.default # default config template
python/ # v2 — python engine
statusline.py # single-file renderer (stdlib only)
pyproject.toml # project metadata
go/ # v3 — Go engine (go-git, zero subprocess)
rust/ # v4 — Rust engine (gix/gitoxide, zero subprocess)
benchmarks/
bench.sh # hyperfine engine comparison
generate-report.sh # RESULTS.md generator
profile-bash.sh # detailed subprocess profiling
RESULTS.md # auto-generated benchmark report (committed by CI)
results/ # raw hyperfine output (gitignored)
tests/
run-tests.sh # bash-specific test runner
test-engine.sh # engine-agnostic test runner
fixtures/ # shared mock JSON data
scripts/
generate-demo.sh # fixture → ANSI → SVG
ansi2svg.py # ANSI-to-SVG converter
src/ # symlinks → engines/bash/ (backward compat)
skill/SKILL.md # Claude Code /statusline skill
install.sh # stack-agnostic installer
Makefile # unified build targets
docs/
performance-journey.md # article: bash → python → go → rust
assets/
demo-dark.svg # auto-generated
demo-light.svg # auto-generated