Customize your status line
What is the status line?
Section titled “What is the status line?”The status line is a customizable bar that appears at the bottom of Claude Code. It runs any shell script you configure, receives JSON session data on stdin, and displays whatever your script prints — giving you a persistent, at-a-glance view of context usage, costs, git status, or anything else you want to track.
It’s useful when you want to:
- Monitor context window usage as you work
- Track session costs in real time
- Keep the current git branch and status always visible
- Distinguish between multiple open sessions
For the full reference — including all available JSON fields, multi-line output, colors, and Windows configuration — see the official status line documentation.
Pretty status line
Section titled “Pretty status line”This is a ready-made status line that shows everything useful in one compact bar:

🌿 main ✔ │ 🤖 Sonnet 4.6 │ ctx ██░░░░░░ 14% │ 28.0k │ ⏱️ 3% ↺3h7m │ 💰$5.0789 │ +423 -55What each segment shows:
| Segment | Description |
|---|---|
🌿 main ✔ | Git branch + clean/dirty indicator |
🤖 Sonnet 4.6 | Current model |
ctx ██░░░░░░ 14% | Context window usage bar |
28.0k | Current input token count |
⏱️ 3% ↺3h7m | 5-hour rate limit used + time until reset |
💰$5.0789 | Total session cost |
+423 -55 | Lines added/removed this session |
Requirements: jq and git must be installed. Colors require a terminal with ANSI 256-color support (most modern terminals qualify).
The easiest way is to let Claude Code set it up for you. Open Claude Code and run:
/statusline show git branch with clean/dirty indicator, model name, context usage bar with percentage, input tokens, 5-hour rate limit with reset timer, total session cost, and lines added/removed. Use ANSI 256 colors.Claude Code will generate the script, write it to ~/.claude/, and update your settings.json automatically. Restart Claude Code for it to appear.
-
Write the script
Save the following to
~/.claude/statusline-command.sh:#!/usr/bin/env bash# Claude Code status line: git info + context + cost# Uses ANSI 256-color codes. Sections separated by unicode dividers.input=$(cat)# ── ANSI helpers ────────────────────────────────────────────────────────────reset='\033[0m'bold='\033[1m'dim='\033[2m'# Foreground 256-colorfg() { printf '\033[38;5;%sm' "$1"; }# PaletteCOLOR_GIT_CLEAN=82 # bright greenCOLOR_GIT_DIRTY=214 # orangeCOLOR_MODEL_FG=153 # light blueCOLOR_CTX_LOW=82 # green (< 60 %)COLOR_CTX_MID=214 # orange (60-85 %)COLOR_CTX_HIGH=196 # red (> 85 %)COLOR_COST=221 # goldCOLOR_SESSION_LOW=82 # green (< 60 %)COLOR_SESSION_MID=214 # orange (60-85 %)COLOR_SESSION_HIGH=196 # red (> 85 %)COLOR_DIV=240 # mid-grey for dividersDIV=' │ ' # unicode vertical bar divider with padding# ── JSON fields ─────────────────────────────────────────────────────────────cwd=$(echo "$input" | jq -r '.workspace.current_dir // .cwd // ""')used_pct=$(echo "$input" | jq -r '.context_window.used_percentage // empty')input_tokens=$(echo "$input" | jq -r '.context_window.current_usage |((.input_tokens // 0) + (.output_tokens // 0) + (.cache_creation_input_tokens // 0) + (.cache_read_input_tokens // 0)) |if . == 0 then empty else . end')model_name=$(echo "$input" | jq -r '.model.display_name // ""')total_cost=$(echo "$input" | jq -r '.cost.total_cost_usd // empty')lines_added=$(echo "$input" | jq -r '.cost.total_lines_added // empty')lines_removed=$(echo "$input"| jq -r '.cost.total_lines_removed // empty')sess_pct=$(echo "$input" | jq -r '.rate_limits.five_hour.used_percentage // empty')sess_reset=$(echo "$input" | jq -r '.rate_limits.five_hour.resets_at // empty')# ── Git info ─────────────────────────────────────────────────────────────────git_section=""if [ -n "$cwd" ] && [ -d "$cwd" ]; thenbranch=$(git -C "$cwd" --no-optional-locks branch --show-current 2>/dev/null)if [ -n "$branch" ]; thenif git -C "$cwd" --no-optional-locks diff --quiet 2>/dev/null && \git -C "$cwd" --no-optional-locks diff --cached --quiet 2>/dev/null && \[ -z "$(git -C "$cwd" --no-optional-locks ls-files --others --exclude-standard 2>/dev/null)" ]; thengit_icon='✔'git_color=$(fg $COLOR_GIT_CLEAN)elsegit_icon='✘'git_color=$(fg $COLOR_GIT_DIRTY)figit_section="${git_color}${bold}🌿 ${branch} ${git_icon}${reset}"fifi# ── Model section ────────────────────────────────────────────────────────────model_section=""if [ -n "$model_name" ]; thenmodel_section="$(fg $COLOR_MODEL_FG)🤖 ${model_name}${reset}"fi# ── Context usage bar + percentage ──────────────────────────────────────────ctx_section=""if [ -n "$used_pct" ]; thenpct_int=$(printf "%.0f" "$used_pct")if [ "$pct_int" -ge 85 ]; thenctx_color=$(fg $COLOR_CTX_HIGH)elif [ "$pct_int" -ge 60 ]; thenctx_color=$(fg $COLOR_CTX_MID)elsectx_color=$(fg $COLOR_CTX_LOW)fifilled=$(LC_ALL=C awk -v p="$used_pct" 'BEGIN { printf "%d", int(p/12.5 + 0.5) }')bar=""for i in 1 2 3 4 5 6 7 8; doif [ "$i" -le "$filled" ]; then bar="${bar}█"; else bar="${bar}░"; fidonectx_section="${ctx_color}ctx ${bar} ${pct_int}%${reset}"fi# ── Current context input tokens ────────────────────────────────────────────tokens_section=""if [ -n "$input_tokens" ] && [ "$input_tokens" -gt 0 ] 2>/dev/null; thenctx_k=$(LC_ALL=C awk -v t="$input_tokens" 'BEGIN { printf "%.1fk", t/1000 }')tokens_section="$(dim)${ctx_k}${reset}"fi# ── Session usage (5-hour rate limit window) ────────────────────────────────session_section=""if [ -n "$sess_pct" ] && [ -n "$sess_reset" ]; thensess_pct_int=$(printf "%.0f" "$sess_pct")if [ "$sess_pct_int" -ge 85 ]; thensess_color=$(fg $COLOR_SESSION_HIGH)elif [ "$sess_pct_int" -ge 60 ]; thensess_color=$(fg $COLOR_SESSION_MID)elsesess_color=$(fg $COLOR_SESSION_LOW)finow=$(date +%s)diff=$(( sess_reset - now ))if [ "$diff" -gt 0 ]; thenhrs=$(( diff / 3600 ))mins=$(( (diff % 3600) / 60 ))if [ "$hrs" -gt 0 ]; thenreset_label="${hrs}h${mins}m"elsereset_label="${mins}m"fisession_section="${sess_color}⏱️ ${sess_pct_int}% ↺${reset_label}${reset}"elsesession_section="${sess_color}⏱️ ${sess_pct_int}%${reset}"fifi# ── Session cost ─────────────────────────────────────────────────────────────cost_section=""if [ -n "$total_cost" ]; thencost=$(LC_ALL=C awk -v c="$total_cost" 'BEGIN { printf "%.4f", c }')cost_section="$(fg $COLOR_COST)💰 \$${cost}${reset}"fi# ── Lines changed ─────────────────────────────────────────────────────────────lines_section=""if [ -n "$lines_added" ] || [ -n "$lines_removed" ]; thenadded=${lines_added:-0}removed=${lines_removed:-0}lines_section="$(fg $COLOR_GIT_CLEAN)+${added}${reset} $(fg $COLOR_GIT_DIRTY)-${removed}${reset}"fi# ── Assemble output ──────────────────────────────────────────────────────────divider="$(fg $COLOR_DIV)${DIV}${reset}"output=""for section in "$git_section" "$model_section" "$ctx_section" "$tokens_section" "$session_section" "$cost_section" "$lines_section"; do[ -z "$section" ] && continueif [ -z "$output" ]; thenoutput="$section"elseoutput="${output}${divider}${section}"fidone[ -n "$output" ] && printf '%b' "$output" -
Make it executable
Terminal window chmod +x ~/.claude/statusline-command.sh -
Add to settings
Open
~/.claude/settings.jsonand add thestatusLinekey (replaceUSERNAMEwith your actual username):{"statusLine": {"type": "command","command": "bash /home/USERNAME/.claude/statusline-command.sh"}}On macOS your home directory is
/Users/username, on Linux it’s/home/username. You can runecho $HOMEin your terminal to confirm. -
Restart Claude Code
Settings reload automatically, but the status line won’t appear until you restart Claude Code.
Customize or remove the status line
Section titled “Customize or remove the status line”The easiest way to modify or remove your status line is to ask Claude Code directly using the /statusline command:
/statusline remove it/statusline add the current date and time/statusline show only model name and cost, no git infoClaude Code will update your script and settings.json accordingly. For manual edits, the /statusline official docs cover all available JSON fields and configuration options including multi-line output, colors, clickable links, and Windows support.