REACT ARCH / DOCUMENTATION

API reference

Every supported runtime export and public type, with concrete examples for the values each function expects and returns.

Entry points

ImportContains
react-arch-diagramsAll core and React exports.
react-arch-diagrams/coreSerializable records, layout, geometry, routing, and animation helpers.
react-arch-diagrams/reactReact components, hooks, renderer types, interaction, and spawn types.
react-arch-diagrams/elkThe ELK layout function and LayoutEngine adapter.
react-arch-diagrams/styles.cssDefault canvas, node, edge, port, selection, and animation styles.

React exports

ExportPurpose
DiagramRenders the diagram, camera, selection, dragging, spawning, and serialization handle.
DefaultNodeRenders node.label, or node.id when no label exists.
DefaultEdgeRenders the routed path, hit target, markers, label, selection, and edge animation.
useDiagramLayoutRuns layout and routing, reports loading and errors, and discards stale asynchronous results.
react-api.tsx
const diagramRef = useRef<DiagramHandle>(null);

type StatusData = { status: string };

function StatusNode({ node, selected, dragging }: NodeRendererProps<StatusData>) {
  return <div data-selected={selected} data-dragging={dragging}>{node.data?.status}</div>;
}

function DashedEdge(props: EdgeRendererProps) {
  return <DefaultEdge {...props} edge={{ ...props.edge, className: "dashed-edge" }} />;
}

const nodeTypes: NodeTypes<StatusData> = { default: DefaultNode, status: StatusNode };
const edgeTypes: EdgeTypes = { dashed: DashedEdge };

<Diagram
  ref={diagramRef}
  nodes={document.nodes}
  edges={document.edges}
  layout={document.layout}
  nodeTypes={nodeTypes}
  edgeTypes={edgeTypes}
  shapes={shapes}
  layoutEngine={elkLayoutEngine}
  width="100%"
  height={560}
  padding={48}
  className="system-map"
  style={{ borderRadius: 0 }}
  ariaLabel="Checkout service architecture"
  fit
  spawn={{ mode: "flow", animation: "scale" }}
  interactive={{ pan: true, zoom: true, dragNodes: true, select: true }}
  selectedNodeIds={[selectedNodeId]}
  selectedEdgeIds={[selectedEdgeId]}
  onNodeClick={(node) => setSelectedNodeId(node.id)}
  onEdgeClick={(edge) => setSelectedEdgeId(edge.id)}
  onNodeMove={(id, position) => savePosition(id, position)}
  onLayout={(result) => console.log(result.bounds)}
  onError={(error) => reportError(error)}
  empty={<p>No services</p>}
/>;

diagramRef.current?.fit();
diagramRef.current?.zoomTo(1.5, { x: 400, y: 240 });
diagramRef.current?.panTo({ x: 600, y: 300 });
diagramRef.current?.replaySpawns();
const svg = diagramRef.current?.getSvgElement();
const markup = diagramRef.current?.toSvgString();
use-diagram-layout.tsx
function RoutedPreview({ document }: { document: DiagramDocument }) {
  const { result, loading, error } = useDiagramLayout(document);

  if (loading) return <p>Calculating layout</p>;
  if (error) return <p>{error.message}</p>;
  return <pre>{JSON.stringify(result, null, 2)}</pre>;
}

Diagram props

PropDefaultPurpose
nodesrequiredSerializable node records.
edgesrequiredSerializable edge records.
layoutmanualManual, row, column, grid, or layered layout.
nodeTypes{}Custom React node renderers keyed by node.type.
edgeTypes{}Custom SVG edge renderers keyed by edge.type.
shapesbuilt-insCustom boundary intersection functions keyed by node.shape.
layoutEnginelazy ELKEngine used when layout.type is layered.
width100%Diagram container width.
height500Diagram container height.
padding40Diagram units added around fitted bounds.
classNamenoneClass added to the outer container.
stylenoneInline styles added to the outer container.
ariaLabelArchitecture diagramAccessible name for the SVG document.
interactivepan, zoom, selectBoolean or individual pan, zoom, dragNodes, and select switches.
fittrueRefits while layout changes until the user moves the camera.
selectedNodeIds[]Controlled node selection styling.
selectedEdgeIds[]Controlled edge selection styling.
spawnfalseFlow-depth or timed node entrance options.
onNodeClicknoneReports the positioned node and mouse event.
onEdgeClicknoneReports the routed edge and mouse event.
onNodeMovenoneReports the node id and final position after dragging.
onLayoutnoneReports each completed layout result.
onErrorinline alertReports layout or routing errors.
emptynullContent rendered when nodes is empty.

