claude-code-vitals
v1.0.0
Published
Zero-dependency statusline for Claude Code with gradient bars, smart tips, and theme support
Maintainers
Readme
claude-code-vitals
Zero-dependency statusline for Claude Code with gradient slider bars, smart tips, and theme support.
Ahmad Hassan · [email protected]
Opus 4.6 │ Pro │ main ● │ myproject │ v2.1.71
5-Hour ━━━━●────────────────── 12% resets 1h 59m
Weekly ━━━━━━━━━━━●────────── 54% Wed 5:30 AM
Context ━━━━━━━━━━━━━●──────── 61% 78.0K left of 200K
$5.02 │ 26m 48s (API 12m) │ ↑124K ↓43K │ cache 97% │ +287 −358
✓ Cache efficiency excellent (97%) — fast responses, low overhead.Why?
- Zero dependencies — single
.mjsfile, nothing to install at runtime - Zero API calls — reads everything from Claude Code's stdin (
rate_limits,context_window,cost) - Fast — no network, no async. Git info cached for 5 seconds
- Smart tips — contextual suggestions like "Context at 80% — consider /compact"
- Configurable — toggle sections, switch themes, add custom tip rules via JSON
- 5 built-in themes — Catppuccin Mocha, Tokyo Night, Dracula, Nord, Gruvbox Dark
Install
One command (recommended)
npx claude-code-vitalsThis copies the statusline to ~/.claude/statusline.mjs and updates your settings.json.
With config file
npx claude-code-vitals initSame as above, plus creates ~/.claude/vitals.config.json with all defaults.
Manual
- Copy
index.mjsto~/.claude/statusline.mjs - Add to
~/.claude/settings.json:
{
"statusLine": {
"type": "command",
"command": "node ~/.claude/statusline.mjs",
"padding": 1
}
}Uninstall
npx claude-code-vitals removeWhat it shows
Account row
Your display name and login email from your Claude.ai account.
Identity row
| Segment | Source | When shown |
|---|---|---|
| Model | model.display_name | Always |
| Plan | Pro / Max | When logged into Claude.ai |
| Git | main ● ↑2 | When in a git repo |
| Worktree | worktree name | When in a --worktree session |
| Directory | project → subdir | Always (shows breadcrumb if cwd ≠ project root) |
| Version | v2.1.71 | Always |
| Output style | explanatory | When not "default" |
| Agent | agent name | When using --agent |
| Vim mode | NORMAL / INSERT | When vim mode is enabled |
Gauges
Three slider bars with per-cell gradient coloring (green → yellow → red):
- 5-Hour — rolling 5-hour rate limit usage + reset countdown
- Weekly — 7-day rate limit usage + friendly reset date
- Context — context window usage + remaining tokens
Metrics row
| Metric | Example | Meaning |
|---|---|---|
| Cost | $5.02 | Total API cost this session |
| Duration | 26m (API 12m) | Wall clock + time waiting for API |
| Tokens | ↑124K ↓43K | Cumulative input/output tokens |
| Cache | cache 97% | Prompt cache hit rate (green ≥50%, yellow ≥20%, red <20%) |
| Lines | +287 −358 | Lines added/removed by Claude |
| >200K | ⚠ >200K | Warning when latest call exceeds 200K tokens |
Smart tips
One contextual suggestion shown at a time, highest priority wins:
| Priority | Example |
|---|---|
| Critical | ⚠ Context 95% full — auto-compression soon. Consider /compact. |
| Warning | ○ 5-hour usage at 75% — resets 1h 59m. |
| Info | ○ 370 lines changed with uncommitted work — consider committing. |
| Success | ✓ Cache efficiency excellent (97%) |
Configuration
Create ~/.claude/vitals.config.json (or run npx claude-code-vitals init):
{
"theme": "catppuccin-mocha",
"bar": {
"style": "slider",
"width": 22
},
"sections": {
"account": true,
"identity": true,
"gauges": true,
"metrics": true,
"tips": true
}
}You only need to include settings you want to change — everything else uses defaults.
Toggle sections
{ "sections": { "account": false, "tips": false } }Toggle individual gauges/metrics
{
"gauges": { "weekly": false },
"metrics": { "cache": false, "lines": false }
}Change bar style
{ "bar": { "style": "blocks", "width": 25 } }Two styles available:
slider—━━━━━━●──────────(default, modern)blocks—████████▍─────────(classic, sub-cell precision)
Custom thresholds
{ "thresholds": { "warning": 60, "critical": 85 } }Affects gauge color breakpoints and tip triggers.
Custom tip rules
Add your own tip rules that trigger based on conditions:
{
"tips": {
"custom": [
{
"when": { "context_pct": { ">=": 60 } },
"priority": 15,
"level": "info",
"message": "Context at {context_pct}% — maybe time to wrap up this task."
},
{
"when": { "cost": { ">=": 5 }, "five_hour_pct": { ">=": 50 } },
"priority": 8,
"level": "warning",
"message": "Burning through quota fast — ${cost} spent, {five_hour_pct}% of 5hr limit used."
}
]
}
}Available variables for when conditions and {interpolation}:
| Variable | Type | Description |
|---|---|---|
| context_pct | number | Context window usage 0-100 |
| context_remaining | string | Formatted remaining tokens (e.g. "78.0K") |
| five_hour_pct | number | 5-hour rate limit 0-100 (-1 if unavailable) |
| seven_day_pct | number | 7-day rate limit 0-100 (-1 if unavailable) |
| cost | number | Session cost in USD |
| duration_min | number | Session duration in minutes |
| lines_changed | number | Total lines added + removed |
| has_uncommitted | boolean | Whether git has uncommitted changes |
| cache_rate | number | Cache hit rate 0-100 (-1 if unavailable) |
| exceeds_200k | boolean | Whether latest API call exceeds 200K tokens |
Condition operators: >, >=, <, <=, ==, !=
Themes
Built-in themes
Set via config: { "theme": "tokyo-night" }
catppuccin-mocha— warm pastels on dark (default)tokyo-night— cool blues and purplesdracula— vivid on charcoalnord— arctic, muted tonesgruvbox-dark— retro warm earth tones
Custom inline theme
Provide a full color palette directly in your config:
{
"theme": {
"text": [205, 214, 244],
"subtext": [166, 173, 200],
"dim": [147, 153, 178],
"border": [88, 91, 112],
"track": [49, 50, 68],
"surface": [17, 17, 27],
"overlay": [108, 112, 134],
"accent": [180, 190, 254],
"blue": [137, 180, 250],
"cyan": [116, 199, 236],
"teal": [148, 226, 213],
"green": [166, 227, 161],
"yellow": [249, 226, 175],
"orange": [250, 179, 135],
"red": [243, 139, 168],
"purple": [203, 166, 247],
"pink": [245, 194, 231],
"rose": [242, 205, 205]
}
}All 17 colors must be provided as [R, G, B] arrays.
How it works
- Claude Code pipes JSON to your statusline command via stdin after each assistant message
index.mjsreads stdin, parses the JSON, loads your config- Renders colored output to stdout using ANSI true-color escape codes
- Claude Code displays the output at the bottom of the terminal
No API calls. Rate limits come directly from stdin (rate_limits.five_hour, rate_limits.seven_day) — the same data source Claude Code uses for /usage. This means the statusline is always perfectly synced and adds zero latency.
Git caching: git commands are cached to a temp file for 5 seconds to avoid repeated subprocess spawns during rapid status line updates (Claude Code debounces at 300ms).
Performance
| Operation | Time | Notes | |---|---|---| | Stdin parse | <1ms | Synchronous JSON.parse | | Config load | <1ms | Single file read, cached by OS | | Git info | 0ms (cached) / ~50ms (fresh) | 5s file-based cache | | Account read | <1ms | Single file read | | Render | <1ms | String concatenation only | | Total | ~2ms typical | No network, no async |
Contributing
See CONTRIBUTING.md for how to add themes, metrics, tip rules, and bar styles.
