Customizing Your Claude Code Status Line cover image

Customizing Your Claude Code Status Line

Scott Keck-Warren • July 10, 2026

I've had a nasty habit of hitting my Claude session limit right in the middle of something "important". Not where I would like to, at something like a natural stopping point, but right in the middle of a refactor or a long debugging session. I got into a terrible habit of checking the usage over and over again to make sure I didn't have to stop "midstream".

That felt wrong because the information existed, but there had to be a better way to surface it.

It turns out there is a way to customize the status line to display helpful information, and it's a game-changer.

What the Status Line Is

The status line is a customizable bar that lives at the bottom of Claude Code. By default, it shows some basic info (and to me, unhelpful), but the real power is that you can make it show almost anything you want. Claude Code runs a shell script you define, feeds it JSON data about your current session via stdin, and displays whatever your script prints back.

As a huge bonus, it doesn't consume API tokens, which matters because it runs constantly when Claude refreshes.

You can configure it two ways. The manual approach is to edit ~/.claude/settings.json directly and set the statusLine field to a script you've written. The much easier approach is just telling Claude Code what you want and have it do the "hard" work for you.

Setting It Up in 30 Seconds

You don't have to write a shell script yourself. Run:

/statusline display model on one line, context window as a progress bar on one line, the current session usage as a progress bar on one line, the weekly usage as a progress bar on another

That's the exact prompt I use. Claude Code reads your description, generates the script, and wires everything up in your settings automatically. No manual JSON editing and thankfully no wrestling with jq syntax.

My status bar looks like this after running it:

Sonnet 5
Context [#-------------------] 7%
5h     [#-------------------] 7%
7d     [--------------------] 4%

Weirdly, I've done this on both my work and personal computers, and they both gave slightly different results. My work computer included when the session resets and a completely different format for the progress bar.

Why Each Line Matters

My current statusline.sh contains four lines that I think are important to me. They include the model, context window, 5-hour usage, and 7-day usage.

I've included the model because I have an unfortunate habit of not always knowing which model I'm on. Having the model name front and center means I always know what I'm paying for and what to expect in terms of speed and capability. It's a small thing, but I've caught myself on the wrong model more than once.

Next is the context window usage, which I watch most closely. The context window fills up as the session grows, and when it gets too full, Claude's responses start to degrade. Seeing a progress bar means I know exactly when to run /compact or /clear instead of waiting until things start going off the rails.

Next is the 5-hour usage. As I'm sure you know, Claude plans have rate limits that reset on a rolling basis. The 5-hour bar shows how much of that window I've burned through in the current period. If it's climbing fast, I know to either pace myself or expect to take a break. This one alone has saved me from mid-session surprises on heavy days.

Finally, I keep track of the 7-day usage. It's useful for knowing whether I've been particularly heavy on usage this week and if I need to moderate what I'm doing to prevent hitting it several days before it resets. I mostly glance at it and move on, but it's nice context when I'm trying to decide whether to spin up a lot of parallel tasks or take it easy.

What's Actually Happening Under the Hood

When Claude Code runs your status line script, it passes a JSON blob to stdin that includes fields like model.display_name, context_window.used_percentage, rate_limits.five_hour.used_percentage, and rate_limits.seven_day.used_percentage. Your script reads those values and prints whatever output you want.

Each print or echo statement in the script becomes a row in the status bar, which is how we get the four-line display. You could print one line or ten, add colors, show raw numbers instead of progress bars, whatever you want.

If you ever want to see the generated script, look in ~/.claude/settings.json after running the command. The statusLine key will point to a script file somewhere in your Claude config directory, and you can open and tweak it directly if you want to make adjustments the natural language approach doesn't cover.

Clearing or Changing It

If you set something up and want to start over, run /statusline delete or /statusline clear. Then describe what you want, and it generates a fresh script.

Same goes for tweaking: just run a new /statusline prompt with a different description. I've tried a few variations, but I keep coming back to my four-liner above. It hits the right balance of information density without cluttering up the interface.

Next Steps

At work, we're set up to prioritize reviewing other people's pull requests, but it's a pain to keep checking, so my next step is to include this in the status line too.

Try It

If you're already using Claude Code regularly, this is a 30-second setup with an immediate payoff. Run /statusline with a description of what you want to see, watch it generate the script, and you're done.

The full documentation is at https://code.claude.com/docs/en/statusline if you want to dig into the JSON schema or write your own script from scratch. But for most people, plain English gets you there faster.

"My" Script

In case you're interested, below is my current ~/.claude/statusline.sh script that I'm using.

#!/bin/bash
#~/.claude/statusline.sh
input=$(cat)

model=$(echo "$input" | jq -r '.model.display_name')
ctx_used=$(echo "$input" | jq -r '.context_window.used_percentage // 0')
five_hour=$(echo "$input" | jq -r '.rate_limits.five_hour.used_percentage // empty')
seven_day=$(echo "$input" | jq -r '.rate_limits.seven_day.used_percentage // empty')

make_bar() {
    local pct=$1
    local width=20
    local pct_int=${pct%.*}
    [ -z "$pct_int" ] && pct_int=0
    local filled=$(( pct_int * width / 100 ))
    [ "$filled" -gt "$width" ] && filled=$width
    local empty=$(( width - filled ))
    local bar=""
    for ((i=0; i<filled; i++)); do bar="${bar}#"; done
    for ((i=0; i<empty; i++)); do bar="${bar}-"; done
    printf "%s" "$bar"
}

ctx_bar=$(make_bar "$ctx_used")
printf "\033[2m%s\033[0m\n" "$model"
printf "\033[2mContext [%s] %.0f%%\033[0m\n" "$ctx_bar" "$ctx_used"

if [ -n "$five_hour" ]; then
    five_bar=$(make_bar "$five_hour")
    printf "\033[2m5h     [%s] %.0f%%\033[0m\n" "$five_bar" "$five_hour"
else
    printf "\033[2m5h     [no data]\033[0m\n"
fi

if [ -n "$seven_day" ]; then
    week_bar=$(make_bar "$seven_day")
    printf "\033[2m7d     [%s] %.0f%%\033[0m\n" "$week_bar" "$seven_day"
else
    printf "\033[2m7d     [no data]\033[0m\n"
fi