Handles

Beginner · 2 min read · Updated Nov 6, 2026

React Flow Handles: Creating Custom Node Connections

Handles are connection points that allow nodes to communicate with each other in React Flow. They define where edges enter and leave nodes, making them essential for building interactive workflow editors, flowcharts, and visual programming applications.

With the <Handle /> component, developers can create multiple connection points, customize their positions, apply unique styles, and dynamically manage node connections.

1. Creating Handles in Custom Nodes

React Flow provides the <Handle /> component to add connection points to custom nodes. Use source handles for outgoing connections and target handles for incoming connections.

Code Example

import { Handle, Position } from '@xyflow/react';

export function CustomNode({ data }) {
  return (
    <div className="custom-node">
      <Handle
        type="target"
        position={Position.Top}
      />

      <strong>{data.label}</strong>

      <Handle
        type="source"
        position={Position.Bottom}
      />
    </div>
  );
}

Key Features:

  • Create incoming and outgoing connections.
  • Position handles on different sides of nodes.
  • Customize handle appearance and behavior.
  • Support reusable custom node components.

2. Using Multiple Handles

React Flow supports multiple source and target handles within a single node. Assign a unique id to each handle so edges can connect to specific connection points.

Code Example

import { Handle, Position } from '@xyflow/react';

export function MultiHandleNode() {
  return (
    <div className="custom-node">
      <Handle
        type="target"
        position={Position.Left}
        id="input-1"
      />

      <strong>Multi Output Node</strong>

      <Handle
        type="source"
        position={Position.Right}
        id="output-1"
        style={{ top: '30%' }}
      />

      <Handle
        type="source"
        position={Position.Right}
        id="output-2"
        style={{ top: '70%' }}
      />
    </div>
  );
}

To connect an edge to a specific handle, use sourceHandle and targetHandle.

const edges = [
  {
    id: 'e1',
    source: '1',
    sourceHandle: 'output-1',
    target: '2',
  },
  {
    id: 'e2',
    source: '1',
    sourceHandle: 'output-2',
    target: '3',
  },
];

Multiple handles are especially useful for AI workflow builders, automation systems, and conditional branching diagrams.

3. Creating Custom Handles

You can customize the appearance of handles by wrapping icons or other React components inside the <Handle /> component. This allows you to create visually distinctive connection points.

Code Example

import { Handle, Position } from '@xyflow/react';

export function CustomIconHandle() {
  return (
    <div className="custom-node">
      <Handle
        type="source"
        position={Position.Right}
        style={{
          width: 24,
          height: 24,
          background: 'none',
          border: 'none',
        }}
      >
        <span className="handle-icon">➜</span>
      </Handle>

      <strong>Custom Handle</strong>
    </div>
  );
}
.handle-icon {
  position: absolute;
  left: 0;
  top: 0;
  font-size: 20px;
  pointer-events: none;
}

Custom handles help create modern node interfaces with icons, buttons, and branded connection points.

4. Using Typeless Handles

React Flow supports flexible connections using typeless handles. By setting connectionMode to ConnectionMode.Loose, a handle can be used for both incoming and outgoing connections without specifying its type.

Code Example

import {
  ReactFlow,
  Handle,
  Position,
  ConnectionMode,
} from '@xyflow/react';

function FlexibleNode() {
  return (
    <div className="custom-node">
      <Handle position={Position.Left} />
      <strong>Flexible Node</strong>
      <Handle position={Position.Right} />
    </div>
  );
}

<ReactFlow
  nodes={nodes}
  edges={edges}
  connectionMode={ConnectionMode.Loose}
/>;

This approach is useful for flexible diagram editors where connections can start or end at any handle.

5. Dynamically Updating Handles

Sometimes the number or position of handles changes based on node data or user interactions. React Flow provides the useUpdateNodeInternals() Hook to recalculate handle positions and node dimensions.

Code Example

import { useEffect } from 'react';
import {
  Handle,
  Position,
  useUpdateNodeInternals,
  useNodeId,
} from '@xyflow/react';

export function DynamicNode({ data }) {
  const nodeId = useNodeId();
  const updateNodeInternals = useUpdateNodeInternals();

  useEffect(() => {
    updateNodeInternals(nodeId);
  }, [data.outputs, nodeId, updateNodeInternals]);

  return (
    <div className="custom-node">
      <strong>Dynamic Node</strong>

      {data.outputs.map((output, index) => (
        <Handle
          key={output.id}
          id={output.id}
          type="source"
          position={Position.Right}
          style={{
            top: `${((index + 1) /
              (data.outputs.length + 1)) * 100}%`,
          }}
        />
      ))}
    </div>
  );
}

This technique is useful for dynamic workflow builders where users can add, remove, or reposition connection points.

6. Customizing Handle Styles

Handles can be styled using inline CSS or external stylesheets. You can customize their size, color, border, shape, and position to match your application's design.

Code Example

<Handle
  type="source"
  position={Position.Right}
  style={{
    width: 12,
    height: 12,
    background: '#6366f1',
    border: '2px solid white',
    borderRadius: '50%',
  }}
/>

You can also use CSS classes to style handles consistently across your application.

.react-flow__handle {
  width: 12px;
  height: 12px;
  background: #6366f1;
  border: 2px solid white;
}

.react-flow__handle:hover {
  background: #4f46e5;
  transform: scale(1.2);
}

7. Styling Handles During Connections

React Flow automatically adds CSS classes to handles during connection interactions. The connecting class indicates an active connection attempt, while valid indicates a valid connection target.

Code Example

.react-flow__handle.connecting {
  background: #f59e0b;
}

.react-flow__handle.valid {
  background: #22c55e;
  box-shadow: 0 0 8px rgba(34, 197, 94, 0.5);
}

These visual states provide useful feedback and make connecting nodes more intuitive.

8. Hiding Handles in React Flow

You can hide handles without removing their dimensions from the DOM. Use visibility: hidden or opacity: 0 instead of display: none, because React Flow needs handle dimensions to calculate connections correctly.

Code Example

<Handle
  type="source"
  position={Position.Right}
  style={{
    visibility: 'hidden',
  }}
/>

Alternatively, use opacity to make a handle invisible while preserving its layout and connection functionality.

.hidden-handle {
  opacity: 0;
}
Custome HandlesOpen in New Tab