react-flow-implementation
Implements React Flow node-based UIs correctly using @xyflow/react. Use when building flow charts, diagrams, visual editors, or node-based applications with React. Covers nodes, edges, handles, custom components, state management, and viewport control.
How do I install this agent skill?
npx skills add https://github.com/existential-birds/beagle --skill react-flow-implementationIs this agent skill safe to install?
- Gen Agent Trust Hubpass
This skill provides implementation patterns, code snippets, and best practices for building node-based user interfaces with the @xyflow/react library. No security issues were detected.
- Socketpass
No alerts
- Snykpass
Risk: LOW · No issues
- Runlayerwarn
3/3 files flagged
- ZeroLeakspass
Score: 93/100 · 2 sections analyzed
What does this agent skill do?
React Flow Implementation
Quick Start
import { useCallback } from 'react';
import { ReactFlow, 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' } },
{ id: '2', position: { x: 200, y: 100 }, data: { label: 'Node 2' } },
];
const initialEdges = [{ id: 'e1-2', source: '1', target: '2' }];
export default function Flow() {
const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
const onConnect = useCallback(
(connection) => setEdges((eds) => addEdge(connection, eds)),
[setEdges]
);
return (
<div style={{ width: '100%', height: '100vh' }}>
<ReactFlow
nodes={nodes}
edges={edges}
onNodesChange={onNodesChange}
onEdgesChange={onEdgesChange}
onConnect={onConnect}
fitView
/>
</div>
);
}
Implementation gates
Run these in order; do not skip ahead on “looks fine.”
- Styles on the page — Pass if the bundle that renders
<ReactFlow />imports@xyflow/react/dist/style.css(or equivalent CSS pipeline) so nodes/edges are visible and hit-targets match visuals. useReactFlowboundary — Pass if every caller ofuseReactFlow()is a descendant of<ReactFlowProvider>that wraps the same tree as<ReactFlow />(or you have intentionally split stores and can name both roots).- Stable
nodeTypes/edgeTypes— Pass if those maps are module-scope constants oruseMemowith stable deps—not a new{ ... }literal each render in the component that renders<ReactFlow />. - Handles match edges — Pass if for nodes with multiple
Handleids, every edge that must land on a specific handle setssourceHandle/targetHandleaccordingly (or you accept default handle resolution deliberately).
See ADDITIONAL_COMPONENTS.md for MiniMap, Controls, Background, NodeToolbar, and NodeResizer patterns.
Core Patterns
TypeScript Types
import type { Node, Edge, NodeProps, BuiltInNode } from '@xyflow/react';
// Define custom node type with data shape
type CustomNode = Node<{ value: number; label: string }, 'custom'>;
// Combine with built-in nodes
type MyNode = CustomNode | BuiltInNode;
type MyEdge = Edge<{ weight?: number }>;
// Use throughout app
const [nodes, setNodes] = useNodesState<MyNode>(initialNodes);
Custom Nodes
import { memo } from 'react';
import { Handle, Position, type NodeProps } from '@xyflow/react';
// Define node type
type CounterNode = Node<{ count: number }, 'counter'>;
// Always wrap in memo for performance
const CounterNode = memo(function CounterNode({ data, isConnectable }: NodeProps<CounterNode>) {
return (
<>
<Handle type="target" position={Position.Top} isConnectable={isConnectable} />
<div className="counter-node">
Count: {data.count}
{/* nodrag prevents dragging when interacting with button */}
<button className="nodrag" onClick={() => console.log('clicked')}>
Increment
</button>
</div>
<Handle type="source" position={Position.Bottom} isConnectable={isConnectable} />
</>
);
});
// Register in nodeTypes (define OUTSIDE component to avoid re-renders)
const nodeTypes = { counter: CounterNode };
// Use in ReactFlow
<ReactFlow nodeTypes={nodeTypes} ... />
Multiple Handles
// Use handle IDs when a node has multiple handles of same type
<Handle type="source" position={Position.Right} id="a" />
<Handle type="source" position={Position.Right} id="b" style={{ top: 20 }} />
// Connect with specific handles
const edge = {
id: 'e1-2',
source: '1',
sourceHandle: 'a',
target: '2',
targetHandle: null
};
Custom Edges
import { BaseEdge, EdgeProps, getSmoothStepPath } from '@xyflow/react';
function CustomEdge({ id, sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition, data }: EdgeProps) {
const [edgePath, labelX, labelY] = getSmoothStepPath({
sourceX, sourceY, sourcePosition,
targetX, targetY, targetPosition,
});
return (
<>
<BaseEdge id={id} path={edgePath} />
<text x={labelX} y={labelY} className="edge-label">{data?.label}</text>
</>
);
}
const edgeTypes = { custom: CustomEdge };
State Management
Controlled (Recommended for Production)
// External state with change handlers
const [nodes, setNodes] = useState<Node[]>(initialNodes);
const [edges, setEdges] = useState<Edge[]>(initialEdges);
const onNodesChange = useCallback(
(changes) => setNodes((nds) => applyNodeChanges(changes, nds)),
[]
);
const onEdgesChange = useCallback(
(changes) => setEdges((eds) => applyEdgeChanges(changes, eds)),
[]
);
<ReactFlow
nodes={nodes}
edges={edges}
onNodesChange={onNodesChange}
onEdgesChange={onEdgesChange}
/>
Using useReactFlow
import { useReactFlow, ReactFlowProvider } from '@xyflow/react';
function FlowControls() {
const {
getNodes, setNodes, addNodes, updateNodeData,
getEdges, setEdges, addEdges,
fitView, zoomIn, zoomOut, setViewport,
deleteElements, toObject,
} = useReactFlow();
const addNode = () => {
addNodes({ id: `${Date.now()}`, position: { x: 100, y: 100 }, data: { label: 'New' } });
};
return <button onClick={addNode}>Add Node</button>;
}
// Must wrap in provider when using useReactFlow
function App() {
return (
<ReactFlowProvider>
<Flow />
<FlowControls />
</ReactFlowProvider>
);
}
Updating Node Data
const { updateNodeData } = useReactFlow();
// Merge with existing data
updateNodeData(nodeId, { label: 'Updated' });
// Replace data entirely
updateNodeData(nodeId, { newField: 'value' }, { replace: true });
Viewport & Fit View
// Fit on initial render
<ReactFlow fitView fitViewOptions={{ padding: 0.2, maxZoom: 1 }} />
// Programmatic control
const { fitView, setViewport, getViewport, zoomTo } = useReactFlow();
// Fit to specific nodes
fitView({ nodes: [{ id: '1' }, { id: '2' }], duration: 500 });
// Set exact viewport
setViewport({ x: 100, y: 100, zoom: 1.5 }, { duration: 300 });
Connection Validation
const isValidConnection = useCallback((connection: Connection) => {
// Prevent self-connections
if (connection.source === connection.target) return false;
// Custom validation logic
const sourceNode = getNode(connection.source);
const targetNode = getNode(connection.target);
return sourceNode?.type !== targetNode?.type;
}, []);
<ReactFlow isValidConnection={isValidConnection} />
Common Props Reference
<ReactFlow
// Core data
nodes={nodes}
edges={edges}
onNodesChange={onNodesChange}
onEdgesChange={onEdgesChange}
// Custom types (define OUTSIDE component)
nodeTypes={nodeTypes}
edgeTypes={edgeTypes}
// Connections
onConnect={onConnect}
connectionMode={ConnectionMode.Loose} // Allow target-to-target
isValidConnection={isValidConnection}
// Viewport
fitView
minZoom={0.1}
maxZoom={4}
defaultViewport={{ x: 0, y: 0, zoom: 1 }}
// Interaction
nodesDraggable={true}
nodesConnectable={true}
elementsSelectable={true}
panOnDrag={true}
zoomOnScroll={true}
// Additional components
<MiniMap />
<Controls />
<Background variant={BackgroundVariant.Dots} />
</ReactFlow>
CSS Classes for Interaction
| Class | Effect |
|---|---|
nodrag | Prevent dragging when clicking element |
nowheel | Prevent zoom on wheel events |
nopan | Prevent panning from element |
nokey | Prevent keyboard events (use on inputs) |
Additional Components
See ADDITIONAL_COMPONENTS.md for MiniMap, Controls, Background, NodeToolbar, NodeResizer.
How can the creator link this skill?
Add the canonical catalog link to the repository README so users can inspect current installs and available audits. The publishing guide covers the complete discovery path.
<a href="https://skillzs.dev/skills/existential-birds/beagle/react-flow-implementation">View react-flow-implementation on skillZs</a>