Message Scroller

A reader-aware transcript that follows streamed output at the live edge, lets go when the reader scrolls away, and offers a metal pill with a thought orb to come back.

What should the first release include?
Start with the smallest workflow that still feels complete.
Include streaming and recovery states too.
Yes. Those states make the first version feel dependable.
How should we present tool results?
Keep results close to the action that produced them.
What about actions that need confirmation?
Pause the run, explain the impact, and ask before continuing.
Can the transcript stay easy to navigate?
Use the rail to jump between turns without losing your place.

Install

Steps for Next.js.

  1. Install the package

    One package carries every component, the beUI base they build on, and the effect libraries.

    bun add @poulo2/ai-components
  2. Load the styles with Tailwind v4

    Add both lines to your global stylesheet so Tailwind generates the classes the components use. If your app already defines the shadcn/ui tokens, skip the theme import to keep your own palette.

    @import "@poulo2/ai-components/theme.css";
    @source "../node_modules/@poulo2/ai-components/dist";
  3. Or load the prebuilt stylesheet

    For apps without Tailwind. Import it once at the root; it includes Tailwind's base reset.

    import "@poulo2/ai-components/styles.css";

Props

NameTypeDefaultDescription
busyboolean—Marks the transcript as streaming. The pill then shows the orb and the streaming label.
navigation"rail"—Adds a compact rail for jumping between message rows.
jumpLabelstring"Jump to latest"Label of the pill when nothing is streaming.
streamingLabelstring"New reply"Label of the pill while busy.
metalbooleantrueWraps the pill in the liquid-metal ring.
fadeEdgesbooleantrueSoftens the top and bottom edges of the transcript.
followOutputbooleantrueKeeps streamed output pinned while the reader is near the end.
followThresholdnumber56Distance from the end that still counts as following.
smoothbooleantrueSmoothly follows growing content and the jump back.
onFollowChange(following: boolean) => void—Reports when the reader leaves or returns to the live edge.
labelstring"Conversation"Accessible label for the scrollable transcript.