Streaming
Append the source prefix
Section titled “Append the source prefix”Pass everything received so far, preserving the previous prefix. OpenDIL forwards the new suffix to its parser worker. Pause delivery by leaving text unchanged and isStreaming={true}. Set it to false to finalize the document.
<DilRenderer key={messageId} text={source} isStreaming={receiving} />A new document, edited source, or replay needs a new React key. Source positions and chunk sizes use JavaScript UTF-16 code units; decode network bytes before appending them.
Progressive reveal
Section titled “Progressive reveal”Reveal is off by default. Enable it with true, or set the stagger and fade duration:
<DilRenderer text={source} isStreaming={receiving} progressiveReveal={{ staggerMs: 50, durationMs: 180 }}/>New visual blocks fade once. Completed content and returning virtualized views stay presented. Reduced motion skips the animation. Containers can resize as content arrives or wraps; the renderer does not retain their largest height.
Update cadence
Section titled “Update cadence”updateInterval="instant" is the default. A numeric interval coalesces background presentation work while source keeps arriving:
<DilRenderer text={source} isStreaming={receiving} updateInterval={200} />This allows at most one scheduled streaming presentation update per interval. It does not wait for a quiet stream. Native edits and user-action binding refreshes stay responsive. Values must be finite and nonnegative; 0 is immediate.
Follow the stream
Section titled “Follow the stream”import { useRef, useState } from "react";import { DilRenderer, type DilRendererHandle } from "@snackbit/opendil";
function Answer({ text, receiving }: { text: string; receiving: boolean }) { const renderer = useRef<DilRendererHandle>(null); const [following, setFollowing] = useState(false); function jump() { renderer.current?.resumeAutoScroll(); } return ( <> <DilRenderer ref={renderer} text={text} isStreaming={receiving} autoScroll={{ behavior: "smooth", padding: 32 }} onFollowChange={setFollowing} /> {receiving && !following && ( <button onClick={jump}>Jump to latest</button> )} </> );}Following uses page scrolling. Any wheel gesture, touch scroll, scrollbar drag, or page-scroll key pauses it immediately. It stays paused until resumeAutoScroll() is called. Padding uses available page space below the message rather than adding blank content. Reduced motion uses instant scrolling.
Following remains engaged after source completion to catch late chart and expression layout. Animation frames stop while the view is settled; a later resize resumes tracking. For multiple messages, enable auto-scroll only on the active or latest renderer.
Try real token delivery
Section titled “Try real token delivery”The demo replays o200k_base tokens at 1–1000 tokens/sec. This is a demo transport; your application can use its own model provider or stream. The advanced benchmark mode uses explicitly labelled character workloads.