はじめに
データの流れやワークフローを視覚的に表現したい、ノードベースのエディタを作りたい。そういうニーズ、最近増えてきていると思うんですよ。
GitHubで34,000スター以上、週間270万ダウンロード。React Flowはノードベースのインタラクティブなダイアグラムを構築するためのReactコンポーネントとして、かなりの地位を確立しています。
正直なところ、最初は「フローチャートのライブラリなんて自分には関係ない」と思っていたんです。でも実際に触ってみたら、ワークフロービルダーからAIパイプライン設計まで、応用範囲の広さに驚きました。30代になって思うのは、「使わないだろう」と決めつけずに触ってみることの大切さですね。
React Flowとは
React Flowは、ノードベースのエディタやインタラクティブなダイアグラムを構築するためのカスタマイズ可能なReactコンポーネントライブラリです。
xyflow社が開発・メンテナンスしており、npmでは@xyflow/reactパッケージとして提供されています。MITライセンスのオープンソースなので、商用利用も問題なし。
Stripe、Zapier、Retool、Railwayなど、名だたるテック企業が採用しているという事実が、その信頼性を物語っています。
特徴・メリット
1. 箱から出してすぐ使える
ドラッグ、ズーム、パンニング、複数選択、要素の追加・削除。これらの機能が最初から組み込まれています。
個人的には、この「すぐ動く」感覚が一番ありがたい。ゼロから実装すると膨大な時間がかかる機能が、最初から揃っているわけです。
2. カスタマイズ性が高い
ノードは単なるReactコンポーネント。つまり、普段使っているReactの知識がそのまま活かせます。
const CustomNode = ({ data }) => {
return (
<div className="custom-node">
<Handle type="target" position={Position.Top} />
<div>{data.label}</div>
<Handle type="source" position={Position.Bottom} />
</div>
)
}
TailwindやCSS-in-JSとの相性も良好。デザインの自由度が高いので、プロジェクトの雰囲気に合わせられます。
3. パフォーマンスが考慮されている
変更されたノードだけが再レンダリングされる設計。数百ノードを扱うような場面でも、スムーズに動作します。
コスパ的に、パフォーマンス最適化を自分でやらなくていいのは大きい。
4. プラグインが充実
- Background: グリッドやドットのバックグラウンド
- MiniMap: 全体を俯瞰できるミニマップ
- Controls: ズームイン・アウトのコントロール
- Panel: フローティングパネル
- NodeToolbar: ノード操作用のツールバー
- NodeResizer: ノードのサイズ変更
これ、意外と自分で作ると大変なんですよ。標準で用意されているのは時短になる。
5. TypeScriptフレンドリー
型定義がしっかりしているので、TypeScriptで書くときのストレスがない。エディタの補完も効くし、型安全に開発できます。
インストール方法
前提条件
React 17以上のプロジェクトが必要です。
インストール
npm install @xyflow/react
以前はreactflowというパッケージ名でしたが、現在は@xyflow/reactに統一されています。
スタイルの読み込み
デフォルトスタイルを使う場合:
import '@xyflow/react/dist/style.css'
必要最小限のスタイルだけ使いたい場合:
import '@xyflow/react/dist/base.css'
基本的な使い方
シンプルなフロー
import { useCallback } from 'react'
import {
ReactFlow,
addEdge,
useNodesState,
useEdgesState,
type Node,
type Edge,
type Connection,
} from '@xyflow/react'
import '@xyflow/react/dist/style.css'
// 初期ノード
const initialNodes: Node[] = [
{
id: '1',
position: { x: 0, y: 0 },
data: { label: '入力' },
type: 'input',
},
{
id: '2',
position: { x: 0, y: 100 },
data: { label: '処理' },
},
{
id: '3',
position: { x: 0, y: 200 },
data: { label: '出力' },
type: 'output',
},
]
// 初期エッジ(ノード間の接続線)
const initialEdges: Edge[] = [
{ id: 'e1-2', source: '1', target: '2' },
{ id: 'e2-3', source: '2', target: '3' },
]
function Flow() {
const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes)
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges)
const onConnect = useCallback(
(connection: Connection) => {
setEdges((eds) => addEdge(connection, eds))
},
[setEdges]
)
return (
<div style={{ width: '100%', height: '500px' }}>
<ReactFlow
nodes={nodes}
edges={edges}
onNodesChange={onNodesChange}
onEdgesChange={onEdgesChange}
onConnect={onConnect}
fitView
/>
</div>
)
}
export default Flow
これだけでドラッグ可能なノード、接続可能なエッジ、ズーム・パンが動作します。普通のhookと同じ感覚で使えるのがいいですね。
カスタムノードの作成
import { Handle, Position, type NodeProps } from '@xyflow/react'
type TaskNodeData = {
label: string
status: 'pending' | 'running' | 'completed'
}
function TaskNode({ data }: NodeProps<TaskNodeData>) {
const statusColors = {
pending: 'bg-gray-200',
running: 'bg-yellow-200',
completed: 'bg-green-200',
}
return (
<div className={`px-4 py-2 rounded-lg shadow-md ${statusColors[data.status]}`}>
<Handle type="target" position={Position.Top} />
<div className="font-medium">{data.label}</div>
<div className="text-sm text-gray-600">{data.status}</div>
<Handle type="source" position={Position.Bottom} />
</div>
)
}
// 使用時
const nodeTypes = { task: TaskNode }
function Flow() {
// ...
return (
<ReactFlow
nodes={nodes}
edges={edges}
nodeTypes={nodeTypes}
// ...
/>
)
}
Reactコンポーネントとして実装できるので、stateやpropsも普通に使える。学習コストが低いのがありがたい。
プラグインの活用
import {
ReactFlow,
Background,
Controls,
MiniMap,
} from '@xyflow/react'
function Flow() {
return (
<div style={{ width: '100%', height: '500px' }}>
<ReactFlow
nodes={nodes}
edges={edges}
onNodesChange={onNodesChange}
onEdgesChange={onEdgesChange}
fitView
>
<Background variant="dots" gap={12} size={1} />
<Controls />
<MiniMap />
</ReactFlow>
</div>
)
}
これでグリッド背景、ズームコントロール、ミニマップが追加される。コンポーネントを追加するだけで機能が増えるのは直感的。
実践的なユースケース
ワークフロービルダー
n8nやZapierのような自動化ツールのインターフェース。トリガー→アクション→条件分岐といったフローを視覚的に組み立てられます。
const workflowNodes: Node[] = [
{
id: 'trigger',
type: 'trigger',
position: { x: 250, y: 0 },
data: { label: 'Webhook受信', icon: 'webhook' },
},
{
id: 'filter',
type: 'condition',
position: { x: 250, y: 100 },
data: { label: '条件分岐', condition: 'status === 200' },
},
{
id: 'action1',
type: 'action',
position: { x: 100, y: 200 },
data: { label: 'Slack通知' },
},
{
id: 'action2',
type: 'action',
position: { x: 400, y: 200 },
data: { label: 'DBに保存' },
},
]
マインドマップ
アイデア整理やブレインストーミング用のツール。
import { MarkerType } from '@xyflow/react'
const mindMapEdges: Edge[] = [
{
id: 'e1-2',
source: 'main',
target: 'idea1',
type: 'smoothstep',
markerEnd: { type: MarkerType.ArrowClosed },
},
// ...
]
AIパイプライン設計
LangChainやFlowise的な、AIモデルの処理フローを設計するツール。入力→プロンプトテンプレート→LLM→出力パーサーといった流れを視覚化できます。
組織図・ER図
階層構造やエンティティ間の関係を表現。dagre等のレイアウトアルゴリズムと組み合わせると、自動配置も可能。
import dagre from 'dagre'
const getLayoutedElements = (nodes: Node[], edges: Edge[]) => {
const dagreGraph = new dagre.graphlib.Graph()
dagreGraph.setDefaultEdgeLabel(() => ({}))
dagreGraph.setGraph({ rankdir: 'TB' })
nodes.forEach((node) => {
dagreGraph.setNode(node.id, { width: 150, height: 50 })
})
edges.forEach((edge) => {
dagreGraph.setEdge(edge.source, edge.target)
})
dagre.layout(dagreGraph)
const layoutedNodes = nodes.map((node) => {
const nodeWithPosition = dagreGraph.node(node.id)
return {
...node,
position: {
x: nodeWithPosition.x - 75,
y: nodeWithPosition.y - 25,
},
}
})
return { nodes: layoutedNodes, edges }
}
注意点
親要素のサイズ指定
ReactFlowは親要素の100%を占めるので、親要素に明示的なサイズが必要です。
// NG: 高さが0になる
<div>
<ReactFlow />
</div>
// OK: 高さを指定
<div style={{ height: '500px' }}>
<ReactFlow />
</div>
これ、最初にハマるポイントなので覚えておくといいです。
状態管理の設計
ノードやエッジの状態が複雑になってきたら、Zustandなど外部の状態管理と組み合わせることを検討してください。React Flowが提供するhooksと相性がいいです。
まとめ
React Flowを使ってみて感じたこと:
- 学習コスト: Reactの知識がそのまま活きる。1日で基本は把握できる
- カスタマイズ性: ノードもエッジも自由に設計可能
- パフォーマンス: 大量ノードでもスムーズ
- エコシステム: プラグイン、サンプル、ドキュメントが充実
- 実績: Stripe、Zapierなど大手が採用
正直なところ、ノードベースのUIを1から実装するのは相当な工数がかかります。ドラッグ、ズーム、接続線の描画、当たり判定...考えるだけで気が遠くなる。それがReact Flowなら、数時間で動くプロトタイプが作れる。
ワークフロービルダー、ノーコードツール、データパイプラインの可視化。こういったプロジェクトを検討しているなら、React Flow一択ですね。
まだ触ったことがない人は、公式サイトのExamplesから試してみてください。50以上のサンプルがあるので、イメージが湧きやすいと思います。