Logo

React

@smoothstream/react is the React adapter. It drives the shared engine from animation frames and turns presentation snapshots into React elements.

npm install @smoothstream/react
pnpm add @smoothstream/react
yarn add @smoothstream/react
bun add @smoothstream/react

Peer dependencies: react and react-dom at 18.2 or 19. Reveal CSS and the default prose theme import automatically.

Render Markdown children

Pass one accumulated Markdown string as children. The public type is children?: string; omit it or pass an empty string while waiting for the first text. Pass Markdown as data rather than inserting React elements inside the component.

AssistantMessage.tsx
import { Smoothstream } from "@smoothstream/react"; export function AssistantMessage({  text,  receiving,}: {  text: string;  receiving: boolean;}) {  return (    <Smoothstream className="assistant-markdown" receiving={receiving}>      {text}    </Smoothstream>  );}

className is applied to the Markdown root. Use it for layout and token overrides.

Chat messages

Keep the in-flight answer in streaming mode. Render stored messages as static so they appear immediately and skip the completion announcement.

<>  {history.map((message) => (    <Smoothstream key={message.id} mode="static">      {message.content}    </Smoothstream>  ))}  <Smoothstream key={active.id} receiving={active.receiving}>    {active.content}  </Smoothstream></>

When receiving becomes false, leave that streaming instance mounted until presentation finishes. Moving it into a different history subtree can remount it even with the same key. Start the next assistant turn with a new key.

The complete streaming example includes text accumulation, cancellation, request errors, and effect cleanup.

Completion callbacks

Use onRevealComplete to show follow-up controls when the final presentation unit begins appearing, or onPresentationComplete after all entrances and reveal-node compaction finish. Both fire once after receiving becomes false. See Completion callbacks for the timing details and a two-stream handoff example.

Next.js and SSR

The published entry is a Client Component, so you can import Smoothstream from a Server Component and still get a client boundary.

mode="static" emits settled semantic HTML on the server and hydrates in place.

In streaming mode with reducedMotion="system" (the default), the server and first hydration share an empty motion-pending shell. The browser then reads prefers-reduced-motion before Markdown appears. An empty stream can resolve that policy while it waits for the first token. Forced "always" and "never" policies are deterministic during SSR and skip the pending state.

Browser-only work such as image loading, syntax highlighting, and clipboard copy starts after mount.

Timing props remount playback

Changing interval, duration, mode, or reveal on a mounted component remounts playback so the new timing applies to a fresh schedule. Treat those as per-response settings, not knobs to twist while tokens arrive.

Full option list: API.

© 2026 Smoothstream. All rights reserved.

Built withRadiant Docs