| name | reactflow-expert |
| license | Apache-2.0 |
| description | Builds DAG visualizations using ReactFlow v12 with custom nodes, ELKjs auto-layout, Zustand state management, and live state updates via WebSocket. Use when implementing workflow visualization dashboards, creating custom agent node components, integrating ELK layout algorithms, or wiring execution state into React components. Activate on "ReactFlow", "workflow visualization", "DAG visualization", "ELKjs", "custom nodes", "node-based editor", "graph visualization". NOT for writing Mermaid diagrams (use mermaid-graph-writer), general React development, or static diagram rendering. |
| allowed-tools | Read,Write,Edit,Bash,Grep,Glob |
| metadata | {"tags":["reactflow","workflow-visualization","dag-visualization"],"pairs-with":[{"skill":"websocket-streaming","reason":"Live DAG state updates flow through WebSocket connections to ReactFlow visualizations"},{"skill":"human-gate-designer","reason":"Human approval gates are rendered as interactive ReactFlow custom nodes"},{"skill":"task-decomposer","reason":"Decomposed task DAGs are visualized as ReactFlow node graphs with ELKjs layout"}]} |
| category | Frontend & UI |
| tags | ["reactflow","node-editor","graph-visualization","interactive","react"] |
ReactFlow Expert
Builds DAG visualizations using ReactFlow v12 with custom agent nodes, ELKjs auto-layout, Zustand state management, and live execution state updates.
Decision Points
State Management Strategy Selection
Graph Size <= 50 nodes?
├─ YES: Use useNodesState/useEdgesState hooks (simpler)
└─ NO: Use Zustand store
├─ Real-time updates required? → Include WebSocket integration
├─ Multi-component access? → Global Zustand store
└─ Complex interactions? → Add action methods (updateNodeData, bulkUpdate)
Layout Algorithm by DAG Shape
Node Count:
├─ < 20 nodes: Use 'layered' algorithm with direction='DOWN'
├─ 20-100 nodes: Use 'layered' with direction='RIGHT'
├─ > 100 nodes: Use 'stress' algorithm (better for large graphs)
└─ Highly connected (edges > 2x nodes): Use 'force' algorithm
Aspect Ratio:
├─ Wide dashboard: direction='RIGHT'
├─ Tall sidebar: direction='DOWN'
└─ Square viewport: Let ELK choose optimal direction
Custom Node Complexity Decision
Node Data Fields:
├─ Only status + name: Use built-in node types with custom styling
├─ 3-5 fields: Custom node with simple layout
├─ 6+ fields or nested data: Custom node with collapsible sections
└─ Interactive elements: Custom node + "nodrag" className on controls
Sync Strategy for Live Updates
Update Frequency:
├─ Real-time (< 1s): WebSocket with optimistic updates
├─ Frequent (1-10s): WebSocket with batching
├─ Periodic (> 10s): HTTP polling
└─ User-triggered: Manual refresh button
Data Size:
├─ Full DAG < 1MB: Send complete state
├─ Large DAG: Send delta updates (node ID + changed fields)
└─ Huge DAG: Implement viewport-based loading
Failure Modes
Infinite Re-render Loop
Symptom: Browser tab freezes, React DevTools shows constant re-renders
Detection: If nodeTypes object is defined inside component body
Fix: Move nodeTypes outside component or wrap in useMemo
Stale State Updates
Symptom: Node status changes don't appear visually, but store updates correctly
Detection: If mutating existing node objects instead of creating new ones
Fix: Always spread objects: { ...node, data: { ...node.data, newField } }
Layout Thrashing
Symptom: Nodes jump around constantly, poor performance with live updates
Detection: If ELK layout runs on every state change instead of topology changes
: Only trigger layout when nodes/edges are added/removed, not data updates