Components
Built-in components that ship with @barefootjs/xyflow. Drop them inside <Flow> (or compose into custom nodes / edges).
#Overview
@barefootjs/xyflow ships seven JSX-native components. Most pages only need <Flow> with a <Background> and <Controls>; the rest opt in for richer flows (minimap, custom nodes, custom edges).
#Everything together
1import { Flow, Background, Controls, MiniMap } from "@/components/ui/xyflow"23const initialNodes = [4 { id: "1", position: { x: 100, y: 100 }, data: { label: "Input" } },5 { id: "2", position: { x: 350, y: 50 }, data: { label: "Transform" } },6 { id: "3", position: { x: 350, y: 200 }, data: { label: "Validate" } },7 { id: "4", position: { x: 600, y: 125 }, data: { label: "Output" } },8]9const initialEdges = [10 { id: "e1-2", source: "1", target: "2" },11 { id: "e1-3", source: "1", target: "3" },12 { id: "e2-4", source: "2", target: "4" },13 { id: "e3-4", source: "3", target: "4" },14]1516<Flow nodes={initialNodes} edges={initialEdges}>17 <Background variant="dots" gap={20} />18 <Controls />19 <MiniMap pannable zoomable />20</Flow>#<Flow>
The top-level container. Owns the store, the viewport transform, pan / zoom / drag subsystems, and the per-node measurement loop. Accepts nodes, edges, optional nodeTypes / edgeTypes maps, and any of the overlays below as children.
| Prop | Type | Default | Description |
|---|---|---|---|
| nodes | NodeBase[] | - | Initial node list. Each node needs `id`, `position: { x, y }`, and `data: {…}`. |
| edges | EdgeBase[] | - | Initial edge list. Each edge needs `id`, `source`, `target`. |
| nodeTypes | Record<string, NodeComponent> | - | Map of `node.type` → custom component for rendering. |
| edgeTypes | Record<string, EdgeComponent> | - | Map of `edge.type` → custom component for rendering. |
| children | Child | - | Slot for `<Background>` / `<Controls>` / `<MiniMap>` overlays. |
#<Background>
Pattern background that scales and pans with the viewport. Three variants — "dots", "lines", "cross" — plus gap / color tuning. The default color resolves to var(--border) so the pattern stays subtle in both light and dark themes.
#Variants
1import { Flow, Background } from "@/components/ui/xyflow"23export function Variants() {4 return (5 <div className="grid grid-cols-3 gap-4">6 <Flow nodes={[]} edges={[]}>7 <Background variant="dots" gap={20} />8 </Flow>9 <Flow nodes={[]} edges={[]}>10 <Background variant="lines" gap={30} />11 </Flow>12 <Flow nodes={[]} edges={[]}>13 <Background variant="cross" gap={32} />14 </Flow>15 </div>16 )17}| Prop | Type | Default | Description |
|---|---|---|---|
| variant | "dots" | "lines" | "cross" | "dots" | Pattern style. |
| gap | number | 20 | Spacing between pattern repeats (in flow coordinates, scales with zoom). |
| color | string | "var(--border)" | Pattern color. Defaults to the design-system border token so light / dark themes adapt. |
#<Controls>
Zoom-in / zoom-out / fit-view / lock buttons. Each button is opt-out via the show* props; corner placement via position.
| Prop | Type | Default | Description |
|---|---|---|---|
| position | "top-left" | "top-right" | "bottom-left" | "bottom-right" | "bottom-left" | Corner the controls float in. |
| showZoom | boolean | true | Show zoom-in / zoom-out buttons. |
| showFitView | boolean | true | Show fit-view button. |
| showInteractive | boolean | true | Show the lock toggle. |
#<MiniMap>
Overview map with a synced viewport rectangle. Pannable and zoomable by default; per-node colours via the nodeColor prop (string or function).
| Prop | Type | Default | Description |
|---|---|---|---|
| pannable | boolean | true | Allow drag-to-pan inside the minimap. |
| zoomable | boolean | true | Allow wheel zoom on the minimap. |
| nodeColor | string | (node) => string | "#e2e8f0" | Per-node fill color in the minimap. |
#<Handle>
Per-node connection point. Render inside a custom node body with a type ("source" | "target") and a position. Pass a stable id when a node has more than one handle on the same side so edges can target a specific connection point.
| Prop | Type | Default | Description |
|---|---|---|---|
| type | "source" | "target" | "source" | Whether this handle starts (`source`) or accepts (`target`) a connection. |
| position | Position | Position.Top | Where on the node body the handle sits — `Top`, `Bottom`, `Left`, or `Right`. |
| nodeId | string | - | Id of the parent node. Required so the connection layer can resolve handle bounds. |
| id | string | - | Optional handle id. Required when a node has more than one handle of the same type so edges can pin via `sourceHandle` / `targetHandle`. |
#<NodeWrapper>
The transform / selection / measurement shell Flow mounts around every node. Most consumers don't reach for it directly — it shows up when you want the wrapper styling but need a fully manual rendering path instead of the nodeTypes map.
| Prop | Type | Default | Description |
|---|---|---|---|
| nodeId | string | - | Stable id of the node inside `store.nodeLookup()`. |
| children | Child | - | Slot for the rendered node body. |
| ref | (element: HTMLElement) => void | - | Optional ref callback for low-level imperative work; rarely needed. |
#<SimpleEdge>
The default edge renderer. Reads the edge's type / animated / selected flags and draws a stroke alongside an invisible wide hit area for click selection.
| Prop | Type | Default | Description |
|---|---|---|---|
| edgeId | string | - | Stable id of the edge inside `store.edgeLookup()`. Used to read `type`, `selected`, `animated` reactively. |