Diagrams

FeatureXYFlow

Node-based diagrams with XYFlow (React Flow) — flow charts, mind maps, and interactive node editors.

Read this when adding diagram features to your app.
Useful for workflow builders, mind maps, or visual editors.

Why XYFlow

XYFlow (formerly React Flow) is purpose-built for node-based UIs. It handles pan, zoom, selection, and connections — you focus on defining nodes and their behavior.

The library supports custom node types, edge styles, and interactions. It's well-documented and widely used for everything from workflow builders to visual programming environments.

Key Features

What XYFlow provides:

Custom Nodes

Any React component. Build nodes with custom UI, inputs, and behaviors.

Connections

Connect nodes visually. Drag to connect, custom edge styles, animated edges.

Interactions

Pan, zoom, select. Built-in controls with customizable behavior.

Catalyst Integration

Catalyst includes a diagrams module:

modules/diagrams/

Full diagram module with persistence

app/(app)/app/diagrams/

Diagram editor pages

Quick Start

Basic flow

"use client"
import { ReactFlow, Background, Controls } from "@xyflow/react"
import "@xyflow/react/dist/style.css"

const initialNodes = [
  { id: "1", position: { x: 0, y: 0 }, data: { label: "Start" } },
  { id: "2", position: { x: 0, y: 100 }, data: { label: "Process" } },
  { id: "3", position: { x: 0, y: 200 }, data: { label: "End" } },
]

const initialEdges = [
  { id: "e1-2", source: "1", target: "2" },
  { id: "e2-3", source: "2", target: "3" },
]

export function FlowDiagram() {
  return (
    <div style={{ width: "100%", height: 500 }}>
      <ReactFlow
        nodes={initialNodes}
        edges={initialEdges}
        fitView
      >
        <Background />
        <Controls />
      </ReactFlow>
    </div>
  )
}

Interactive flow with state

import { useState, useCallback } from "react"
import {
  ReactFlow,
  addEdge,
  useNodesState,
  useEdgesState,
  Background,
  Controls,
  MiniMap,
} from "@xyflow/react"

export function InteractiveFlow() {
  const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes)
  const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges)

  const onConnect = useCallback((params) => {
    setEdges((eds) => addEdge(params, eds))
  }, [setEdges])

  return (
    <ReactFlow
      nodes={nodes}
      edges={edges}
      onNodesChange={onNodesChange}
      onEdgesChange={onEdgesChange}
      onConnect={onConnect}
      fitView
    >
      <Background />
      <Controls />
      <MiniMap />
    </ReactFlow>
  )
}

Custom node type

import { Handle, Position } from "@xyflow/react"

function CustomNode({ data }) {
  return (
    <div className="rounded-lg border bg-background p-4 shadow-sm">
      <Handle type="target" position={Position.Top} />
      <div className="font-medium">{data.label}</div>
      {data.description && (
        <div className="text-sm text-muted-foreground">{data.description}</div>
      )}
      <Handle type="source" position={Position.Bottom} />
    </div>
  )
}

// Register in nodeTypes
const nodeTypes = { custom: CustomNode }

<ReactFlow nodeTypes={nodeTypes} ... />

Built-in Components

Background

Grid or dot pattern background

Controls

Zoom in/out, fit view, lock buttons

MiniMap

Overview minimap for navigation

Panel

Positioned panels for UI overlays

Tips

Import the CSS. XYFlow needs its stylesheet for proper rendering of controls and edges.

Set container dimensions. The ReactFlow component needs a sized parent — won't work without width/height.

Use hooks for state. useNodesState and useEdgesState handle immutable updates correctly.

Memoize custom nodes. Wrap custom node components in memo() to prevent unnecessary re-renders.

Learn More

For AI Agents

Key rules:

  • Import from @xyflow/react
  • Import @xyflow/react/dist/style.css
  • Container must have explicit width and height
  • Use useNodesState/useEdgesState for state management
  • Check modules/diagrams/ for Catalyst patterns
  • Memoize custom node components