Remote OpenClaw Blog
Claude Code Statusline: Setup, Custom Scripts, and Troubleshooting
9 min read ยท
The Claude Code statusline is a customizable line at the bottom of the terminal interface that displays live session data such as the active model, current directory, git branch, session cost, and context window usage. You configure it by running the /statusline command inside a session, or by adding a statusLine entry to ~/.claude/settings.json that points to a script which receives session JSON on stdin and prints the line to stdout.
What Is the Claude Code Status Line?
The status line is Claude Code's equivalent of a shell prompt: a persistent strip of text under the input box that reflects the state of your session without you asking for it. Because it is generated by a shell command you control, it can show anything a script can compute, from context percentage and running cost to git branch, active subagent, or your 5-hour rate limit usage.
Per the official statusline documentation, the script runs after each new assistant message, after /compact finishes, when the permission mode changes, or when vim mode toggles, with rapid changes debounced at 300ms. It runs entirely locally and does not consume API tokens, which makes it one of the few Claude Code customizations that is genuinely free to run. If you are new to the tool itself, start with our Claude Code guide and come back here once you have a session running.
Quick Setup With /statusline
The /statusline command accepts a natural language description and builds the status line for you. Claude Code generates a script file in ~/.claude/ and updates your settings automatically, so you never touch JSON if you do not want to:
/statusline show model name and context percentage with a progress bar
To remove it later, run /statusline again and ask it to delete or clear the status line (for example /statusline remove it). This is the right path for most people; drop down to manual configuration when you want version-controlled scripts or team-shared settings.
The statusLine settings.json Schema
The statusLine setting takes a type of "command" plus the command to run, and supports three optional fields. This is the full schema as documented in the Claude Code settings reference as of July 2026:
{
"statusLine": {
"type": "command",
"command": "~/.claude/statusline.sh",
"padding": 2,
"refreshInterval": 5,
"hideVimModeIndicator": true
}
}
- type (required): must be
"command". - command (required): a script path or an inline shell command.
- padding (optional): extra horizontal spacing in characters, default
0. - refreshInterval (optional): re-runs the command every N seconds (minimum 1), useful for clocks or git changes that happen while the session is idle.
- hideVimModeIndicator (optional): suppresses the built-in
-- INSERT --text when your script rendersvim.modeitself.
Put the block in ~/.claude/settings.json for a personal statusline or .claude/settings.json to share one with your team. Output supports multiple lines (each echo is a row), ANSI color codes like \033[32m, and OSC 8 clickable hyperlinks in terminals such as iTerm2, Kitty, and WezTerm.
The JSON Your Script Receives
Claude Code pipes a single JSON object to your script's stdin on every update, and everything the statusline can display comes from that object. The most useful fields, verified against the official docs as of July 2026:
| Field | What it contains |
|---|---|
model.display_name | Human-readable model name, e.g. "Opus" |
workspace.current_dir | Current working directory (also project_dir for the original root) |
cost.total_cost_usd | Running session cost in USD, plus duration and lines added/removed |
context_window.used_percentage | How full the context window is; remaining_percentage is the inverse |
context_window.current_usage | Input, output, and cache token counts (null before the first API call) |
effort.level / thinking.enabled | Current reasoning effort level and whether extended thinking is on |
rate_limits | 5-hour and 7-day usage percentages with reset timestamps (Pro/Max subscribers) |
session_id, version, output_style | Session identifier, Claude Code version, and active output style |
vim.mode, agent.name, pr.number | Conditional fields: vim mode, active agent, and open PR for the current branch |
Several fields are conditional or nullable. rate_limits only appears for Claude Pro and Max subscribers after the first API response, and context_window.current_usage is null before the first call and right after /compact. Always write fallbacks such as // 0 in jq. The effort and thinking fields pair well with the controls covered in our Claude Code ultrathink guide.
Building a Custom Statusline Script
A working statusline script is three steps: read stdin, extract fields with jq, and echo one line. This is the exact example from the official documentation:
#!/bin/bash
# Read JSON data that Claude Code sends to stdin
input=$(cat)
# Extract fields using jq
MODEL=$(echo "$input" | jq -r '.model.display_name')
DIR=$(echo "$input" | jq -r '.workspace.current_dir')
# The "// 0" provides a fallback if the field is null
PCT=$(echo "$input" | jq -r '.context_window.used_percentage // 0' | cut -d. -f1)
# Output the status line - ${DIR##*/} extracts just the folder name
echo "[$MODEL] ๐ ${DIR##*/} | ${PCT}% context"
Save it as ~/.claude/statusline.sh, run chmod +x ~/.claude/statusline.sh, then add the statusLine block from the schema section above to ~/.claude/settings.json. Before wiring it in, test it standalone with mock input:
echo '{"model":{"display_name":"Opus"},"workspace":{"current_dir":"/home/user/project"},"context_window":{"used_percentage":25}}' | ~/.claude/statusline.sh
From there, extend it however you like: add git branch --show-current for the branch, color the context bar red past 90 percent with ANSI codes, or print a second echo line with session cost and duration. One caution from the docs: your script's output is captured rather than connected to the terminal, so tput cols cannot see the terminal width. Read the COLUMNS and LINES environment variables instead (set by Claude Code since v2.1.153).
Popular Community Statuslines
ccstatusline by sirmalloc is the most popular community statusline for Claude Code, with more than 11,000 GitHub stars as of July 2026 and a no-install setup: point your statusLine command at npx -y ccstatusline@latest. If you would rather not write bash, these projects cover most needs:
| Project | Setup | Standout features |
|---|---|---|
| ccstatusline (sirmalloc) | npx -y ccstatusline@latest | 50+ widgets, powerline themes, multi-line layouts, interactive TUI editor |
| claude-code-statusline (rz1989s) | Installer script to ~/.claude/statusline/ | 28 components across up to 9 lines, TOML config, cost tracking, MCP monitoring |
| claude-statusline (dwillitzer) | Shell script, optional Node.js | Context monitoring with token counting, verbose and compact display modes |
| claude-statusline (TheoBrigitte) | Single binary, TOML config | Fast multi-segment modules: context, cost, API status, session duration |
Community statuslines are shell commands running on your machine, so apply the same judgment you would to any script you download. The same trust model applies to Claude plugins, which can also ship statusline-adjacent tooling.
Troubleshooting
Most statusline failures come down to a script that is not executable, output going to stderr instead of stdout, or unhandled null fields. Work through these in order:
- Statusline not appearing at all: run
chmod +x ~/.claude/statusline.sh, confirm the script prints to stdout, and run it manually with mock input.claude --debuglogs the exit code and stderr from the first statusline invocation. - Shows
--or empty values: fields likeused_percentageare null before the first API response. Add jq fallbacks (// 0) and send one message before judging the output. - Disabled by another setting: if
disableAllHooksistruein your settings, the status line is disabled too. The statusline also only runs after you accept the workspace trust dialog; until then you will see "statusline skipped ยท restart to fix". - Windows path problems: in Git Bash, backslashes in the
commandpath get consumed as escape characters. Use forward slashes. - Links not clickable: OSC 8 hyperlinks need iTerm2, Kitty, or WezTerm; Terminal.app does not support them. Set
FORCE_HYPERLINK=1before launching if detection fails, and preferprintf '%b'overecho -e. - Stale or blank after edits: script changes only show on the next update trigger, slow scripts block updates until they finish, and in-flight runs are cancelled when a new update fires. Keep the script fast.
Limitations
The statusline is display-only: it cannot approve tools, change settings, or feed information back into the model, and it temporarily hides during autocomplete, the help menu, and permission prompts. System notifications such as MCP server errors share the same row on the right side, so very wide statuslines get truncated in narrow terminals.
Two design constraints are worth planning around. First, complex ANSI and OSC escape sequences can occasionally garble output when they overlap other UI updates; if you see corruption, simplify toward plain text. Second, the context percentage your script shows may differ slightly from /context because the two are calculated at different moments. For monitoring that needs to be exact, check /context or /cost directly, and treat the statusline as a fast approximation.
Related Guides
- Claude Code Guide [2026]: CLI, Desktop, Web, and Real-World Fit
- Claude Code Best Practices in 2026: What Actually Holds Up
- Claude Code Templates: The Complete Guide for 2026
- Claude Code MCP: How to Add and Manage MCP Servers
Go deeper
The operator playbooks
Production-ready PDF guides for OpenClaw and Hermes Agent โ $19.99 each.
Skills for this topic
Browse all skills โFrequently Asked Questions
How do I add a status line in Claude Code?
Run /statusline inside a Claude Code session and describe what you want, for example "/statusline show model name and context percentage". Claude Code generates the script and updates ~/.claude/settings.json automatically. For manual control, add a statusLine block with "type": "command" and a script path to your settings file.
Why is my Claude Code statusline not showing?
The three most common causes are a script missing execute permission ( chmod +x fixes it), output written to stderr instead of stdout, and disableAllHooks: true in settings, which disables the statusline too. Also confirm you accepted the workspace trust dialog; otherwise Claude Code shows "statusline skipped" instead of your output.
Does the Claude Code statusline use API tokens?
No. The statusline script runs locally on your machine and consumes no API tokens, so even a statusline that refreshes every second adds nothing to your bill. The one-time exception is the /statusline setup command itself, which uses the model to generate your script.
What is the best Claude Code statusline?
For most people it is ccstatusline : over 11,000 GitHub stars as of July 2026, 50+ widgets, and zero-install setup via npx -y ccstatusline@latest . If you want full control or minimal dependencies, a 10-line bash script with jq covers model, directory, and context percentage.

