partial-react
v0.0.8
Published
A state-preserving renderer for prefix-growing streaming React/TSX.
Readme
partial-react
Renderer for generated React/TSX.
Input
GenUIRenderer accepts TSX source strings:
import { GenUIRenderer } from "partial-react";
const renderer = await GenUIRenderer.create(document.getElementById("preview"), {
preserveStateOnUpdate: true,
callbacks: {
onRendered: (_component, code) => console.log(code),
onError: (error, phase) => console.error(phase, error),
},
});
renderer.render("export default function App() { return <div>Hello world</div>; }");Output
- The target element receives a React preview.
onReady(component, url, code)fires after a module compiles and imports.onRendered(component, code, serial)fires after React commits.onError(error, phase)reports"transform","compile", or"render".
Imports
import { GenUIRenderer } from "partial-react";
import { createTsxCompiler } from "partial-react/compiler";
import { mergeFallbackImports, prepareRendererImportMap } from "partial-react/import-map";
import { useGenUIRenderContext } from "partial-react/render-context";Bundlers
The loader's import() specifiers are computed at runtime — a blob URL for the generated module, import-map targets for its dependencies — so no bundler may resolve them at build time. They carry @vite-ignore, webpackIgnore: true, and turbopackIgnore: true together, which covers Vite, webpack/Rspack, and Turbopack (Next.js); if you re-emit this source through a tool that strips comments, preserve those three.
Turbopack builds also need #1690: compiler.ts loads the tsx wasm through Vite's ?url query, which Turbopack rejects. Until that lands, Next.js consumers still need to patch that import.
State and Streaming
- Keep
preserveStateOnUpdate: truefor normal previews. It preserves useful React state and DOM continuity across regenerated code. - Set
preserveStateOnUpdate: falseonly when every update should remount from scratch, usually while debugging renderer state bugs. - Use the preview wrapper's
streamingprop (GenUIPreviewHost/StaticGenUIRenderer) when the input is still growing or being patched in place. It treats the code as partial TSX and avoids surfacing transient mid-stream errors. - Leave
streamingoff for complete snapshots, final answers, history replay, and deterministic one-shot renders.
Corner Cases
render(code)replaces the current buffer with a complete TSX module.clear({ preserveVisualState: true })clears pending code but leaves the last visual tree in place.- Missing default exports fail at compile/import time.
- Render failures call
onErrorand, with state preservation on, try to restore the last good component.
Test
bun test lib/partial-react