
React Flow Advanced
Ship complex node-based editors and diagrams in React with sub-flows, custom edges, layout engines, and undo/redo without missing React Flow footguns.
Install
npx skills add https://github.com/existential-birds/beagle --skill react-flow-advancedWhat is this skill?
- Six sequenced shipping gates for sub-flows, connection lines, DnD, undo/redo, dagre layout, and connect-on-drop
- Sub-flow checks: parentId, registered parent type, and relative child positioning after drag inside/outside groups
- External drop pipeline: preventDefault on dragOver plus screenToFlowPosition (not raw client coords)
- Undo/redo consistency: add → undo → redo must match visible graph and canUndo/canRedo state
- Programmatic layout: setNodes after dagre rankdir plus fitView on requestAnimationFrame to avoid stale viewport
Adoption & trust: 479 installs on skills.sh; 62 GitHub stars; 3/3 security scanners passed (skills.sh audits); trending (+100% hot-view momentum).
Recommended Skills
Journey fit
React Flow implementation work belongs on the Build shelf because it produces interactive graph UI code, not launch or ops work. Frontend is the canonical subphase: nodeTypes, pane drag-and-drop, connection lines, and dagre layout all live in client graph components.
Common Questions / FAQ
Is React Flow Advanced safe to install?
skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.
SKILL.md
READMESKILL.md - React Flow Advanced
# Advanced React Flow Patterns ## Gates (check before shipping) Use these as **sequenced** checks—not “I think it works.” 1. **Sub-flows / groups:** **Pass:** Every `parentId` matches an existing node `id`; the parent `type` is registered in `nodeTypes`; child positions are relative to the parent as intended (spot-check one drag inside/outside the group). 2. **Custom connection line:** **Pass:** With a valid/invalid drag, stroke or `connectionStatus` visibly differs; path renders without console errors from `getSmoothStepPath` (invalid coords). 3. **External drag-and-drop:** **Pass:** `onDragOver` always `preventDefault()`; drop position uses `screenToFlowPosition` (not raw `clientX`/`clientY` as flow coords); new node appears under the cursor on the pane. 4. **Undo/redo:** **Pass:** One undo returns to the prior `{ nodes, edges }`; redo restores; rapid changes do not leave `canUndo`/`canRedo` inconsistent with visible graph (exercise add → undo → redo once). 5. **Programmatic layout (dagre):** **Pass:** After `setNodes`, node positions match intended `rankdir`; `fitView` runs after layout (e.g. `requestAnimationFrame`) so the viewport is not stale. 6. **Connect on drop (new node):** **Pass:** Dropping on empty pane creates a node **and** an edge from the source handle; dropping on a valid target does not duplicate nodes (only the invalid-drop path adds a node). 7. **Selectors / store:** **Pass:** Components that `useStore` with objects use `shallow` (or equivalent) so unrelated store updates do not re-render every frame. ## Sub-Flows (Nested Nodes) ```tsx const nodes = [ // Parent (group) node { id: 'group-1', type: 'group', position: { x: 0, y: 0 }, style: { width: 400, height: 300, padding: 10 }, data: { label: 'Group' }, }, // Child nodes { id: 'child-1', parentId: 'group-1', // Reference parent extent: 'parent', // Constrain to parent bounds expandParent: true, // Auto-expand parent if dragged to edge position: { x: 20, y: 50 }, // Relative to parent data: { label: 'Child 1' }, }, { id: 'child-2', parentId: 'group-1', extent: 'parent', position: { x: 200, y: 50 }, data: { label: 'Child 2' }, }, ]; ``` ### Group Node Component ```tsx function GroupNode({ data, id }: NodeProps) { return ( <div className="group-node"> <div className="group-header">{data.label}</div> {/* Children are rendered automatically by React Flow */} </div> ); } ``` ## Custom Connection Line ```tsx import { ConnectionLineComponentProps, getSmoothStepPath } from '@xyflow/react'; function CustomConnectionLine({ fromX, fromY, fromPosition, toX, toY, toPosition, connectionStatus, }: ConnectionLineComponentProps) { const [path] = getSmoothStepPath({ sourceX: fromX, sourceY: fromY, sourcePosition: fromPosition, targetX: toX, targetY: toY, targetPosition: toPosition, }); return ( <g> <path d={path} fill="none" stroke={connectionStatus === 'valid' ? '#22c55e' : '#ef4444'} strokeWidth={2} strokeDasharray="5 5" /> </g> ); } <ReactFlow connectionLineComponent={CustomConnectionLine} /> ``` ## Drag and Drop from External Source ```tsx import { useCallback, useRef, useState } from 'react'; import { useReactFlow } from '@xyflow/react'; function DnDFlow() { const reactFlowWrapper = useRef(null); const { screenToFlowPosition, addNodes } = useReactFlow(); const [reactFlowInstance, setReactFlowInstance] = useState(null); const onDragOver = useCallback((event: DragEvent) => { event.preventDefault(); event.dataTransfer.dropEffect = 'move'; }, []); const onDrop = useCallback((eve