Getting started
OpenDIL renders a growing text response as an interactive React interface. Your application supplies the source; the document can contain Markdown, controls, charts, and its own state.
Install
Section titled “Install”Use React 19.
npm install @snackbit/opendil react react-domFor the default iframe isolation mode (mode="isolated"), also copy the runtime assets. The asset CLI requires Node 22 or newer:
npx opendil copy-assets --out public/opendilServe the copied opendil directory with your application. The iframe renderer loads its sandboxed frame from /opendil/frame.html. Copy these assets again when you upgrade the package.
Host (mode="host") and Shadow DOM (mode="shadow") modes do not require copy-assets. Their runtime code and workers are bundled with your application.
Render a document
Section titled “Render a document”import { DilRenderer } from "@snackbit/opendil";import "@snackbit/opendil/styles.css";
export function Answer() { return <DilRenderer text="<title>Hello, interface.</title>" />;}Add interaction
Section titled “Add interaction”Document state lives in a bounded QuickJS worker. A control updates that state, and expressions supply the next values to the interface.
{@body const [name, setName] = DIL.useState("Ada")}{@body const [notifications, setNotifications] = DIL.useState(true)}<box border padding={5} radius="xl" gap={4}> <title size="xl">Make yourself at home.</title> <label>Display name</label> <input aria-label="Display name" value={name} onChange={setName} /> <checkbox checked={notifications} onChange={setNotifications}> Send me release updates </checkbox> <box background="surface-secondary" radius="lg" padding={4} gap={2} > <title>Welcome, {name || "friend"}.</title> <text color="secondary">Release updates are {notifications ? "on" : "off"}.</text> </box></box>Send a stream
Section titled “Send a stream”<DilRenderer key={messageId} text={sourceReceivedSoFar} isStreaming={receiving}/>Append to the existing source prefix. Set isStreaming={false} after the final chunk. Use a new key to replace, edit, or restart a document. The renderer does not connect to a model provider or own your network transport.
Read Streaming for reveal, update cadence, and scroll following.
Configure asset paths
Section titled “Configure asset paths”runtimeBaseUrl applies only to iframe mode. For an application hosted below a subpath, point to the matching runtime directory:
<DilRenderer text={source} runtimeBaseUrl="/my-app/opendil/" />Keep the runtime assets and npm package on the same version. See Isolation for Shadow DOM and host rendering, and Customization for your own components and theme.