@toon-ui/react
v2.0.1
Published
React runtime and component registry for ToonUI.
Readme
@toon-ui/react
@toon-ui/react is the explicit React integration layer for ToonUI.
Use it when you want to own the UI adapter instead of relying on the default client package.
Quick path
- Server:
createToonProtocol()from@toon-ui/core. - Client: build an adapter with
createToonReactAdapter(). - Create a runtime with
createToonReactRuntime({ adapter }). - Render with
ToonMessageorToonRenderer. - Reinject interactions with
runtime.messages.*.
Install
In a React host app:
pnpm add @toon-ui/core @toon-ui/reactDo NOT force react or react-dom in this command. Those belong to the host framework and should already be managed by the app.
Main exports
createToonReactAdapter()createToonAdapter()mergeToonComponentRegistry()createToonReactRuntime()assertToonReactAdapter()ToonMessageToonRendererextractToonMarkdowngetToonButtonProps()getToonInputProps()getToonTextareaProps()getToonCheckboxProps()basicPreset()useToonAction()
Recommended adapter pattern
import {
createToonReactAdapter,
createToonReactRuntime,
getToonButtonProps,
type ToonButtonComponentProps,
} from '@toon-ui/react';
function MyButton(props: ToonButtonComponentProps) {
return <button {...getToonButtonProps(props)}>{props.node.label}</button>;
}
const adapter = createToonReactAdapter({
level: 'default',
components: {
button: MyButton,
},
});
const runtime = createToonReactRuntime({ adapter });Why adapters matter
A raw component registry was weak API design.
An adapter makes the contract explicit:
- what UI you replace
- what defaults remain
- where interaction wiring comes from
- what coverage is still missing via
adapter.meta.missingKeys - whether the adapter is
minimal,default, orstrict
console.log(adapter.meta.level);
console.log(adapter.meta.providedKeys);
console.log(adapter.meta.missingKeys);Use the levels like this:
default-> merges ToonUI defaults plus your overridesminimal-> only what you register manuallystrict-> requires full coverage and throws if any adapter slot is missing
Reinjecting interactions
onReply={(payload) => {
const message = runtime.messages.toModelMessage(payload);
console.log(message.content);
console.log(message.displayContent);
}}For useChat-style state:
const next = runtime.messages.toUIMessage(payload);Hooks
useToonAction() now mirrors the protocol mental model:
const { events, messages } = useToonAction();