Use when creating custom React Flow nodes, edges, and handles. Covers custom node components, resizable nodes, toolbars, and advanced customization.
View on GitHubTheBushidoCollective/han
reactflow
February 5, 2026
Select agents to install to:
npx add-skill https://github.com/TheBushidoCollective/han/blob/main/frameworks/reactflow/skills/reactflow-custom-nodes/SKILL.md -a claude-code --skill reactflow-custom-nodesInstallation paths:
.claude/skills/reactflow-custom-nodes/# React Flow Custom Nodes and Edges
Create fully customized nodes and edges with React Flow. Build complex
node-based editors with custom styling, behaviors, and interactions.
## Custom Node Component
```tsx
import { memo } from 'react';
import { Handle, Position, type NodeProps, type Node } from '@xyflow/react';
// Define custom node data type
type TextUpdaterNodeData = {
label: string;
onChange: (value: string) => void;
};
type TextUpdaterNode = Node<TextUpdaterNodeData>;
function TextUpdaterNode({ data, isConnectable }: NodeProps<TextUpdaterNode>) {
const onChange = (evt: React.ChangeEvent<HTMLInputElement>) => {
data.onChange(evt.target.value);
};
return (
<div className="text-updater-node">
<Handle
type="target"
position={Position.Top}
isConnectable={isConnectable}
/>
<div>
<label htmlFor="text">Text:</label>
<input
id="text"
name="text"
onChange={onChange}
className="nodrag"
defaultValue={data.label}
/>
</div>
<Handle
type="source"
position={Position.Bottom}
id="a"
isConnectable={isConnectable}
/>
</div>
);
}
// Memoize for performance
export default memo(TextUpdaterNode);
```
## Registering Custom Nodes
```tsx
import { ReactFlow } from '@xyflow/react';
import TextUpdaterNode from './TextUpdaterNode';
import ColorPickerNode from './ColorPickerNode';
// Define node types outside component to prevent re-renders
const nodeTypes = {
textUpdater: TextUpdaterNode,
colorPicker: ColorPickerNode,
};
function Flow() {
const [nodes, setNodes, onNodesChange] = useNodesState([
{
id: '1',
type: 'textUpdater',
position: { x: 0, y: 0 },
data: {
label: 'Hello',
onChange: (value) => console.log(value),
},
},
]);
return (
<ReactFlow
nodes={nodes}
nodeTypes={nodeTypes}
onNodesChange={onNodesChang