Quickstart
Pick the API path, drop a canvas into a page, and react to events.
Pick an API path
Three entry points, same canonical diagram. Pick the one that matches the surface you’re building; you can mix-and-match as you go.
- Embed / read-only.
WireProvider+WireCanvasinmode="view". This is what every card on the Layouts page does. - Custom editor.
WireProvider+WireCanvasinmode="edit", plusWireOptionPanelin a modal or sidebar — see Click → modal and Click → sidebar. - Full editor shell.
WireWorkspacebundles provider + sidebar + canvas + inspector for the “drop in and ship” case.
Minimal viewer
A WireDiagram is a plain object. Pass it to WireProvider, render WireCanvas, set a height on the parent — that’s the whole pattern.
"use client";
import {
WireProvider,
WireCanvas,
type WireDiagram
} from "@aigentive/wire-react";
const diagram: WireDiagram = {
version: 1,
id: "agent-chain",
layout: "LR",
nodes: [
{ id: "in", kind: "trigger", title: "Webhook" },
{ id: "ai", kind: "ai", title: "Plan answer", from: "in", model: "gpt-5.4-mini" },
{ id: "out", kind: "action", title: "Send reply", from: "ai", tone: "success" }
],
edges: []
};
export function AgentDiagram() {
return (
<div style={{ height: 320 }}>
<WireProvider defaultDiagram={diagram}>
<WireCanvas
mode="view"
fitView
fitViewPadding={0.2}
showControls={false}
showMiniMap={false}
/>
</WireProvider>
</div>
);
}Add typed options + click-to-inspect
Declare a WireOptionCatalog once. WireOptionPanel renders the form for whichever node you point it at and dispatches node.patch actions back into the diagram on edit. Wire onEvent on WireProvider to track the clicked node.
"use client";
import { useCallback, useState } from "react";
import {
WireProvider,
WireCanvas,
WireOptionPanel,
type WireEvent,
type WireOptionCatalog
} from "@aigentive/wire-react";
const options: WireOptionCatalog = {
ai: [
{ key: "model", storage: "node", type: "select",
options: ["gpt-5.4-mini", "gpt-4.1-mini", "o4-mini"] },
{ key: "temperature", type: "number", min: 0, max: 2, step: 0.1 }
],
action: [
{ key: "channel", type: "select",
options: ["email", "chat", "ticket", "slack"] }
]
};
export function AgentEditor({ diagram }) {
const [openId, setOpenId] = useState<string>();
const onEvent = useCallback((event: WireEvent) => {
if (event.type === "node.click") setOpenId(event.nodeId);
else if (event.type === "pane.click") setOpenId(undefined);
}, []);
return (
<WireProvider defaultDiagram={diagram} validateOnChange onEvent={onEvent}>
<div className="grid grid-cols-[1fr_320px]">
<WireCanvas mode="view" fitView />
{openId ? (
<aside className="border-l p-4">
<WireOptionPanel catalog={options} nodeId={openId} />
</aside>
) : null}
</div>
</WireProvider>
);
}Full editor shell
When you want the bundled experience — palette + canvas + inspector + validation panel — drop in WireWorkspace. It’s a controlled component: pass diagram + onChange and you keep the source of truth.
"use client";
import { useState } from "react";
import {
WireWorkspace,
type WireDiagram,
type WireOptionCatalog
} from "@aigentive/wire-react";
export function FullEditor({ initial, options }: {
initial: WireDiagram;
options: WireOptionCatalog;
}) {
const [diagram, setDiagram] = useState(initial);
return (
<WireWorkspace
diagram={diagram}
onChange={setDiagram}
optionCatalog={options}
onEvent={(e) => console.log(e.source, e.type)}
/>
);
}Author in JSX
Sometimes you want the diagram to live next to the component that owns it. The <Flow> facade compiles a tree of node markers into canonical JSON; the same renderer takes it from there.
import {
Flow,
TriggerNode,
AINode,
ActionNode
} from "@aigentive/wire-react";
export function AgentDiagram() {
return (
<Flow layout="LR">
<TriggerNode id="in" title="Webhook" />
<AINode id="ai" title="Plan answer" from="in" model="gpt-5.4-mini" />
<ActionNode id="out" title="Send reply" from="ai" tone="success" />
</Flow>
);
}Headless compile
<Flow> has two modes. mode="svg" (the default shown above) renders inline SVG. mode="json" renders nothing and instead fires onCompile with the canonical WireDiagram — perfect for capturing the JSON to save, send to an MCP server, or hand off to your own renderer.
import {
Flow,
TriggerNode,
AINode,
ActionNode,
type WireDiagram
} from "@aigentive/wire-react";
export function CompileOnly({ onSave }: { onSave: (d: WireDiagram) => void }) {
return (
<Flow mode="json" onCompile={onSave}>
<TriggerNode id="in" title="Webhook" />
<AINode id="ai" title="Plan answer" from="in" model="gpt-5.4-mini" />
<ActionNode id="out" title="Send reply" from="ai" tone="success" />
</Flow>
);
}Where next
- Concepts — the diagram shape, action reducer, and event surface.
- Customize cards — replace the default node renderer.
- Listen — the full
onEventsurface. - Examples — three layouts plus modal/sidebar interactions, all live on this site.