Skip to content
Sign in
PlaygroundGeneration statsMenu

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.

One quiet line of figures, with the full breakdown behind the info button.

Installation

$ pnpm dlx shadcn@latest add https://chatcn.dev/r/generation-stats.json

Usage

tsx
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.

Opens on hover with a mouse, or on click and tap. Shows cached and reasoning tokens.

Live while streaming

Figures update in place at fixed widths, so the line never shifts.

Dev panel

The breakdown in place, for an inspector sidebar.

States

Token limit, content filter, provider error, missing values and waiting.

Props

PropTypeNotes
variant"inline" | "popover" | "panel"Defaults to inline
modelstringSet in mono
ttftMs, durationMsnumberTime to first token and total time
tokensPerSecondnumberOutput speed
inputTokens, cachedInputTokensnumberCached shows under input in the breakdown
outputTokens, reasoningTokensnumberReasoning shows under output in the breakdown
cost, currency, localenumber, stringFormatted like cost-display
finishReasonstringstop, length, tool-calls, content-filter, error, other
livebooleanFixed-width figures and a Streaming status
fieldsGenerationStatField[]Inline fields in order. Add duration for total time
label, defaultOpenstring, booleanPopover trigger label and initial state

Keyboard

KeyAction
Enter, SpaceOpen the popover from the info button
EscapeClose 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-label and 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.