---
name: react-flow-usage
description: Comprehensive React Flow (@xyflow/react) patterns and best practices for building node-based UIs, workflow editors, and interactive diagrams. Use when working with React Flow for (1) building flow editors or node-based interfaces, (2) creating custom nodes and edges, (3) implementing drag-and-drop workflows, (4) optimizing performance for large graphs, (5) managing flow state and interactions, (6) implementing auto-layout or positioning, or (7) TypeScript integration with React Flow.
license: MIT
metadata:
author: xyflow Team
version: "1.0.0"
package: "@xyflow/react"
---
# React Flow Usage Guide
Comprehensive patterns and best practices for building production-ready node-based UIs with React Flow (@xyflow/react v12+).
## When to Use This Skill
Apply these guidelines when:
- Building workflow editors, flow diagrams, or node-based interfaces
- Creating custom node or edge components
- Implementing drag-and-drop functionality for visual programming
- Optimizing performance for graphs with 100+ nodes
- Managing flow state, save/restore, or undo/redo
- Implementing auto-layout with dagre, elkjs, or custom algorithms
- Integrating React Flow with TypeScript
## Rule Categories by Priority
| Priority | Category | Focus | Prefix |
|----------|----------|-------|--------|
| 1 | Setup & Configuration | CRITICAL | `setup-` |
| 2 | Performance Optimization | CRITICAL | `perf-` |
| 3 | Node Patterns | HIGH | `node-` |
| 4 | Edge Patterns | HIGH | `edge-` |
| 5 | State Management | HIGH | `state-` |
| 6 | Hooks Usage | MEDIUM | `hook-` |
| 7 | Layout & Positioning | MEDIUM | `layout-` |
| 8 | Interaction Patterns | MEDIUM | `interaction-` |
| 9 | TypeScript Integration | MEDIUM | `typescript-` |
## Quick Start Pattern
```tsx
import { useCallback } from 'react';
import {
ReactFlow,
Background,
Controls,
MiniMap,
useNodesState,
useEdgesState,
addEdge
} from '@xyflow/react';
import '@xyflow/react/dist/style.css';
const initialNodes = [
{ id: '1', position: { x: 0, y: 0 }, data: { label: 'Node 1' } },
];
const initialEdges = [
{ id: 'e1-2', source: '1', target: '2' },
];
// Define outside component or use useMemo
const nodeTypes = { custom: CustomNode };
const edgeTypes = { custom: CustomEdge };
function Flow() {
const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
const onConnect = useCallback(
(params) => setEdges((eds) => addEdge(params, eds)),
[setEdges]
);
return (
);
}
```
## Core Concepts Overview
### Node Structure
- `id`: Unique identifier (required)
- `position`: `{ x: number, y: number }` (required)
- `data`: Custom data object (required)
- `type`: Built-in or custom type
- `style`, `className`: Styling
- `draggable`, `selectable`, `connectable`: Interaction controls
- `parentId`: For nested/grouped nodes
- `extent`: Movement boundaries
### Edge Structure
- `id`: Unique identifier (required)
- `source`: Source node id (required)
- `target`: Target node id (required)
- `sourceHandle`, `targetHandle`: Specific handle ids
- `type`: 'default' | 'straight' | 'step' | 'smoothstep' | custom
- `animated`: Boolean for animation
- `label`: String or React component
- `markerStart`, `markerEnd`: Arrow markers
### Handle Usage
- Position: `Position.Top | Bottom | Left | Right`
- Type: `'source' | 'target'`
- Multiple handles per node supported
- Use unique `id` prop for multiple handles
## Essential Patterns
### Custom Nodes
```tsx
import { memo } from 'react';
import { Handle, Position, NodeProps } from '@xyflow/react';
const CustomNode = memo(({ data, selected }: NodeProps) => {
return (
);
});
// IMPORTANT: Define outside component
const nodeTypes = { custom: CustomNode };
```
### Custom Edges
```tsx
import { BaseEdge, EdgeLabelRenderer, getBezierPath, EdgeProps } from '@xyflow/react';
function CustomEdge({ id, sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition }: EdgeProps) {
const [edgePath, labelX, labelY] = getBezierPath({
sourceX, sourceY, sourcePosition, targetX, targetY, targetPosition,
});
return (
<>
Custom Label
>
);
}
```
### Performance Optimization
```tsx
// 1. Memoize node/edge types (define outside component)
const nodeTypes = useMemo(() => ({ custom: CustomNode }), []);
// 2. Memoize callbacks
const onConnect = useCallback((params) =>
setEdges((eds) => addEdge(params, eds)), [setEdges]
);
// 3. Use simple edge types for large graphs
const edgeType = nodes.length > 100 ? 'straight' : 'smoothstep';
// 4. Avoid unnecessary re-renders in custom components
const CustomNode = memo(({ data }) => {data.label}
);
```
## Key Hooks
- `useReactFlow()` - Access flow instance methods (getNodes, setNodes, fitView, etc.)
- `useNodesState()` / `useEdgesState()` - Managed state with change handlers
- `useNodes()` / `useEdges()` - Reactive access to current nodes/edges
- `useNodesData(id)` - Get specific node data (more performant than useNodes)
- `useHandleConnections()` - Get connections for a handle
- `useConnection()` - Track connection in progress
- `useStore()` - Direct store access (use sparingly)
## Common Patterns
### Drag and Drop
```tsx
const onDrop = useCallback((event) => {
event.preventDefault();
const type = event.dataTransfer.getData('application/reactflow');
const position = screenToFlowPosition({
x: event.clientX,
y: event.clientY,
});
setNodes((nds) => nds.concat({
id: getId(),
type,
position,
data: { label: `${type} node` },
}));
}, [screenToFlowPosition]);
```
### Save and Restore
```tsx
const { toObject } = useReactFlow();
// Save
const flow = toObject();
localStorage.setItem('flow', JSON.stringify(flow));
// Restore
const flow = JSON.parse(localStorage.getItem('flow'));
setNodes(flow.nodes || []);
setEdges(flow.edges || []);
setViewport(flow.viewport);
```
### Connection Validation
```tsx
const isValidConnection = useCallback((connection) => {
// Prevent self-connections
if (connection.source === connection.target) return false;
// Custom validation logic
return true;
}, []);
```
## Detailed Rules
For comprehensive patterns and best practices, see individual rule files in the `rules/` directory organized by category:
```
rules/setup-*.md - Critical setup patterns
rules/perf-*.md - Performance optimization
rules/node-*.md - Node customization patterns
rules/edge-*.md - Edge handling patterns
rules/state-*.md - State management
rules/hook-*.md - Hooks usage
rules/layout-*.md - Layout and positioning
rules/interaction-*.md - User interactions
rules/typescript-*.md - TypeScript integration
```
## Full Compiled Documentation
For the complete guide with all rules and examples expanded: see `AGENTS.md`
## Scraped Documentation Reference
Comprehensive scraped documentation from reactflow.dev is available in `scraped/`:
- **Learn**: `scraped/learn-concepts/`, `scraped/learn-customization/`, `scraped/learn-advanced/`
- **API**: `scraped/api-hooks/`, `scraped/api-types/`, `scraped/api-utils/`, `scraped/api-components/`
- **Examples**: `scraped/examples-nodes/`, `scraped/examples-edges/`, `scraped/examples-interaction/`, `scraped/examples-layout/`
- **UI Components**: `scraped/ui-components/`
- **Tutorials**: `scraped/learn-tutorials/`
- **Troubleshooting**: `scraped/learn-troubleshooting/`
## Common Issues
1. **Couldn't create edge** - Add `onConnect` handler
2. **Nodes not draggable** - Check `nodesDraggable` prop
3. **CSS not loading** - Import `@xyflow/react/dist/style.css`
4. **useReactFlow outside provider** - Wrap with ``
5. **Performance issues** - See Performance category rules
6. **TypeScript errors** - Use proper generic types `useReactFlow()`
## References
- Official Documentation: https://reactflow.dev
- GitHub: https://github.com/xyflow/xyflow
- Package: `@xyflow/react` (npm)
- Examples: https://reactflow.dev/examples
- API Reference: https://reactflow.dev/api-reference