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. The /statusline command is also covered in the commands reference.
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 │ 📅 7d:1% │ 💰$5.0789 │ ✏️ +423 -55What each segment shows:
| Segment | Description |
|---|---|
🌿 main ✔ | Git branch + clean/dirty indicator (or worktree name) |
🤖 Sonnet 4.6 | Current model |
ctx ██░░░░░░ 14% | Context window usage bar, color-coded green/orange/red |
🪙 28.0k | Current input token count |
⏱️ 3% ↺3h7m | 5-hour rate limit used + time until reset |
📅 7d:1% | 7-day rate limit used |
💰$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).
Open Claude Code and paste the prompt below. Claude will write the script, make it executable, and update your settings.json — producing the exact statusline shown in the screenshot above.
Please install the following statusline script for me exactly as written:
1. Write this content to ~/.claude/statusline-command.sh:
#!/usr/bin/env bash# Claude Code status line: git info + context + cost + lines# 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=82COLOR_GIT_DIRTY=214COLOR_MODEL_FG=153COLOR_CTX_LOW=82COLOR_CTX_MID=214COLOR_CTX_HIGH=196COLOR_COST=221COLOR_SESSION_LOW=82COLOR_SESSION_MID=214COLOR_SESSION_HIGH=196COLOR_7DAY_LOW=82COLOR_7DAY_MID=214COLOR_7DAY_HIGH=196COLOR_LINES_ADD=82COLOR_LINES_REM=196COLOR_DIV=240
DIV=' │ '
# ── 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')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')seven_day=$(echo "$input" | jq -r '.rate_limits.seven_day.used_percentage // empty')lines_added=$(echo "$input" | jq -r '.cost.total_lines_added // 0')lines_removed=$(echo "$input"| jq -r '.cost.total_lines_removed // 0')
# ── Git info (with worktree support) ─────────────────────────────────────────git_section=""worktree_name=$(echo "$input" | jq -r '.worktree.name // empty')if [ -n "$worktree_name" ]; then git_section="$(fg $COLOR_GIT_CLEAN)${bold}🌿 ${worktree_name} ⎇${reset}"elif [ -n "$cwd" ] && [ -d "$cwd" ]; then branch=$(git -C "$cwd" --no-optional-locks branch --show-current 2>/dev/null) if [ -n "$branch" ]; then if 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)" ]; then git_icon='✔' git_color=$(fg $COLOR_GIT_CLEAN) else git_icon='✘' git_color=$(fg $COLOR_GIT_DIRTY) fi git_section="${git_color}${bold}🌿 ${branch} ${git_icon}${reset}" fifi
# ── Model section ────────────────────────────────────────────────────────────model_section=""if [ -n "$model_name" ]; then model_section="$(fg $COLOR_MODEL_FG)🤖 ${model_name}${reset}"fi
# ── Context usage bar + percentage ──────────────────────────────────────────ctx_section=""if [ -n "$used_pct" ]; then pct_int=$(printf "%.0f" "$used_pct") if [ "$pct_int" -ge 85 ]; then ctx_color=$(fg $COLOR_CTX_HIGH) elif [ "$pct_int" -ge 60 ]; then ctx_color=$(fg $COLOR_CTX_MID) else ctx_color=$(fg $COLOR_CTX_LOW) fi filled=$(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; do if [ "$i" -le "$filled" ]; then bar="${bar}█"; else bar="${bar}░"; fi done ctx_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; then ctx_k=$(LC_ALL=C awk -v t="$input_tokens" 'BEGIN { printf "%.1fk", t/1000 }') tokens_section="🪙 ${ctx_k}"fi
# ── Session usage (5-hour rate limit window) ────────────────────────────────session_section=""if [ -n "$sess_pct" ] && [ -n "$sess_reset" ]; then sess_pct_int=$(printf "%.0f" "$sess_pct") if [ "$sess_pct_int" -ge 85 ]; then sess_color=$(fg $COLOR_SESSION_HIGH) elif [ "$sess_pct_int" -ge 60 ]; then sess_color=$(fg $COLOR_SESSION_MID) else sess_color=$(fg $COLOR_SESSION_LOW) fi now=$(date +%s) diff=$(( sess_reset - now )) if [ "$diff" -gt 0 ]; then hrs=$(( diff / 3600 )) mins=$(( (diff % 3600) / 60 )) if [ "$hrs" -gt 0 ]; then reset_label="${hrs}h${mins}m" else reset_label="${mins}m" fi session_section="${sess_color}⏱️ ${sess_pct_int}% ↺${reset_label}${reset}" else session_section="${sess_color}⏱️ ${sess_pct_int}%${reset}" fifi
# ── 7-day rate limit ─────────────────────────────────────────────────────────seven_day_section=""if [ -n "$seven_day" ]; then seven_day_int=$(printf "%.0f" "$seven_day") if [ "$seven_day_int" -ge 85 ]; then seven_day_color=$(fg $COLOR_7DAY_HIGH) elif [ "$seven_day_int" -ge 60 ]; then seven_day_color=$(fg $COLOR_7DAY_MID) else seven_day_color=$(fg $COLOR_7DAY_LOW) fi seven_day_section="${seven_day_color}📅 7d:${seven_day_int}%${reset}"fi
# ── Session cost ─────────────────────────────────────────────────────────────cost_section=""if [ -n "$total_cost" ]; then cost=$(LC_ALL=C awk -v c="$total_cost" 'BEGIN { printf "%.4f", c }') cost_section="$(fg $COLOR_COST)💰 \$${cost}${reset}"fi
# ── Lines added / removed ────────────────────────────────────────────────────lines_section=""if [ "$lines_added" -ne 0 ] 2>/dev/null || [ "$lines_removed" -ne 0 ] 2>/dev/null; then lines_section="$(fg $COLOR_LINES_ADD)✏️ +${lines_added}${reset} $(fg $COLOR_LINES_REM)-${lines_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" "$seven_day_section" "$cost_section" "$lines_section"; do [ -z "$section" ] && continue if [ -z "$output" ]; then output="$section" else output="${output}${divider}${section}" fidone
[ -n "$output" ] && printf '%b' "$output"
2. Run: chmod +x ~/.claude/statusline-command.sh
3. Add this to ~/.claude/settings.json: "statusLine": { "type": "command", "command": "bash $HOME/.claude/statusline-command.sh" }
4. Restart Claude Code.-
Write the script
Save the following to
~/.claude/statusline-command.sh:#!/usr/bin/env bash# Claude Code status line: git info + context + cost + lines# 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_7DAY_LOW=82 # green (< 60 %)COLOR_7DAY_MID=214 # orange (60-85 %)COLOR_7DAY_HIGH=196 # red (> 85 %)COLOR_LINES_ADD=82 # bright green for added linesCOLOR_LINES_REM=196 # red for removed linesCOLOR_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')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')seven_day=$(echo "$input" | jq -r '.rate_limits.seven_day.used_percentage // empty')lines_added=$(echo "$input" | jq -r '.cost.total_lines_added // 0')lines_removed=$(echo "$input"| jq -r '.cost.total_lines_removed // 0')# ── Git info (with worktree support) ─────────────────────────────────────────git_section=""worktree_name=$(echo "$input" | jq -r '.worktree.name // empty')if [ -n "$worktree_name" ]; thengit_section="$(fg $COLOR_GIT_CLEAN)${bold}🌿 ${worktree_name} ⎇${reset}"elif [ -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="🪙 ${ctx_k}"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# ── 7-day rate limit ─────────────────────────────────────────────────────────seven_day_section=""if [ -n "$seven_day" ]; thenseven_day_int=$(printf "%.0f" "$seven_day")if [ "$seven_day_int" -ge 85 ]; thenseven_day_color=$(fg $COLOR_7DAY_HIGH)elif [ "$seven_day_int" -ge 60 ]; thenseven_day_color=$(fg $COLOR_7DAY_MID)elseseven_day_color=$(fg $COLOR_7DAY_LOW)fiseven_day_section="${seven_day_color}📅 7d:${seven_day_int}%${reset}"fi# ── 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 added / removed ────────────────────────────────────────────────────lines_section=""if [ "$lines_added" -ne 0 ] 2>/dev/null || [ "$lines_removed" -ne 0 ] 2>/dev/null; thenlines_section="$(fg $COLOR_LINES_ADD)✏️ +${lines_added}${reset} $(fg $COLOR_LINES_REM)-${lines_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" "$seven_day_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:{"statusLine": {"type": "command","command": "bash $HOME/.claude/statusline-command.sh"}} -
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 official status line docs cover all available JSON fields and configuration options including multi-line output, colors, clickable links, and Windows support.