/react-flow
React Flow (@xyflow/react) for workflow visualization with custom nodes and edges. Use when building graph visualizations, creating custom workflow nodes, implementing edge labels, or controlling viewport. Triggers on ReactFlow, @xyflow/react, Handle, NodeProps, EdgeProps,
Claude Code
$ npx -y skills add shep-ai/shep --skill react-flow --agent claude-code
Codex
$ npx skills add shep-ai/shep --skill react-flow -a codex -y
Cursor
$ npx skills add shep-ai/shep --skill react-flow -a cursor -y
Gemini CLI
$ npx skills add shep-ai/shep --skill react-flow -a gemini-cli -y
GitHub Copilot
$ npx skills add shep-ai/shep --skill react-flow -a github-copilot -y
OpenCode
$ npx skills add shep-ai/shep --skill react-flow -a opencode -y
Windsurf
$ npx skills add shep-ai/shep --skill react-flow -a windsurf -y
SKILL.md
react-flow.SKILL.mdname: react-flow
description: React Flow (@xyflow/react) for workflow visualization with custom nodes and edges. Use when building graph visualizations, creating custom workflow nodes, implementing edge labels, or controlling viewport. Triggers on ReactFlow, @xyflow/react, Handle, NodeProps, EdgeProps, useReactFlow, fitView.
React Flow
React Flow (@xyflow/react) is a library for building node-based graphs, workflow editors, and interactive diagrams. It provides a highly customizable framework for creating visual programming interfaces, process flows, and network visualizations.
Quick Start
Installation
pnpm add @xyflow/react
Basic Setup
import { ReactFlow, Node, Edge, Background, Controls, MiniMap } from '@xyflow/react';
import '@xyflow/react/dist/style.css';
const initialNodes: Node[] = [
{
id: '1',
type: 'input',
data: { label: 'Input Node' },
position: { x: 250, y: 5 },
},
{
id: '2',
data: { label: 'Default Node' },
position: { x: 100, y: 100 },
},
{
id: '3',
type: 'output',
data: { label: 'Output Node' },
position: { x: 400, y: 100 },
},
];
const initialEdges: Edge[] = [
{ id: 'e1-2', source: '1', target: '2', animated: true },
{ id: 'e2-3', source: '2', target: '3' },
];
function Flow() {
return (
<div style={{ width: '100vw', height: '100vh' }}>
<ReactFlow nodes={initialNodes} edges={initialEdges}>
<Background />
<Controls />
<MiniMap />
</ReactFlow>
</div>
);
}
export default Flow;Core Concepts
Nodes
Nodes are the building blocks of the graph. Each node has:
- `id`: Unique identifier
- `type`: Node type (built-in or custom)
- `position`: { x, y } coordinates
- `data`: Custom data object
import { Node } from '@xyflow/react';
const node: Node = {
id: 'node-1',
type: 'default',
position: { x: 100, y: 100 },
data: { label: 'Node Label' },
style: { background: '#D6D5E6' },
className: 'custom-node',
};Built-in node types:
- `default`: Standard node
- `input`: No target handles
- `output`: No source handles
- `group`: Container for other nodes
Edges
Edges connect nodes. Each edge requires:
- `id`: Unique identifier
- `source`: Source node ID
- `target`: Target node ID
import { Edge } from '@xyflow/react';
const edge: Edge = {
id: 'e1-2',
source: '1',
target: '2',
type: 'smoothstep',
animated: true,
label: 'Edge Label',
style: { stroke: '#fff', strokeWidth: 2 },
};Built-in edge types:
- `default`: Bezier curve
- `straight`: Straight line
- `step`: Orthogonal with sharp corners
- `smoothstep`: Orthogonal with rounded corners
Handles
Handles are connection points on nodes. Use `Position` enum for placement:
import { Handle, Position } from '@xyflow/react';
<Handle type="target" position={Position.Top} />
<Handle type="source" position={Position.Bottom} />Available positions: `Position.Top`, `Position.Right`, `Position.Bottom`, `Position.Left`
State Management
Controlled Flow
Use state hooks for full control:
import { useNodesState, useEdgesState, addEdge, OnConnect } from '@xyflow/react';
import { useCallback } from 'react';
function ControlledFlow() {
const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
const onConnect: OnConnect = useCallback(
(connection) => setEdges((eds) => addEdge(connection, eds)),
[setEdges]
);
return (
<ReactFlow
nodes={nodes}
edges={edges}
onNodesChange={onNodesChange}
onEdgesChange={onEdgesChange}
onConnect={onConnect}
/>
);
}useReactFlow Hook
Access the React Flow instance for programmatic control:
import { useReactFlow } from '@xyflow/react';
function FlowControls() {
const {
getNodes,
getEdges,
setNodes,
setEdges,
addNodes,
addEdges,
deleteElements,
fitView,
zoomIn,
zoomOut,
getNode,
getEdge,
updateNode,
updateEdge,
} = useReactFlow();
return (
<button onClick={() => fitView()}>Fit View</button>
);
}Custom Nodes
Define custom nodes using `NodeProps<T>` with typed data:
import { NodeProps, Node, Handle, Position } from '@xyflow/react';
export type CustomNode = Node<{ label: string; status: 'active' | 'inactive' }, 'custom'>;
function CustomNodeComponent({ data, selected }: NodeProps<CustomNode>) {
return (
<div className={`px-4 py-2 ${selected ? 'ring-2' : ''}`}>
<Handle type="target" position={Position.Top} />
<div className="font-bold">{data.label}</div>
<Handle type="source" position={Position.Bottom} />
</div>
);
}Register with `nodeTypes`:
const nodeTypes: NodeTypes = { custom: CustomNodeComponent };
<ReactFlow nodeTypes={nodeTypes} />Key Patterns
- **Multiple Handles**: Use `id` prop and `style` for positioning
- **Dynamic Handles**: Call `useUpdateNodeInternals([nodeId])` after adding/removing handles
- **Interactive Elements**: Add `className="nodrag"` to prevent dragging on inputs/buttons
See [Custom Nodes Reference](./references/custom-nodes.md) for detailed patterns including styling, aviation map pins, and dynamic handles.
Custom Edges
Define custom edges using `EdgeProps<T>` and path utilities:
import { BaseEdge, EdgeProps, getBezierPath } from '@xyflow/react';
export type CustomEdge = Edge<{ status: 'normal' | 'error' }, 'custom'>;
function CustomEdgeComponent(props: EdgeProps<CustomEdge>) {
const [edgePath] = getBezierPath(props);
return (
<BaseEdge
id={props.id}
path={edgePath}
style={{ stroke: props.data?.status === 'error' ? '#ef4444' : '#64748b' }}
/>
);
}Path Utilities
- `getBezierPath()` - Smooth curves
- `getStraightPath()` - Straight line
Read more
name: react-flow description: React Flow (@xyflow/react) for workflow visualization with custom nodes and edges. Use when building graph visualizations, creating custom workflow nodes, implementing edge labels, or controlling viewport. Triggers on ReactFlow, @xyflow/react, Handle, NodeProps, EdgeProps, useReactFlow, fitView.
React Flow
React Flow (@xyflow/react) is a library for building node-based graphs, workflow editors, and interactive diagrams. It provides a highly customizable framework for creating visual programming interfaces, process flows, and network visualizations.
Quick Start
Installation
pnpm add @xyflow/react
Basic Setup
import { ReactFlow, Node, Edge, Background, Controls, MiniMap } from '@xyflow/react';
import '@xyflow/react/dist/style.css';
const initialNodes: Node[] = [
{
id: '1',
type: 'input',
data: { label: 'Input Node' },
position: { x: 250, y: 5 },
},
{
id: '2',
data: { label: 'Default Node' },
position: { x: 100, y: 100 },
},
{
id: '3',
type: 'output',
data: { label: 'Output Node' },
position: { x: 400, y: 100 },
},
];
const initialEdges: Edge[] = [
{ id: 'e1-2', source: '1', target: '2', animated: true },
{ id: 'e2-3', source: '2', target: '3' },
];
function Flow() {
return (
<div style={{ width: '100vw', height: '100vh' }}>
<ReactFlow nodes={initialNodes} edges={initialEdges}>
<Background />
<Controls />
<MiniMap />
</ReactFlow>
</div>
);
}
export default Flow;Core Concepts
Nodes
Nodes are the building blocks of the graph. Each node has:
- `id`: Unique identifier
- `type`: Node type (built-in or custom)
- `position`: { x, y } coordinates
- `data`: Custom data object
import { Node } from '@xyflow/react';
const node: Node = {
id: 'node-1',
type: 'default',
position: { x: 100, y: 100 },
data: { label: 'Node Label' },
style: { background: '#D6D5E6' },
className: 'custom-node',
};Built-in node types:
- `default`: Standard node
- `input`: No target handles
- `output`: No source handles
- `group`: Container for other nodes
Edges
Edges connect nodes. Each edge requires:
- `id`: Unique identifier
- `source`: Source node ID
- `target`: Target node ID
import { Edge } from '@xyflow/react';
const edge: Edge = {
id: 'e1-2',
source: '1',
target: '2',
type: 'smoothstep',
animated: true,
label: 'Edge Label',
style: { stroke: '#fff', strokeWidth: 2 },
};Built-in edge types:
- `default`: Bezier curve
- `straight`: Straight line
- `step`: Orthogonal with sharp corners
- `smoothstep`: Orthogonal with rounded corners
Handles
Handles are connection points on nodes. Use `Position` enum for placement:
import { Handle, Position } from '@xyflow/react';
<Handle type="target" position={Position.Top} />
<Handle type="source" position={Position.Bottom} />Available positions: `Position.Top`, `Position.Right`, `Position.Bottom`, `Position.Left`
State Management
Controlled Flow
Use state hooks for full control:
import { useNodesState, useEdgesState, addEdge, OnConnect } from '@xyflow/react';
import { useCallback } from 'react';
function ControlledFlow() {
const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
const onConnect: OnConnect = useCallback(
(connection) => setEdges((eds) => addEdge(connection, eds)),
[setEdges]
);
return (
<ReactFlow
nodes={nodes}
edges={edges}
onNodesChange={onNodesChange}
onEdgesChange={onEdgesChange}
onConnect={onConnect}
/>
);
}useReactFlow Hook
Access the React Flow instance for programmatic control:
import { useReactFlow } from '@xyflow/react';
function FlowControls() {
const {
getNodes,
getEdges,
setNodes,
setEdges,
addNodes,
addEdges,
deleteElements,
fitView,
zoomIn,
zoomOut,
getNode,
getEdge,
updateNode,
updateEdge,
} = useReactFlow();
return (
<button onClick={() => fitView()}>Fit View</button>
);
}Custom Nodes
Define custom nodes using `NodeProps<T>` with typed data:
import { NodeProps, Node, Handle, Position } from '@xyflow/react';
export type CustomNode = Node<{ label: string; status: 'active' | 'inactive' }, 'custom'>;
function CustomNodeComponent({ data, selected }: NodeProps<CustomNode>) {
return (
<div className={`px-4 py-2 ${selected ? 'ring-2' : ''}`}>
<Handle type="target" position={Position.Top} />
<div className="font-bold">{data.label}</div>
<Handle type="source" position={Position.Bottom} />
</div>
);
}Register with `nodeTypes`:
const nodeTypes: NodeTypes = { custom: CustomNodeComponent };
<ReactFlow nodeTypes={nodeTypes} />Key Patterns
- **Multiple Handles**: Use `id` prop and `style` for positioning
- **Dynamic Handles**: Call `useUpdateNodeInternals([nodeId])` after adding/removing handles
- **Interactive Elements**: Add `className="nodrag"` to prevent dragging on inputs/buttons
See [Custom Nodes Reference](./references/custom-nodes.md) for detailed patterns including styling, aviation map pins, and dynamic handles.
Custom Edges
Define custom edges using `EdgeProps<T>` and path utilities:
import { BaseEdge, EdgeProps, getBezierPath } from '@xyflow/react';
export type CustomEdge = Edge<{ status: 'normal' | 'error' }, 'custom'>;
function CustomEdgeComponent(props: EdgeProps<CustomEdge>) {
const [edgePath] = getBezierPath(props);
return (
<BaseEdge
id={props.id}
path={edgePath}
style={{ stroke: props.data?.status === 'error' ? '#ef4444' : '#64748b' }}
/>
);
}Path Utilities
- `getBezierPath()` - Smooth curves
- `getStraightPath()` - Straight line
Other skills on shep.
More skills from other plugins.
brainstorming
You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…
ask-matt
Ask which skill or flow fits your situation. A router over the skills in this repo.
Questions about react-flow.
- Which coding agents can use react-flow?
- react-flow installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.

