Reasoning

Shows the model's reasoning as it streams, then folds it away behind a short “Thought for 12s” line.

Loading preview…

Install

  1. 1

    Run this command in your Tailwind CSS project. It adds components/ai/reasoning-collapsible.tsx and installs its dependencies.

    $ npx shadcn@latest add https://gradientdeck.com/ai-components/r/reasoning-collapsible.json

Usage & API

Example

reasoning-collapsible.tsx
import { Reasoning } from "@/components/ai/reasoning-collapsible"

<Reasoning
  text="…"
  streaming={true}
/>

Props Reasoning

PropType & descriptionRequired
textstringThe reasoning text so far. Grows while streaming.Required
streamingbooleanRequired
secondsnumberHow long the model thought, shown once streaming ends.Optional
autoCollapsenumber | falseClose the panel this many ms after streaming ends. Set to false to keep it open.Optional

Dependencies

  • React
  • Tailwind CSS
  • motion
  • lucide-react
Implementation notes

Collapsible exports Reasoning. While streaming is true the trigger reads Thinking… with a moving shine, and the panel is open. When streaming ends, the label becomes Thought for {seconds}s, or Thought for a moment if seconds is omitted. A timer then calls setOpen(false) after autoCollapse, unless that prop is false. Clicking the button toggles the panel at any time, and aria-expanded follows the open state. The sample walks a weekend in Lisbon for two under €600: easyJet out, TAP back, two nights in Baixa, about €540. The Replay control under the answer is demo chrome, not part of Reasoning.

Choosing a layout

Use it when the wait is long enough that a blank gap feels stuck, and the notes are something a person might actually read. Collapsible fits a normal chat: the thinking is there, then it gets out of the way so the answer can sit underneath. Rail fits a trace you want to watch, such as a debugging note, because the folded state already shows the newest lines instead of hiding everything.

Skip it when there is no separate reasoning channel, or when the thinking is a list of named steps, searches, or rejected options. That is Chain of thought. A wait with no text yet is Loader: an orb, dots, bars, or a spinner, optionally with a label. Do not put the finished answer inside text. In both previews the answer is a sibling that appears once streaming is false.

Does the panel close on its own?

Only Collapsible does. Reasoning starts open while streaming is true, then waits autoCollapse milliseconds, 800 by default, and closes. Set autoCollapse to false to leave it open. ReasoningRail never starts a timer. It stays at previewHeight until the person clicks, and it stays fully open after that click until they click again. Both components keep that open flag in local state. There is no open prop to control from outside.

What is shown if I leave seconds unset?

Reasoning uses Thought for a moment once streaming is false and seconds is missing. While streaming it always shows Thinking…, even if you passed seconds for later. ReasoningRail uses the word Reasoning in both of those cases. It only switches to Reasoned for {seconds}s after streaming ends and seconds is a number. The Lisbon demo passes 12. The CI demo passes 9. The number is display text, not a clock the component runs.