Reasoning
AICollapsible model thinking: a shimmering Thinking label with a live timer while it runs, then Thought for 12s, collapsed.
npx prodular-ui add reasoningThinking
Opens while the model thinks so people can follow along, and collapses when it is done.
"use client"
import * as React from "react"import { RotateCcwIcon } from "lucide-react"
import { Button } from "@/components/ui/button"import { Reasoning, ReasoningContent, ReasoningTrigger } from "@/components/ui/reasoning"
const THOUGHT = "The forecast asks for Q4 revenue with the Halcyon expansion included. Halcyon signed for 400 more seats at $38 a month starting November 1, so that adds two months of $15,200. I should also check whether the October churn from Orbis is already in the baseline before adding anything, otherwise the number will be counted twice."
const TOKENS = THOUGHT.match(/\S+\s*/g) ?? []
export default function ReasoningThinking() { const [count, setCount] = React.useState(0) const [run, setRun] = React.useState(0)
React.useEffect(() => { let n = 0 const id = setInterval(() => { n += 1 setCount(n) if (n >= TOKENS.length) clearInterval(id) }, 90) return () => clearInterval(id) }, [run])
return ( <div className="flex w-full max-w-xl flex-col items-start gap-6"> <Reasoning streaming={count < TOKENS.length} className="min-h-40"> <ReasoningTrigger /> <ReasoningContent>{TOKENS.slice(0, count).join("")}</ReasoningContent> </Reasoning> <Button variant="outline" size="sm" onClick={() => { setCount(0) setRun((r) => r + 1) }} > <RotateCcwIcon data-icon="inline-start" /> Think again </Button> </div> )}Done
Collapsed by default. The label carries the time spent.
Compared the three vendor quotes on total cost over 24 months, not the first year price. Kestrel is cheapest in year one but adds a 9% uplift at renewal, which makes Northbeam $11,800 cheaper over the full term.
import { Reasoning, ReasoningContent, ReasoningTrigger } from "@/components/ui/reasoning"
export default function ReasoningDone() { return ( <div className="flex w-full max-w-xl flex-col gap-4"> <Reasoning duration={12}> <ReasoningTrigger /> <ReasoningContent> The variance is concentrated in the Payroll line. October has 23 working days against 21 in September, and the two engineering hires started on October 6. Both explain most of the $41,300 increase, so the rest is within the normal range for overtime. </ReasoningContent> </Reasoning> <Reasoning duration={84} defaultOpen> <ReasoningTrigger /> <ReasoningContent> Compared the three vendor quotes on total cost over 24 months, not the first year price. Kestrel is cheapest in year one but adds a 9% uplift at renewal, which makes Northbeam $11,800 cheaper over the full term. </ReasoningContent> </Reasoning> </div> )}Anatomy
<Reasoning streaming={isThinking}> <ReasoningTrigger /> <ReasoningContent>{reasoningText}</ReasoningContent></Reasoning>Guidance
Use it when
- When the model exposes reasoning or a summary of it, above the answer it led to.
- Keep it collapsed for history. People open it when they doubt an answer.
Avoid
- Showing raw chain of thought your provider asks you not to show. Use a summary instead.
- Putting the answer inside Reasoning. The answer belongs in Response.
Rules for AI agents
Published in llms-full.txt, the registry and the MCP server, so coding agents follow them when they build with this component.
- Render Reasoning before tool calls and before Response inside the same assistant Message, in the order the model produced them.
- Set streaming to true while reasoning tokens arrive and false as soon as the first answer token or tool call starts.
- Pass duration in seconds when you load a finished message from history, so the label does not read 1s.
- Do not render Reasoning for models that do not reason. No empty Thinking rows.
API
Reasoning
| Prop | Type | Default | Description |
|---|---|---|---|
| streaming | boolean | false | Shimmer, live timer and auto open while true. |
| duration | number | Final thinking time in seconds. Measured automatically when omitted. | |
| openWhileStreaming | boolean | true | Open while thinking and collapse when it ends. |
| open / defaultOpen / onOpenChange | boolean | Control the expanded state. |
ReasoningTrigger
| Prop | Type | Default | Description |
|---|---|---|---|
| children | ReactNode | Replaces the automatic Thinking and Thought for label. |
Installation
The Prodular UI CLI adds the source to components/ui with everything it depends on. In a project that already uses shadcn/ui, the shadcn CLI installs it from the Prodular registry too. See Installation for the first setup.
npx prodular-ui add reasoning# or, with the registry in components.jsonnpx shadcn@latest add @prodular/reasoning