# How to Set Up a Custom Status Line in Claude Code: Display Context Usage, Model, and Session Cost

> Customize your Claude Code status line to show context usage, model, and cost. Learn how to set up a custom status line using the settings.json file for real-time insights.

- Repository: [Shayan Rais/claude-code-best-practice](https://github.com/shanraisshan/claude-code-best-practice)
- Tags: how-to-guide
- Published: 2026-03-12

---

**Configure a custom status line in Claude Code by adding a `statusLine` object to [`.claude/settings.json`](https://github.com/shanraisshan/claude-code-best-practice/blob/main/.claude/settings.json) that executes a script receiving JSON payload data on STDIN, enabling real-time display of context consumption, model name, estimated cost, and session metadata.**

The **Claude Code Best-Practice** repository demonstrates how to extend Claude Code's interface through custom UI components. A custom status line provides critical visibility into expensive API calls and context window limits, helping you monitor token consumption and model selection without leaving the composer pane.

## Understanding the Status Line Architecture

Claude Code injects a UI layer beneath the composer that can execute external commands on every refresh. According to the repository's architecture, the **Settings** layer in [`.claude/settings.json`](https://github.com/shanraisshan/claude-code-best-practice/blob/main/.claude/settings.json) drives UI customization, including the status line configuration documented in [`best-practice/claude-settings.md`](https://github.com/shanraisshan/claude-code-best-practice/blob/main/best-practice/claude-settings.md) (lines 84-98).

The system operates through three mechanisms:

- **Configuration** – Define a `statusLine` object with `"type": "command"` pointing to an executable script
- **Invocation** – Claude Code runs the command on each UI refresh, passing a JSON blob via STDIN
- **Rendering** – The script's STDOUT appears as formatted text in the status bar, with optional `padding` for spacing

## Configuring the Status Line in settings.json

Create or modify [`.claude/settings.json`](https://github.com/shanraisshan/claude-code-best-practice/blob/main/.claude/settings.json) (or [`settings.local.json`](https://github.com/shanraisshan/claude-code-best-practice/blob/main/settings.local.json) for user-specific overrides) to register your status command. The repository includes a minimal example at lines 65-69:

```json
{
  "statusLine": {
    "type": "command",
    "command": "echo \"shayan's best practice status line\"",
    "padding": 0
  }
}

```

For a functional implementation, point the command to an executable script that parses the incoming JSON payload. The payload contains fields such as `context_window.used_percentage`, `context_window.remaining_percentage`, `current_usage`, `exceeds_200k_tokens`, `model`, and `modelCost`.

## Building a Real-Time Status Script

Create an executable script at `~/.claude/statusline.sh` that reads STDIN and formats the output. The script below uses `jq` to extract context usage, model name, and cost data, then combines it with git and directory information:

```bash
#!/usr/bin/env bash

# ~/.claude/statusline.sh

# Reads JSON from Claude Code and outputs formatted status line

read -r payload
model=$(echo "$payload" | jq -r '.model // "unknown"')
used=$(echo "$payload" | jq -r '.context_window.used_percentage // "0"')
remain=$(echo "$payload" | jq -r '.context_window.remaining_percentage // "0"')
cost=$(echo "$payload" | jq -r '.modelCost // "0"')
branch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "no-branch")
dir=$(pwd | sed "s|$HOME|~|")

printf "[%s] %s%% used (%s%% left) • $%s • %s • %s\n" \
  "$model" "$used" "$remain" "$cost" "$branch" "$dir"

```

Make the script executable and update your configuration:

```bash
chmod +x ~/.claude/statusline.sh

```

Then reference it in [`.claude/settings.json`](https://github.com/shanraisshan/claude-code-best-practice/blob/main/.claude/settings.json):

```json
{
  "statusLine": {
    "type": "command",
    "command": "~/.claude/statusline.sh",
    "padding": 1
  }
}

```

## Implementing Auto-Compaction Thresholds

Extend your status line logic to trigger session maintenance when context usage exceeds safe limits. By monitoring `context_window.used_percentage`, you can automate `/compact` calls when usage crosses 90%.

Create `~/.claude/auto-compact.sh` to run as a background task:

```bash
#!/usr/bin/env bash

# ~/.claude/auto-compact.sh

# Background watcher for automatic context compaction

while true; do
  payload=$(claude statusline)
  used=$(echo "$payload" | jq -r '.context_window.used_percentage')
  if (( used > 90 )); then
    claude /compact
  fi
  sleep 5
done

```

Execute this via `/task` to maintain optimal context levels without manual intervention, preventing token limit errors during long sessions.

## Summary

- **The `statusLine` configuration** in [`.claude/settings.json`](https://github.com/shanraisshan/claude-code-best-practice/blob/main/.claude/settings.json) accepts a `command` type that executes on every UI refresh, receiving JSON data on STDIN.
- **Payload fields** include `context_window.used_percentage`, `model`, `modelCost`, and session directories, enabling precise monitoring of resource consumption.
- **Implementation requires** an executable script (typically bash with `jq`) that reads STDIN and prints a single-line summary to STDOUT.
- **Advanced workflows** can leverage the same JSON payload to trigger auto-compaction when context usage exceeds defined thresholds.

## Frequently Asked Questions

### What data does the Claude Code status line JSON payload contain?

The JSON payload sent to your script includes `context_window.used_percentage`, `context_window.remaining_percentage`, `current_usage`, `exceeds_200k_tokens`, `model`, `modelCost`, and directory information from `/add-dir` commands. The full schema is documented in [`best-practice/claude-settings.md`](https://github.com/shanraisshan/claude-code-best-practice/blob/main/best-practice/claude-settings.md).

### Can I use Python instead of Bash for the status line script?

Yes, any executable that reads STDIN and prints to STDOUT works. Configure the `command` path in [`settings.json`](https://github.com/shanraisshan/claude-code-best-practice/blob/main/settings.json) to point to a Python script (e.g., `"command": "~/.claude/statusline.py"`), then parse `sys.stdin` using the `json` module and print your formatted status string.

### Why doesn't my status line update immediately after editing settings.json?

Changes require a settings reload. Run `/config` in Claude Code and select "Reload settings," or restart the application. Verify the script path is absolute and the file has execute permissions (`chmod +x`).

### How do I show Git branch information in the Claude Code status line?

Include the `git rev-parse --abbrev-ref HEAD` command in your status script, as shown in the bash example. Claude Code executes the status command within the current working directory, so standard git commands resolve to the active project repository.