react-flow-architect
Expert ReactFlow architect for building interactive graph applications with hierarchical node-edge systems, performance optimization, and auto-layout integration. Use when Claude needs to create or optimize ReactFlow applications for: (1) Interactive process graphs with expand/collapse navigation, (2) Hierarchical tree structures with drag & drop, (3) Performance-optimized large datasets with incremental rendering, (4) Auto-layout integration with Dagre, (5) Complex state management for nodes and edges, or any advanced ReactFlow visualization requirements.
Best use case
react-flow-architect is best used when you need a repeatable AI agent workflow instead of a one-off prompt. It is especially useful for teams working in multi. Expert ReactFlow architect for building interactive graph applications with hierarchical node-edge systems, performance optimization, and auto-layout integration. Use when Claude needs to create or optimize ReactFlow applications for: (1) Interactive process graphs with expand/collapse navigation, (2) Hierarchical tree structures with drag & drop, (3) Performance-optimized large datasets with incremental rendering, (4) Auto-layout integration with Dagre, (5) Complex state management for nodes and edges, or any advanced ReactFlow visualization requirements.
Expert ReactFlow architect for building interactive graph applications with hierarchical node-edge systems, performance optimization, and auto-layout integration. Use when Claude needs to create or optimize ReactFlow applications for: (1) Interactive process graphs with expand/collapse navigation, (2) Hierarchical tree structures with drag & drop, (3) Performance-optimized large datasets with incremental rendering, (4) Auto-layout integration with Dagre, (5) Complex state management for nodes and edges, or any advanced ReactFlow visualization requirements.
Users should expect a more consistent workflow output, faster repeated execution, and less time spent rewriting prompts from scratch.
Practical example
Example input
Use the "react-flow-architect" skill to help with this workflow task. Context: Expert ReactFlow architect for building interactive graph applications with hierarchical node-edge systems, performance optimization, and auto-layout integration. Use when Claude needs to create or optimize ReactFlow applications for: (1) Interactive process graphs with expand/collapse navigation, (2) Hierarchical tree structures with drag & drop, (3) Performance-optimized large datasets with incremental rendering, (4) Auto-layout integration with Dagre, (5) Complex state management for nodes and edges, or any advanced ReactFlow visualization requirements.
Example output
A structured workflow result with clearer steps, more consistent formatting, and an output that is easier to reuse in the next run.
When to use this skill
- Use this skill when you want a reusable workflow rather than writing the same prompt again and again.
When not to use this skill
- Do not use this when you only need a one-off answer and do not need a reusable workflow.
- Do not use it if you cannot install or maintain the related files, repository context, or supporting tools.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/react-flow-architect/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How react-flow-architect Compares
| Feature / Agent | react-flow-architect | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Expert ReactFlow architect for building interactive graph applications with hierarchical node-edge systems, performance optimization, and auto-layout integration. Use when Claude needs to create or optimize ReactFlow applications for: (1) Interactive process graphs with expand/collapse navigation, (2) Hierarchical tree structures with drag & drop, (3) Performance-optimized large datasets with incremental rendering, (4) Auto-layout integration with Dagre, (5) Complex state management for nodes and edges, or any advanced ReactFlow visualization requirements.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# ReactFlow Architect
Build production-ready ReactFlow applications with hierarchical navigation, performance optimization, and advanced state management.
## Quick Start
Create basic interactive graph:
```tsx
import ReactFlow, { Node, Edge } from "reactflow";
const nodes: Node[] = [
{ id: "1", position: { x: 0, y: 0 }, data: { label: "Node 1" } },
{ id: "2", position: { x: 100, y: 100 }, data: { label: "Node 2" } },
];
const edges: Edge[] = [{ id: "e1-2", source: "1", target: "2" }];
export default function Graph() {
return <ReactFlow nodes={nodes} edges={edges} />;
}
```
## Core Patterns
### Hierarchical Tree Navigation
Build expandable/collapsible tree structures with parent-child relationships.
#### Node Schema
```typescript
interface TreeNode extends Node {
data: {
label: string;
level: number;
hasChildren: boolean;
isExpanded: boolean;
childCount: number;
category: "root" | "category" | "process" | "detail";
};
}
```
#### Incremental Node Building
```typescript
const buildVisibleNodes = useCallback(
(allNodes: TreeNode[], expandedIds: Set<string>, otherDeps: any[]) => {
const visibleNodes = new Map<string, TreeNode>();
const visibleEdges = new Map<string, TreeEdge>();
// Start with root nodes
const rootNodes = allNodes.filter((n) => n.data.level === 0);
// Recursively add visible nodes
const addVisibleChildren = (node: TreeNode) => {
visibleNodes.set(node.id, node);
if (expandedIds.has(node.id)) {
const children = allNodes.filter((n) => n.parentNode === node.id);
children.forEach((child) => addVisibleChildren(child));
}
};
rootNodes.forEach((root) => addVisibleChildren(root));
return {
nodes: Array.from(visibleNodes.values()),
edges: Array.from(visibleEdges.values()),
};
},
[],
);
```
### Performance Optimization
Handle large datasets with incremental rendering and memoization.
#### Incremental Rendering
```typescript
const useIncrementalGraph = (
allNodes: Node[],
allEdges: Edge[],
expandedList: string[],
) => {
const prevExpandedListRef = useRef<Set<string>>(new Set());
const prevOtherDepsRef = useRef<any[]>([]);
const { visibleNodes, visibleEdges } = useMemo(() => {
const currentExpandedSet = new Set(expandedList);
const prevExpandedSet = prevExpandedListRef.current;
// Check if expanded list changed
const expandedChanged = !areSetsEqual(currentExpandedSet, prevExpandedSet);
// Check if other dependencies changed
const otherDepsChanged = !arraysEqual(otherDeps, prevOtherDepsRef.current);
if (expandedChanged && !otherDepsChanged) {
// Only expanded list changed - incremental update
return buildIncrementalUpdate(
cachedVisibleNodesRef.current,
cachedVisibleEdgesRef.current,
allNodes,
allEdges,
currentExpandedSet,
prevExpandedSet,
);
} else {
// Full rebuild needed
return buildFullGraph(allNodes, allEdges, currentExpandedSet);
}
}, [allNodes, allEdges, expandedList, ...otherDeps]);
return { visibleNodes, visibleEdges };
};
```
#### Memoization Patterns
```typescript
// Memoize node components to prevent unnecessary re-renders
const ProcessNode = memo(({ data, selected }: NodeProps) => {
return (
<div className={`process-node ${selected ? 'selected' : ''}`}>
{data.label}
</div>
);
}, (prevProps, nextProps) => {
// Custom comparison function
return (
prevProps.data.label === nextProps.data.label &&
prevProps.selected === nextProps.selected &&
prevProps.data.isExpanded === nextProps.data.isExpanded
);
});
// Memoize edge calculations
const styledEdges = useMemo(() => {
return edges.map(edge => ({
...edge,
style: {
...edge.style,
strokeWidth: selectedEdgeId === edge.id ? 3 : 2,
stroke: selectedEdgeId === edge.id ? '#3b82f6' : '#94a3b8',
},
animated: selectedEdgeId === edge.id,
}));
}, [edges, selectedEdgeId]);
```
### State Management
Complex node/edge state patterns with undo/redo and persistence.
#### Reducer Pattern
```typescript
type GraphAction =
| { type: "SELECT_NODE"; payload: string }
| { type: "SELECT_EDGE"; payload: string }
| { type: "TOGGLE_EXPAND"; payload: string }
| { type: "UPDATE_NODES"; payload: Node[] }
| { type: "UPDATE_EDGES"; payload: Edge[] }
| { type: "UNDO" }
| { type: "REDO" };
const graphReducer = (state: GraphState, action: GraphAction): GraphState => {
switch (action.type) {
case "SELECT_NODE":
return {
...state,
selectedNodeId: action.payload,
selectedEdgeId: null,
};
case "TOGGLE_EXPAND":
const newExpanded = new Set(state.expandedNodeIds);
if (newExpanded.has(action.payload)) {
newExpanded.delete(action.payload);
} else {
newExpanded.add(action.payload);
}
return {
...state,
expandedNodeIds: newExpanded,
isDirty: true,
};
default:
return state;
}
};
```
#### History Management
```typescript
const useHistoryManager = (
state: GraphState,
dispatch: Dispatch<GraphAction>,
) => {
const canUndo = state.historyIndex > 0;
const canRedo = state.historyIndex < state.history.length - 1;
const undo = useCallback(() => {
if (canUndo) {
const newIndex = state.historyIndex - 1;
const historyEntry = state.history[newIndex];
dispatch({
type: "RESTORE_FROM_HISTORY",
payload: {
...historyEntry,
historyIndex: newIndex,
},
});
}
}, [canUndo, state.historyIndex, state.history]);
const saveToHistory = useCallback(() => {
dispatch({ type: "SAVE_TO_HISTORY" });
}, [dispatch]);
return { canUndo, canRedo, undo, redo, saveToHistory };
};
```
## Advanced Features
### Auto-Layout Integration
Integrate Dagre for automatic graph layout:
```typescript
import dagre from "dagre";
const layoutOptions = {
rankdir: "TB", // Top to Bottom
nodesep: 100, // Node separation
ranksep: 150, // Rank separation
marginx: 50,
marginy: 50,
edgesep: 10,
};
const applyLayout = (nodes: Node[], edges: Edge[]) => {
const g = new dagre.graphlib.Graph();
g.setGraph(layoutOptions);
g.setDefaultEdgeLabel(() => ({}));
// Add nodes to graph
nodes.forEach((node) => {
g.setNode(node.id, { width: 200, height: 100 });
});
// Add edges to graph
edges.forEach((edge) => {
g.setEdge(edge.source, edge.target);
});
// Calculate layout
dagre.layout(g);
// Apply positions
return nodes.map((node) => ({
...node,
position: {
x: g.node(node.id).x - 100,
y: g.node(node.id).y - 50,
},
}));
};
// Debounce layout calculations
const debouncedLayout = useMemo(() => debounce(applyLayout, 150), []);
```
### Focus Mode
Isolate selected nodes and their direct connections:
```typescript
const useFocusMode = (
selectedNodeId: string,
allNodes: Node[],
allEdges: Edge[],
) => {
return useMemo(() => {
if (!selectedNodeId) return { nodes: allNodes, edges: allEdges };
// Get direct connections
const connectedNodeIds = new Set([selectedNodeId]);
const focusedEdges: Edge[] = [];
allEdges.forEach((edge) => {
if (edge.source === selectedNodeId || edge.target === selectedNodeId) {
focusedEdges.push(edge);
connectedNodeIds.add(edge.source);
connectedNodeIds.add(edge.target);
}
});
// Get connected nodes
const focusedNodes = allNodes.filter((n) => connectedNodeIds.has(n.id));
return { nodes: focusedNodes, edges: focusedEdges };
}, [selectedNodeId, allNodes, allEdges]);
};
// Smooth transitions for focus mode
const focusModeStyles = {
transition: "all 0.3s ease-in-out",
opacity: isInFocus ? 1 : 0.3,
filter: isInFocus ? "none" : "blur(2px)",
};
```
### Search Integration
Search and navigate to specific nodes:
```typescript
const searchNodes = useCallback((nodes: Node[], query: string) => {
if (!query.trim()) return [];
const lowerQuery = query.toLowerCase();
return nodes.filter(
(node) =>
node.data.label.toLowerCase().includes(lowerQuery) ||
node.data.description?.toLowerCase().includes(lowerQuery),
);
}, []);
const navigateToSearchResult = (nodeId: string) => {
// Expand parent nodes
const nodePath = calculateBreadcrumbPath(nodeId, allNodes);
const parentIds = nodePath.slice(0, -1).map((n) => n.id);
setExpandedIds((prev) => new Set([...prev, ...parentIds]));
setSelectedNodeId(nodeId);
// Fit view to node
fitView({ nodes: [{ id: nodeId }], duration: 800 });
};
```
## Performance Tools
### Graph Performance Analyzer
Create a performance analysis script:
```javascript
// scripts/graph-analyzer.js
class GraphAnalyzer {
analyzeCode(content, filePath) {
const analysis = {
metrics: {
nodeCount: this.countNodes(content),
edgeCount: this.countEdges(content),
renderTime: this.estimateRenderTime(content),
memoryUsage: this.estimateMemoryUsage(content),
complexity: this.calculateComplexity(content),
},
issues: [],
optimizations: [],
patterns: this.detectPatterns(content),
};
// Detect performance issues
this.detectPerformanceIssues(analysis);
// Suggest optimizations
this.suggestOptimizations(analysis);
return analysis;
}
countNodes(content) {
const nodePatterns = [
/nodes:\s*\[.*?\]/gs,
/const\s+\w+\s*=\s*\[.*?id:.*?position:/gs,
];
let totalCount = 0;
nodePatterns.forEach((pattern) => {
const matches = content.match(pattern);
if (matches) {
matches.forEach((match) => {
const nodeMatches = match.match(/id:\s*['"`][^'"`]+['"`]/g);
if (nodeMatches) {
totalCount += nodeMatches.length;
}
});
}
});
return totalCount;
}
estimateRenderTime(content) {
const nodeCount = this.countNodes(content);
const edgeCount = this.countEdges(content);
// Base render time estimation (ms)
const baseTime = 5;
const nodeTime = nodeCount * 0.1;
const edgeTime = edgeCount * 0.05;
return baseTime + nodeTime + edgeTime;
}
detectPerformanceIssues(analysis) {
const { metrics } = analysis;
if (metrics.nodeCount > 500) {
analysis.issues.push({
type: "HIGH_NODE_COUNT",
severity: "high",
message: `Too many nodes (${metrics.nodeCount}). Consider virtualization.`,
suggestion: "Implement virtualization or reduce visible nodes",
});
}
if (metrics.renderTime > 16) {
analysis.issues.push({
type: "SLOW_RENDER",
severity: "high",
message: `Render time (${metrics.renderTime.toFixed(2)}ms) exceeds 60fps.`,
suggestion: "Optimize with memoization and incremental rendering",
});
}
}
}
```
## Best Practices
### Performance Guidelines
1. **Use React.memo** for node components to prevent unnecessary re-renders
2. **Implement virtualization** for graphs with 1000+ nodes
3. **Debounce layout calculations** during rapid interactions
4. **Use useCallback** for edge creation and manipulation functions
5. **Implement proper TypeScript types** for nodes and edges
### Memory Management
```typescript
// Use Map for O(1) lookups instead of array.find
const nodesById = useMemo(
() => new Map(allNodes.map((n) => [n.id, n])),
[allNodes],
);
// Cache layout results
const layoutCacheRef = useRef<Map<string, Node[]>>(new Map());
// Proper cleanup in useEffect
useEffect(() => {
return () => {
// Clean up any lingering references
nodesMapRef.current.clear();
edgesMapRef.current.clear();
};
}, []);
```
### State Optimization
```typescript
// Use useRef for objects that shouldn't trigger re-renders
const autoSaveDataRef = useRef({
nodes: [],
edges: [],
lastSaved: Date.now(),
});
// Update properties without breaking reference
const updateAutoSaveData = (newNodes: Node[], newEdges: Edge[]) => {
autoSaveDataRef.current.nodes = newNodes;
autoSaveDataRef.current.edges = newEdges;
autoSaveDataRef.current.lastSaved = Date.now();
};
```
## Common Problems & Solutions
### Performance Issues
- **Problem**: Lag during node expansion
- **Solution**: Implement incremental rendering with change detection
- **Problem**: Memory usage increases over time
- **Solution**: Proper cleanup in useEffect hooks and use WeakMap for temporary data
### Layout Conflicts
- **Problem**: Manual positioning conflicts with auto-layout
- **Solution**: Use controlled positioning state and separate layout modes
### Rendering Issues
- **Problem**: Excessive re-renders
- **Solution**: Use memo, useMemo, and useCallback with stable dependencies
- **Problem**: Slow layout calculations
- **Solution**: Debounce layout calculations and cache results
## Complete Example
```typescript
import React, { useState, useCallback, useMemo, useRef } from 'react';
import ReactFlow, { Node, Edge, useReactFlow } from 'reactflow';
import dagre from 'dagre';
import { debounce } from 'lodash';
interface GraphState {
nodes: Node[];
edges: Edge[];
selectedNodeId: string | null;
expandedNodeIds: Set<string>;
history: GraphState[];
historyIndex: number;
}
export default function InteractiveGraph() {
const [state, setState] = useState<GraphState>({
nodes: [],
edges: [],
selectedNodeId: null,
expandedNodeIds: new Set(),
history: [],
historyIndex: 0,
});
const { fitView } = useReactFlow();
const layoutCacheRef = useRef<Map<string, Node[]>>(new Map());
// Memoized styled edges
const styledEdges = useMemo(() => {
return state.edges.map(edge => ({
...edge,
style: {
...edge.style,
strokeWidth: state.selectedNodeId === edge.source || state.selectedNodeId === edge.target ? 3 : 2,
stroke: state.selectedNodeId === edge.source || state.selectedNodeId === edge.target ? '#3b82f6' : '#94a3b8',
},
animated: state.selectedNodeId === edge.source || state.selectedNodeId === edge.target,
}));
}, [state.edges, state.selectedNodeId]);
// Debounced layout calculation
const debouncedLayout = useMemo(
() => debounce((nodes: Node[], edges: Edge[]) => {
const cacheKey = generateLayoutCacheKey(nodes, edges);
if (layoutCacheRef.current.has(cacheKey)) {
return layoutCacheRef.current.get(cacheKey)!;
}
const layouted = applyDagreLayout(nodes, edges);
layoutCacheRef.current.set(cacheKey, layouted);
return layouted;
}, 150),
[]
);
const handleNodeClick = useCallback((event: React.MouseEvent, node: Node) => {
setState(prev => ({
...prev,
selectedNodeId: node.id,
}));
}, []);
const handleToggleExpand = useCallback((nodeId: string) => {
setState(prev => {
const newExpanded = new Set(prev.expandedNodeIds);
if (newExpanded.has(nodeId)) {
newExpanded.delete(nodeId);
} else {
newExpanded.add(nodeId);
}
return {
...prev,
expandedNodeIds: newExpanded,
};
});
}, []);
return (
<ReactFlow
nodes={state.nodes}
edges={styledEdges}
onNodeClick={handleNodeClick}
fitView
/>
);
}
```
This comprehensive skill provides everything needed to build production-ready ReactFlow applications with hierarchical navigation, performance optimization, and advanced state management patterns.Related Skills
req-change-workflow
Standardize requirement/feature changes in an existing codebase (especially Chrome extensions) by turning "改需求/需求变更/调整交互/改功能/重构流程" into a repeatable loop: clarify acceptance criteria, confirm current behavior from code, assess impact/risk, design the new logic, implement with small diffs, run a fixed regression checklist, and update docs/decision log. Use when the user feels the change process is chaotic, when edits tend to sprawl across files, or when changes touch manifest/service worker/OAuth/storage/UI and need reliable verification + rollback planning.
react-native-design
Master React Native styling, navigation, and Reanimated animations for cross-platform mobile development. Use when building React Native apps, implementing navigation patterns, or creating performant animations.
defou-workflow
将原始想法转化为结构清晰、判断明确、具有长期价值的“得否”风格内容报告。
defou-stanley-workflow
Defou x Stanley 融合工作流:结合深度结构化思考与人性弱点洞察,生成极简、犀利且具有长期价值的爆款内容。
agentic-workflow
Practical AI agent workflows and productivity techniques. Provides optimized patterns for daily development tasks such as commands, shortcuts, Git integration, MCP usage, and session management.
react-useeffect
React useEffect best practices from official docs. Use when writing/reviewing useEffect, useState for derived values, data fetching, or state synchronization. Teaches when NOT to use Effect and better alternatives.
react-dev
This skill should be used when building React components with TypeScript, typing hooks, handling events, or when React TypeScript, React 19, Server Components are mentioned. Covers type-safe patterns for React 18-19 including generic components, proper event typing, and routing integration (TanStack Router, React Router).
c4-architecture
Generate architecture documentation using C4 model Mermaid diagrams. Use when asked to create architecture diagrams, document system architecture, visualize software structure, create C4 diagrams, or generate context/container/component/deployment diagrams. Triggers include "architecture diagram", "C4 diagram", "system context", "container diagram", "component diagram", "deployment diagram", "document architecture", "visualize architecture".
workflow-patterns
Use this skill when implementing tasks according to Conductor's TDD workflow, handling phase checkpoints, managing git commits for tasks, or understanding the verification protocol.
workflow-orchestration-patterns
Design durable workflows with Temporal for distributed systems. Covers workflow vs activity separation, saga patterns, state management, and determinism constraints. Use when building long-running processes, distributed transactions, or microservice orchestration.
workflow-automation
Workflow automation is the infrastructure that makes AI agents reliable. Without durable execution, a network hiccup during a 10-step payment flow means lost money and angry customers. With it, workflows resume exactly where they left off. This skill covers the platforms (n8n, Temporal, Inngest) and patterns (sequential, parallel, orchestrator-worker) that turn brittle scripts into production-grade automation. Key insight: The platforms make different tradeoffs. n8n optimizes for accessibility
wiki-architect
Analyzes code repositories and generates hierarchical documentation structures with onboarding guides. Use when the user wants to create a wiki, generate documentation, map a codebase structure, or understand a project's architecture at a high level.