Diagram handle

MethodExample
fit()diagram.current?.fit()
zoomTo(zoom, center?)diagram.current?.zoomTo(1.5, { x: 400, y: 240 })
panTo(center)diagram.current?.panTo({ x: 600, y: 300 })
replaySpawns()diagram.current?.replaySpawns()
getSvgElement()diagram.current?.getSvgElement()
toSvgString()diagram.current?.toSvgString()

Node spawn options

OptionDefaultValues
modeflowflow or time
delay0Non-negative milliseconds before the first node.
interval180Milliseconds between graph layers or ordered nodes.
duration320Entrance duration in milliseconds.
animationscalefade, scale, or slide-up

Document builders

ExportPurpose
defineDiagram(document)Keeps node and edge data inference while returning the same serializable document.
node(id, options?)Creates a node record.
edge(id, from, to, options?)Creates an edge record.
anchors.auto(nodeId)Clips to the node shape toward the next route point.
anchors.side(nodeId, side, position?, offset?)Targets a normalized position on one side.
anchors.port(nodeId, portId)Targets a port declared on the node.
anchors.point(x, y)Uses an absolute diagram point as an endpoint.
routes.straight()Connects the resolved endpoints directly.
routes.elbow(axis?, radius?)Creates one bend.
routes.orthogonal(axis?, split?, radius?, avoidance?)Creates a middle corridor and avoids unrelated nodes by default.
routes.manual(points, radius?)Routes through supplied intermediate points.
routes.auto(radius?, avoidance?)Uses engine points when present, then falls back to obstacle-aware routing.
layouts.manual()Reads node.position.
layouts.row(options?)Places nodes left to right.
layouts.column(options?)Places nodes top to bottom.
layouts.grid(options?)Places nodes in measured grid cells.
layouts.layered(options?)Requests layered ELK layout.
builders.ts
const api = node("api", {
  label: "API",
  ports: [{ id: "events", side: "right", position: 0.75 }]
});

const publish = edge("publish", anchors.port("api", "events"), anchors.auto("queue"), {
  route: routes.orthogonal("horizontal", 0.4, 10)
});

anchors.side("api", "bottom", 0.25, 6);
anchors.point(640, 180);

routes.straight();
routes.elbow("vertical", 8);
routes.orthogonal("horizontal", 0.35, 12, { clearance: 16 });
routes.manual([{ x: 300, y: 80 }, { x: 300, y: 240 }], 10);
routes.auto(8, { avoidNodes: true, avoidEdges: true });

layouts.manual();
layouts.row({ gap: 48, align: "center" });
layouts.column({ gap: 32, align: "start" });
layouts.grid({ columns: 3, columnGap: 48, rowGap: 36 });
layouts.layered({ direction: "right", spacing: 48, layerSpacing: 80 });

const document = defineDiagram({ nodes: [api, node("queue")], edges: [publish] });

Layout and document functions

ExportPurpose
computeDiagramRuns layout and routing and returns a DiagramResult.
arrangeDocumentRuns manual, row, column, or grid layout synchronously.
resolveNodeSizesResolves explicit, measured, minimum, and default dimensions.
DEFAULT_NODE_SIZEThe 160 by 64 fallback size.
layout-api.ts
const measured = new Map([
  ["api", { width: 210, height: 72 }]
]);

DEFAULT_NODE_SIZE;                         // { width: 160, height: 64 }
resolveNodeSizes(document.nodes, measured);
const layout = arrangeDocument(
  { ...document, layout: layouts.grid({ columns: 2 }) },
  measured
);
const complete = await computeDiagram(document, { sizes: measured });

Geometry functions

