Skip to content
OpenDIL
GitHub☆ 2

Streaming

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.

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.

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.

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.

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.