Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
existential-birds avatar

React Flow Implementation

  • 316 installs
  • 74 repo stars
  • Updated July 21, 2026
  • existential-birds/beagle

react-flow-implementation is a frontend implementation skill that builds node-based editors with @xyflow/react for developers who need correct nodes, edges, handles, styles, and state wiring in React.

About

react-flow-implementation is a frontend implementation skill for building node-based UIs with @xyflow/react (React Flow). react-flow-implementation focuses on the wiring that commonly breaks in flow editors: nodes and edges state, add-edge callbacks, custom node components with handles, and including the required React Flow stylesheet import. react-flow-implementation is useful when a developer is implementing a visual editor, diagram builder, or workflow canvas and needs predictable viewport behavior and consistent state updates. Developers reach for react-flow-implementation when they want a working baseline quickly and then iterate into custom nodes, interactions, and persisted graph state without missing key integration steps.

  • Quick-start pattern with useNodesState, useEdgesState, addEdge, and mandatory @xyflow/react CSS import
  • Ordered implementation gates: styles, container sizing, handles, custom nodes, and state before shipping polish
  • Covers nodes, edges, handles, custom components, state management, and viewport control
  • Explicit trigger: flow charts, diagrams, visual editors, and node-based applications

React Flow Implementation by the numbers

  • 316 all-time installs (skills.sh)
  • Ranked #738 of 2,245 Frontend Development skills by installs in the Skillselion catalog
  • Security screen: MEDIUM risk (skills.sh audit)
  • Data as of Jul 28, 2026 (Skillselion catalog sync)
npx skills add https://github.com/existential-birds/beagle --skill react-flow-implementation

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs316
repo stars74
Security audit3 / 3 scanners passed
Last updatedJuly 21, 2026
Repositoryexistential-birds/beagle

How do I implement React Flow with custom nodes?

Implement node-based flow charts, diagrams, and visual editors with @xyflow/react without missing styles, handles, or state wiring.

Who is it for?

Frontend developers building diagrams, workflow canvases, or visual editors in React.

Skip if: Backend-only projects without a React UI surface.

When should I use this skill?

Invoke when a developer is building a node graph UI with @xyflow/react and needs correct state, handles, or styling.

What you get

A working React Flow screen with nodes, edges, state hooks, edge-creation handler, and required stylesheet import.

  • react flow screen
  • custom node scaffolding
  • node/edge state wiring

By the numbers

  • Example setup initializes 2 nodes in `initialNodes`.

Files

SKILL.mdMarkdownGitHub ↗

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.”

1. Styles on the pagePass 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. 2. `useReactFlow` boundaryPass if every caller of useReactFlow() is a descendant of <ReactFlowProvider> that wraps the same tree as <ReactFlow /> (or you have intentionally split stores and can name both roots). 3. Stable `nodeTypes` / `edgeTypes`Pass if those maps are module-scope constants or useMemo with stable deps—not a new { ... } literal each render in the component that renders <ReactFlow />. 4. Handles match edgesPass if for nodes with multiple Handle ids, every edge that must land on a specific handle sets sourceHandle / targetHandle accordingly (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

ClassEffect
nodragPrevent dragging when clicking element
nowheelPrevent zoom on wheel events
nopanPrevent panning from element
nokeyPrevent keyboard events (use on inputs)

Additional Components

See ADDITIONAL_COMPONENTS.md for MiniMap, Controls, Background, NodeToolbar, NodeResizer.

Related skills

How it compares

Pick this when you need a working @xyflow/react implementation with correct state hooks and styles, not just a diagram mock.

FAQ

Why is my React Flow canvas unstyled?

react-flow-implementation includes the required stylesheet import for @xyflow/react. react-flow-implementation uses `import '@xyflow/react/dist/style.css';` to ensure nodes, edges, and handles render with the library’s base styles.

How do I manage nodes and edges state cleanly?

react-flow-implementation uses React Flow’s state hooks to keep updates predictable. react-flow-implementation relies on `useNodesState` and `useEdgesState` so drag, connect, and custom update handlers can mutate graph state without manual reducers.

Is React Flow Implementation safe to install?

skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.

Frontend Developmentfrontendintegrations

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.