claude-norns-statusline
v0.3.0
Published
Norse-themed statusline for Claude Code with OAuth usage tracking, git integration, and beautiful themes
Maintainers
Readme
claude-norns-statusline
A Norse-themed statusline plugin for Claude Code. Displays model info, git status, context window usage, session costs, and OAuth usage tracking — all in a beautiful, configurable terminal statusline.
Zero runtime dependencies. Single bundled file. Under 70ms render time.
Opus 4.6 main ██████░░░░ 62% $1.23 · 45K tok S:42% 3h12m · W:67%TL;DR
Terminal:
# 1. Install
npm install -g claude-norns-statusline@latest
# 2. Install slash commands
claude-norns-statusline --install-commands~/.claude/settings.json:
{
"statusLine": {
"type": "command",
"command": "claude-norns-statusline"
}
}Inside Claude Code — customize on the fly:
/norns:theme bifrost → switch theme instantly
/norns:style capsule → pill-style separators
/norns:show metrics directory → enable extra segments
/norns:lines model,git,directory | context,session → two-line layoutFeatures
- 6 Norse themes — Yggdrasil, Bifrost, Ragnarok, Valhalla, Mist, Jotunheim
- 3 rendering styles — Powerline arrows, minimal pipes, capsule pills
- 17 segments — model, git, context, session, usage, ratelimit, agent, block, daily, diff, metrics, sparkline, activity, version, tmux, directory, custom
- Multi-line layout — spread segments across 1-4 rows
- Slash commands —
/norns:theme bifrostto change settings live, no restart needed - Smart truncation — priority-based segment dropping when terminal is narrow
- Nerd Font + text fallback — works with or without patched fonts
- 5 progress bar styles — block
█░, classic━─, shade▓░, dot●○, pipe┃┊ - Rainbow shimmer — time-based HSV animation while Claude is active
- OAuth usage tracking — session and weekly API usage (auto-discovers credentials)
- File-based caching — configurable TTLs for git, OAuth, and transcript data
- Truecolor support — 24-bit hex colors with automatic fallback
Installation
npm (recommended)
npm install -g claude-norns-statusline@latestnpx (no install)
Use directly in your Claude Code config — npx will fetch it on first run:
npx claude-norns-statusline@latest --theme=yggdrasilFrom source
git clone https://github.com/danjuls/claude-norns-statusline.git
cd claude-norns-statusline
npm install && npm run buildSetup
Add to your Claude Code settings at ~/.claude/settings.json:
{
"statusLine": {
"type": "command",
"command": "npx claude-norns-statusline@latest --theme=yggdrasil --style=powerline"
}
}Or if installed globally / from source:
{
"statusLine": {
"type": "command",
"command": "claude-norns-statusline --theme=bifrost --style=capsule"
}
}Restart Claude Code and the statusline should appear at the bottom of your terminal.
Slash Commands
Control your statusline from inside Claude Code — no manual config editing, no restarts.
Install slash commands
npx claude-norns-statusline@latest --install-commandsThis copies command files to ~/.claude/commands/norns/. They're available immediately.
Available commands
| Command | Example | What it does |
|---------|---------|--------------|
| /norns:theme | /norns:theme bifrost | Switch theme |
| /norns:style | /norns:style capsule | Switch rendering style |
| /norns:show | /norns:show metrics directory | Enable one or more segments |
| /norns:hide | /norns:hide git usage | Disable one or more segments |
| /norns:lines | /norns:lines 2 | Set number of statusline rows |
| /norns:config | /norns:config | Show current configuration |
| /norns:reset | /norns:reset | Reset everything to defaults |
All commands edit ~/.config/claude-norns-statusline/config.json. Changes apply instantly on the next statusline refresh (~150ms while Claude is active).
Example workflow
You: /norns:theme ragnarok
→ "Switched theme to ragnarok" (statusline updates immediately)
You: /norns:show metrics directory
→ "Enabled: metrics, directory" (new segments appear)
You: /norns:lines 2
→ "Set to 2 lines" (segments split across 2 rows)
You: /norns:style capsule
→ "Switched style to capsule" (rounded pill separators)
You: /norns:reset
→ "Reset to defaults" (back to yggdrasil/powerline/1 line)Multi-line Layout
Spread segments across multiple rows instead of cramming everything on one line.
Quick — auto-split
# Via CLI flag
npx claude-norns-statusline@latest --lines=2
# Via slash command (inside Claude Code)
/norns:lines 2Segments auto-distribute by priority: highest-priority segments on line 1, rest on line 2.
Explicit — choose what goes where
In ~/.config/claude-norns-statusline/config.json:
{
"lines": [
["model", "git", "context"],
["session", "usage", "metrics"]
]
}Or via slash command:
/norns:lines model,git,context | session,usage,metricsAny enabled segments not assigned to a line get appended to the last line.
Themes
Powerline style
Minimal style
| Theme | Description | Aesthetic | |-------|-------------|-----------| | yggdrasil | World Tree (default) | Deep forest bark, moss green, ancient gold | | bifrost | Rainbow Bridge | Aurora cyan, violet, shimmering rose | | ragnarok | Fire & Twilight | Ember orange, blood red, molten gold | | valhalla | Hall of the Chosen | Silver light, ice blue, warm gold | | mist | Niflheim Fog | Deep slate, drifting lavender, pale cyan | | jotunheim | Frozen Realm | Deep navy, glacier cyan, frost white |
Preview all themes in your terminal:
echo '{}' | npx claude-norns-statusline --show-themesStyles
| Style | Separators | Example |
|-------|------------|---------|
| powerline | Arrow glyphs | `segment1segment2` |
| **minimal** | Pipe separators `│` | `segment1 │ segment2` |
| **capsule** | Rounded pills | segment1 segment2 |
Use --charset=text for ASCII fallback if your font doesn't support Nerd Font glyphs.
Reading the Statusline
Here's what each part of the statusline shows:
Opus 4.6 HEAD ?9 ██████░░░░ 50% $4.43 · 138K tok S:29% · W:26% · Max 5x
─────────── ──────── ──────────────── ────────────────── ──────────────────────────
model git context session usage| Segment | Example | What it means |
|---------|---------|---------------|
| model | Opus 4.6 | The active Claude model |
| git | main +2 ~1 ?3 | Branch, staged/unstaged/untracked counts (see below) |
| context | ██████░░░░ 50% | How much of Claude's context window (conversation memory) is used. When it hits 100%, older messages get compressed to make room |
| session | $4.43 · 138K tok | Total API cost and tokens consumed this session |
| usage | S:29% · W:26% | S: = 5-hour usage block consumed, W: = 7-day rolling usage. These are your rate limit quotas from Anthropic |
The context bar is the most useful at-a-glance indicator — it tells you how deep into a conversation you are before context compression kicks in.
Optional segments
Enable these for deeper insight — via /norns:show or --segment=true:
| Segment | Example | What it means |
|---------|---------|---------------|
| ratelimit | █████░░░ 75% · 2h | Visual bar of your 5-hour usage window with time until reset |
| agent | Explore | Name of the currently active agent/subagent |
| diff | +142 -38 | Lines of code added and removed this session |
| sparkline | ▁▂▃▅▇ | Cost trend over time — see if spending is accelerating or steady |
| activity | reading file.ts | What Claude is doing right now (parsed from transcript) |
| daily | $12.50 (62%) | Daily aggregate cost with budget percentage |
| block | $3.20 · 45K · 2h left | 5-hour block tracking with cost, tokens, and time remaining |
Git indicators
| Symbol | Meaning | Example |
|--------|---------|---------|
| +N | Staged files (ready to commit) | +3 = 3 files staged |
| ~N | Unstaged modifications | ~2 = 2 files modified but not staged |
| ?N | Untracked files (new, unknown to git) | ?1 = 1 new file |
| ↑N | Commits ahead of remote | ↑2 = 2 unpushed commits |
| ↓N | Commits behind remote | ↓3 = 3 commits to pull |
| ⚑N | Stash entries | ⚑1 = 1 stashed change |
| ● | Dirty working tree (generic, when no specific counts) | — |
Multiple indicators combine: main +2 ~1 ?3 means 2 staged, 1 modified, 3 untracked.
Segments
Segments are the building blocks of the statusline. Each gathers its own data and renders independently.
| Segment | Default | Priority | Description |
|---------|---------|----------|-------------|
| model | on | 100 | Active Claude model name |
| git | on | 90 | Branch, dirty/staged/untracked counts, ahead/behind |
| context | on | 80 | Context window usage with progress bar |
| session | on | 70 | Session cost and token count (with budget warnings) |
| usage | on | 60 | OAuth API session/weekly usage percentages |
| ratelimit | off | 65 | Visual progress bar of 5-hour usage window with reset countdown |
| agent | off | 55 | Active agent/subagent name |
| block | off | 50 | 5-hour usage block tracking (cost/tokens from transcript) |
| daily | off | 45 | Daily aggregate cost with persistent tracking and budget % |
| diff | off | 35 | Lines added/removed in the current session (+142 -38) |
| metrics | off | 40 | Message count and session duration |
| sparkline | off | 25 | Cost-over-time sparkline from transcript (▁▂▃▅▇) |
| activity | off | 15 | Current Claude action (e.g. "reading file.ts", "running cmd") |
| version | off | 30 | Claude Code version |
| tmux | off | 20 | Tmux session name |
| directory | off | 10 | CWD with fish-style path abbreviation |
| custom | off | 5 | Output from a user-defined shell command |
Higher priority segments are kept when the terminal is too narrow — lower priority ones are dropped first.
Enabling/disabling segments
Via slash commands (recommended):
/norns:show metrics directory Enable segments
/norns:hide git usage Disable segmentsVia CLI flags:
--no-git # Disable
--no-usage # Disable
--metrics=true # Enable
--directory=true # EnableVia config file (~/.config/claude-norns-statusline/config.json):
{
"segments": {
"git": { "enabled": false },
"metrics": { "enabled": true },
"custom": { "enabled": true, "options": { "command": "hostname -s" } }
}
}Configuration
Settings are resolved in this order (highest priority first):
- CLI flags —
--theme=ragnarok --style=capsule --no-git - Environment variables —
NORNS_THEME,NORNS_STYLE,NORNS_CHARSET,NORNS_BAR_STYLE,NORNS_SHIMMER,NORNS_OAUTH - Project config —
.claude-norns-statusline.jsonin current directory - User config —
~/.config/claude-norns-statusline/config.json(edited by slash commands) - Defaults
Example config file
{
"theme": "bifrost",
"style": "powerline",
"charset": "nerd",
"barStyle": "block",
"barWidth": 10,
"lines": 2,
"oauth": true,
"segments": {
"model": { "enabled": true, "priority": 100 },
"git": { "enabled": true, "priority": 90 },
"context": { "enabled": true, "priority": 80 },
"session": { "enabled": true, "priority": 70 },
"usage": { "enabled": true, "priority": 60 },
"diff": { "enabled": true, "priority": 35 },
"metrics": { "enabled": true, "priority": 40 },
"directory": { "enabled": true, "priority": 10 }
},
"budget": {
"daily": 20,
"warnAt": 80
}
}The budget section is optional. When configured, the session segment shows a ⚠90% warning when your session cost exceeds the warnAt threshold (default 80%) of your daily budget. The daily segment shows the running total with a percentage of your budget.
CLI reference
| Flag | Description | Default |
|------|-------------|---------|
| --theme=NAME | Theme name | yggdrasil |
| --style=NAME | powerline, minimal, or capsule | powerline |
| --charset=NAME | nerd or text | nerd |
| --bar-style=NAME | block, classic, shade, dot, or pipe | block |
| --lines=N | Number of statusline rows (1-4) | 1 |
| --shimmer | Rainbow animation while Claude is active | false |
| --oauth=false | Disable OAuth usage fetching | true |
| --no-SEGMENT | Disable a segment | — |
| --SEGMENT=true | Enable a segment | — |
| --show-themes | Preview all themes and exit | — |
| --install-commands | Install slash commands to ~/.claude/commands/norns/ | — |
| --debug-stdin | Dump stdin JSON to ~/.cache/claude-norns-statusline/ | — |
Shimmer Effect
Enable a subtle glow animation with --shimmer:
{
"statusLine": {
"type": "command",
"command": "npx claude-norns-statusline@latest --theme=bifrost --shimmer"
}
}Two light bands sweep across the statusline at different speeds, brightening your theme colors as they pass — like a reflection on brushed metal. A gentle background pulse adds a slow "breathing" effect. All theme colors are preserved; the glow just lifts brightness toward white as it passes.
The effect works automatically — Claude Code refreshes the statusline ~every 150ms while active, and each refresh produces the next animation frame. When Claude goes idle, the animation naturally pauses. No background processes needed.
OAuth Usage Tracking
The usage segment shows your 5-hour session and 7-day rolling API usage percentages. It auto-discovers your OAuth token from three sources (tried in order):
~/.claude/.credentials.json— flat file credentials- macOS Keychain —
Claude Code-credentialsentry (most common on macOS) CLAUDE_CODE_OAUTH_TOKENenv var — manual override
If you're logged into Claude Code normally, it should work automatically. Disable with --oauth=false if you don't need it or are using an API key.
Testing Locally
Test the statusline outside of Claude Code by piping JSON to stdin:
# Basic — just model info
echo '{"model":{"id":"claude-opus-4-6","display_name":"Opus 4.6"}}' | npx claude-norns-statusline --oauth=false
# Full data — model, cost, context window
echo '{"model":{"id":"claude-opus-4-6","display_name":"Opus 4.6"},"cost":{"total_cost_usd":1.23},"context_window":{"used_percentage":62,"total_input_tokens":35000,"total_output_tokens":8000}}' | npx claude-norns-statusline --oauth=false
# Try different themes
echo '{}' | npx claude-norns-statusline --theme=ragnarok --oauth=false
echo '{}' | npx claude-norns-statusline --theme=bifrost --style=capsule --oauth=false
# Multi-line
echo '{"model":{"id":"claude-opus-4-6","display_name":"Opus 4.6"},"cost":{"total_cost_usd":0.42},"context_window":{"used_percentage":22,"total_input_tokens":35000,"total_output_tokens":8000}}' | npx claude-norns-statusline --lines=2 --oauth=false
# ASCII fallback (no Nerd Font needed)
echo '{"model":{"id":"claude-opus-4-6","display_name":"Opus 4.6"}}' | npx claude-norns-statusline --charset=text --oauth=false
# Preview all themes
echo '{}' | npx claude-norns-statusline --show-themes
# Debug — dump what Claude Code sends
echo '{"model":{"id":"claude-opus-4-6"}}' | npx claude-norns-statusline --debug-stdin --oauth=false
cat ~/.cache/claude-norns-statusline/debug-stdin.jsonIf developing from source, replace npx claude-norns-statusline with node dist/index.js.
Debugging
If segments aren't showing, add --debug-stdin to your command to inspect what Claude Code sends:
# Add to your statusLine command temporarily
claude-norns-statusline --debug-stdin
# Then check the dump
cat ~/.cache/claude-norns-statusline/debug-stdin.jsonRequirements
- Node.js >= 18
- Claude Code with statusline support
- Nerd Font (optional, use
--charset=textfor ASCII fallback) - Truecolor terminal recommended (iTerm2, Ghostty, Kitty, Alacritty, WezTerm)
License
MIT
