Generation stats
How a response was generated: model, time to first token, tokens per second, input and output tokens, cost and finish reason. A quiet line under a message, an info popover, or a breakdown for dev panels, with a live mode that never shifts.
On this page
Installation
Usage
import { GenerationStats } from "@/components/ui/chatcn/generation-stats"
<GenerationStats
model="claude-sonnet-5-5"
ttftMs={412}
tokensPerSecond={86.4}
inputTokens={4812}
outputTokens={182}
cost={0.0172}
finishReason="stop"
/>Every value is optional. The inline line leaves out what is missing, and the breakdown says Not reported. Finish reasons follow the AI SDK names: length and content-filter read in amber with a warning glyph and a hint on how to fix it, error in red.
With live, time to first token, speed and output tokens reserve their slots from the start, and every figure holds a fixed width in tabular digits while it updates, so nothing in the line moves as tokens arrive. The finish reason reads Streaming. Values update in place; they never animate or count up on their own.
Examples
Breakdown popover
variant="popover" is an info button for a message action bar. It opens after 300 ms of mouse hover, or on click and tap; clicking while hover-opened pins it.
Live while streaming
Dev panel
States
Props
| Prop | Type | Notes |
|---|---|---|
variant | "inline" | "popover" | "panel" | Defaults to inline |
model | string | Set in mono |
ttftMs, durationMs | number | Time to first token and total time |
tokensPerSecond | number | Output speed |
inputTokens, cachedInputTokens | number | Cached shows under input in the breakdown |
outputTokens, reasoningTokens | number | Reasoning shows under output in the breakdown |
cost, currency, locale | number, string | Formatted like cost-display |
finishReason | string | stop, length, tool-calls, content-filter, error, other |
live | boolean | Fixed-width figures and a Streaming status |
fields | GenerationStatField[] | Inline fields in order. Add duration for total time |
label, defaultOpen | string, boolean | Popover trigger label and initial state |
Keyboard
| Key | Action |
|---|---|
Enter, Space | Open the popover from the info button |
Escape | Close it and return focus to the button |
Accessibility
- Both layouts are description lists: TTFT and other short labels are hidden from screen readers, which hear Time to first token instead.
- The info button has an
aria-labeland grows to 44 px on touch screens. Hover opening is mouse only; touch and keyboard open on press. - Warnings pair amber or red with a glyph and a word.
Motion
- The popover uses the kit's 180 ms enter from its trigger, and opens without animation from the keyboard.
- Live figures change in place with no transition: they update many times a second.