Context Meter
betaToken / context-window usage as a compact ring or bar with warning and danger thresholds, rolling numbers and a segmented breakdown card.
Ring
minimal
Ring and bar with a breakdown
Segments, thresholds, value display and a footer. Add tokens to watch the numbers roll into warning and danger.
full
Thresholds
ok, warning and danger bars.
state
In a composer footer
Next to an IconButton send action.
composition
Ask a follow-up…
Installation
npx shadcn@latest add https://kuro.abstergo.fyi/r/context-meter.jsonCopies the source into components/kura/context-meter with its dependencies (kura-theme, popover, use-controllable-state, use-reduced-motion, utils). Tokens come from the kura-theme item.
When to use it
Use it for
- Show how much of a model's context window a conversation uses (e.g. in a composer footer or chat header).
- Break usage down by source — system prompt, tool definitions, attached files, history — in a hover card.
- Warn before the context fills up (auto-compaction, truncation) with warning/danger thresholds.
- Show any other token budget (per-request output limit, monthly quota) as a bar.
Reach for something else when
- Indeterminate progress or “thinking” — use shimmer-text or reasoning.
- Upload or task progress — use a progress bar (or agent-timeline for multi-step work).
- Billing/cost dashboards with history — use a chart.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| max* | number | — | Context window size in tokens, e.g. 200000. |
| used | number | — | Tokens used. Default: the sum of `segments`. |
| segments | readonly ContextSegment[] | — | Breakdown: { id, label, tokens, color? }[], e.g. system / tools / files / history. Enables the hover card and the segmented bar. Colors default to ink tints. |
| variant | "ring" | "bar" | "ring" | ring = 18px donut + value for tight toolbars; bar = horizontal (segmented) bar + value. |
| warningAt | number | 0.7 | Fraction (0–1) from which the meter is amber. |
| dangerAt | number | 0.9 | Fraction (0–1) from which the meter is red. |
| valueDisplay | "percent" | "tokens" | "none" | — | Value next to the meter: 42% or 84.2k / 200k. Default percent for ring, tokens for bar. |
| label | string | "Context" | Name used in the accessible label and the card title (“Context window”). |
| footer | React.ReactNode | — | Note at the bottom of the card. Defaults to a warning sentence at warning/danger levels. |
| open | boolean | — | Hover card open (controlled). |
| onOpenChange | (open: boolean) => void | — | Called when the hover card opens or closes. |
All native attributes of the root element, className and ref pass through.
Anatomy
- ContextMeterTrigger button. `data-variant`, `data-level="ok" | "warning" | "danger"`.
data-slot="context-meter" - RingSVG donut (aria-hidden).
data-slot="context-meter-ring" - BarTrack + fill; segmented by `segments` while level is ok, a single amber/red fill above the thresholds.
data-slot="context-meter-bar" - ValueMono tabular value that rolls to new numbers.
data-slot="context-meter-value" - CardHover/click card: totals, segmented bar, legend with tokens and % of the window, free space, footer.
data-slot="context-meter-card" - SegmentOne legend row.
data-slot="context-meter-segment"
Accessibility
- The meter is a button whose accessible name carries the full reading: “Context: 84,210 of 200,000 tokens used (42%, filling up)”.
- The breakdown opens on hover (300ms delay) and on click/Enter, without moving focus; Escape closes it.
- Levels are conveyed in text (name + card footer), not only by colour.
- Reduced motion: Numbers, ring and bar jump to the new value instead of rolling/growing; the card only fades.
| Keys | Action |
|---|---|
| Enter / Space | Open or close the breakdown card |
| Escape | Close the card |
Notes for agents
- Pass `segments` whenever you know the breakdown; the meter then sums them and gets a hover card. Without segments it is a plain reading (no card).
- Use the provider's real window size for `max` (e.g. 200000) and recount after every turn — counts roll smoothly between values.
- For a quota rather than a context window, set `label` (e.g. "Output") and use variant="bar".