ExportPurpose
resolveEndpointResolves point, node, side, and port endpoints.
endpointNodeIdReturns the referenced node id, if the endpoint has one.
endpointCenterReturns an endpoint point or referenced node center.
rectangleIntersectionIntersects a center ray with a rectangle.
ellipseIntersectionIntersects a center ray with an ellipse.
sidePointCalculates an exact position on a node side.
inferSideChooses the cardinal side that faces a target point.
boundsOfNodesCalculates the union of positioned node bounds.
nodeBoundsConverts one positioned node into Bounds.
centerOfCalculates the center of Bounds.
clampConstrains a number to an inclusive range.
builtInShapesContains rectangle, rounded-rectangle, and ellipse intersection functions.
geometry-api.ts
const bounds = { x: 20, y: 40, width: 160, height: 80 };
const toward = { x: 400, y: 100 };

clamp(1.4, 0, 1);                         // 1
centerOf(bounds);                          // { x: 100, y: 80 }
rectangleIntersection(bounds, toward);     // rectangle boundary point
ellipseIntersection(bounds, toward);       // ellipse boundary point
sidePoint(bounds, "right", 0.25, 4, 6);   // exact side point
inferSide(centerOf(bounds), toward);        // "right"
builtInShapes.ellipse.intersect(bounds, toward);

const positioned = { ...node("api"), position: { x: 20, y: 40 }, width: 160, height: 80 };
const nodes = new Map([["api", positioned]]);

nodeBounds(positioned);
endpointNodeId(anchors.auto("api"));        // "api"
endpointCenter(anchors.auto("api"), nodes); // node center
resolveEndpoint({ nodes, endpoint: anchors.side("api", "right"), toward });
boundsOfNodes([positioned], 24);

Routing functions

ExportPurpose
routeEdgeRoutes one edge against a positioned-node map.
routeEdgesRoutes an edge list against positioned nodes.
pointsToPathConverts points into an SVG path with optional rounded corners.
midpointOnPolylineFinds the length-weighted midpoint used for labels.
routing-api.ts
const points = [{ x: 0, y: 0 }, { x: 100, y: 0 }, { x: 100, y: 80 }];

pointsToPath(points, 10);      // rounded SVG path string
midpointOnPolyline(points);    // point halfway along total path length

const one = routeEdge(
  edge("ab", anchors.auto("a"), anchors.auto("b")),
  positionedNodesById
);
const all = routeEdges(edges, positionedNodes, {
  shapes,
  engineRoutes: { ab: points }
});

Animation functions

ExportPurpose
prefersReducedMotionReads the browser reduced-motion media query.
animateElementRuns Web Animations unless reduced motion is active.
animation-api.ts
if (!prefersReducedMotion()) {
  animateElement(card, [
    { opacity: 0, transform: "translateY(8px)" },
    { opacity: 1, transform: "translateY(0)" }
  ], { duration: 240, easing: "ease-out" });
}

ELK exports

ExportPurpose
layoutWithElkRuns layered layout and returns positioned nodes plus engine route points.
elkLayoutEngineAdapts layoutWithElk to the LayoutEngine contract used by computeDiagram and Diagram.
elk-api.ts
import { computeDiagram } from "react-arch-diagrams/core";
import { elkLayoutEngine, layoutWithElk } from "react-arch-diagrams/elk";

const layoutOnly = await layoutWithElk(document, measuredSizes);
const routed = await computeDiagram(document, {
  layoutEngine: elkLayoutEngine,
  sizes: measuredSizes
});

Core types

PointSizeBoundsAxisDirectionSideBuiltInShapePortSpecNodeEndpointPointEndpointEndpointStraightRouteElbowRouteRouteAvoidanceOptionsOrthogonalRouteManualRouteAutoRouteRouteSpecDiagramNode<T>EdgeAnimationDiagramEdge<T>ManualLayoutFlowLayoutGridLayoutLayeredLayoutLayoutSpecDiagramDocument<NodeData, EdgeData>PositionedNode<T>RoutedEdge<T>LayoutResult<T>DiagramResult<NodeData, EdgeData>ShapeDefinitionShapeRegistryRouteOptionsResolveEndpointOptionsLayoutEngineComputeDiagramOptions

React types

DiagramProps<NodeData, EdgeData>DiagramHandleDiagramLayoutState<NodeData, EdgeData>InteractionOptionsNodeSpawnModeNodeSpawnAnimationNodeSpawnOptionsNodeRendererProps<T>NodeRenderer<T>NodeTypesEdgeRendererProps<T>EdgeRenderer<T>EdgeTypes

Complete diagrams

The diagram recipes use these APIs in service maps, request paths, event pipelines, deployment flows, state machines, data lineage, dependency graphs, and network topology.