Skip to content
Skills Library
Programming · Review & audit

react-flow-code-review

/react-flow-code-review

Reviews React Flow code for anti-patterns, performance issues, and best practices. Use when reviewing code that uses @xyflow/react, checking for common mistakes, or optimizing node-based UI implementations.

Repository
beagle ↗
Licence
Apache-2.0
Last repository change
09.08.2026

Assessment and security

100/ 100Class: good
Format25 / 25
Frontmatter with name and description, valid name, description up to 1,024 characters, name matching the folder.
Discoverability25 / 25
Description explains when to use the skill, has a reasonable length and uses third person.
Content35 / 35
At least 150 words and at most 500 lines, headings, step lists, examples or code.
Hygiene15 / 15
No placeholders such as TODO, no Windows paths, with a licence.
Riskno signals detected in the scan
Files in this package
1
Scripts
0
HTML comments
0
URLs in SKILL.md
0
Deprecation

No signals detected. Repository changed on 09.08.2026, without references to retired models or APIs.

Licence

Apache-2.0, otwarta: można używać i zmieniać, z zachowaniem licencji i informacji o zmianach.

What it does and when to use it

Reviews React Flow code for anti-patterns, performance issues, and best practices. Use when reviewing code that uses @xyflow/react, checking for common mistakes, or optimizing node-based UI implementations.

Original author description

Reviews React Flow code for anti-patterns, performance issues, and best practices. Use when reviewing code that uses @xyflow/react, checking for common mistakes, or optimizing node-based UI implementations.

How it works

  1. Review gates (sequenced)
  2. Critical Anti-Patterns
  3. Performance Checklist
  4. Common Mistakes
  5. TypeScript Issues
  6. Review Questions
Original SKILL.md headings · 235 lines, 936 words
SKILL.md preview
---
name: react-flow-code-review
description: Reviews React Flow code for anti-patterns, performance issues, and best practices. Use when reviewing code that uses @xyflow/react, checking for common mistakes, or optimizing node-based UI implementations.
---

# React Flow Code Review

When reviewing React Flow code, complete the gates below in order. Each step has an objective pass condition before moving on.

## Review gates (sequenced)

1. **Locate flow code** — Search the review scope for `ReactFlow`, `ReactFlowProvider`, `useReactFlow`, `@xyflow/react`, `nodeTypes`, and `edgeTypes`. **Pass:** a short list of file paths (or explicit “none in scope” after searching).

2. **Provider boundary** — For each `useReactFlow()` (and other hooks that require the provider), trace the component tree to an enclosing `ReactFlowProvider`, or record a concrete mismatch with **file:line**.

3. **Stable types and memo surfaces** — For each custom node or edge component, note whether it uses `memo` and typed props (`NodeProps<...>`, etc.). For each `nodeTypes` / `edgeTypes` value passed into `<ReactFlow>`, confirm a stable reference (module scope, or `useMemo` with deps you can point to) or flag unstable recreation with **file:line**.

4. **Report with evidence** — For each finding you will deliver, record **file path and line number(s)** (or a minimal quoted snippet). **Pass:** no critical or high-severity issue is stated without that citation.

5. **Close the checklists** — Use [Performance Checklist](#performance-checklist) and [Common Mistakes](#common-mistakes); each item is **satisfied**, **not applicable** (with reason), or **open** with evidence. **Pass:** no item left silently ambiguous.

## Critical Anti-Patterns

### 1. Defining nodeTypes/edgeTypes Inside Components

**Problem**: Causes all nodes to re-mount on every render.

```tsx
// BAD - recreates object every render
function Flow() {
  const nodeTypes = { custom: CustomNode };  // WRONG
  return <ReactFlow nodeTypes={nodeTypes} />;
}

// GOOD - defined outside component
const nodeTypes = { custom: CustomNode };
function Flow() {
  return <ReactFlow nodeTypes={nodeTypes} />;
}

// GOOD - useMemo if dynamic
function Flow() {
  const nodeTypes = useMemo(() => ({ custom: CustomNode }), []);
  return <ReactFlow nodeTypes={nodeTypes} />;
}
```

### 2. Missing memo() on Custom Nodes/Edges

**Problem**: Custom components re-render on every parent update.

```tsx
// BAD - no memoization
function CustomNode({ data }: NodeProps) {
  return <div>{data.label}</div>;
}

// GOOD - wrapped in memo
import { memo } from 'react';
const CustomNode = memo(function CustomNode({ data }: NodeProps) {
  return <div>{data.label}</div>;
});
```

### 3. Inline Callbacks Without useCallback

**Problem**: Creates new function references, breaking memoization.

```tsx
// BAD - inline callback
<ReactFlow
  onNodesChange={(changes) => setNodes(applyNodeChanges(changes, nodes))}
/>

// GOOD - memoized callback
const onNodesChange = useCallback(
  (changes) => setNodes((nds) => applyNodeChanges(changes, nds)),
  []
);
<ReactFlow onNodesChange={onNodesChange} />
```

### 4. Using useReactFlow Outside Provider

```tsx
// BAD - will throw error
function App() {
  const { getNodes } = useReactFlow();  // ERROR: No provider
  return <ReactFlow ... />;
}

// GOOD - wrap in provider
function FlowContent() {
  const { getNodes } = useReactFlow();  // Works
  return <ReactFlow ... />;
}

function App() {
  return (
    <ReactFlowProvider>
      <FlowContent />
    </ReactFlowProvider>
  );
}
```

### 5. Storing Complex Objects in Node Data

**Problem**: Reference equality checks fail, causing unnecessary updates.

```tsx
// BAD - new object reference every time
setNodes(nodes.map(n => ({
  ...n,
  data: { ...n.data, config: { nested: 'value' } }  // New object each time
})));

// GOOD - use updateNodeData for targeted updates
const { updateNodeData } = useReactFlow();
updateNodeData(nodeId, { config: { nested: 'value' } });
```

## Performance Checklist

### Node Rendering

- [ ] Custom nodes wrapped in `memo()`
- [ ] nodeTypes defined outside component or memoized
- [ ] Heavy computations inside nodes use `useMemo`
- [ ] Event handlers use `useCallback`

### Edge Rendering

- [ ] Custom edges wrapped in `memo()`
- [ ] edgeTypes defined outside component or memoized
- [ ] Edge path calculations are not duplicated

### State Updates

- [ ] Using functional form of setState: `setNodes((nds) => ...)`
- [ ] Not spreading entire state for single property updates
- [ ] Using `updateNodeData` for data-only changes
- [ ] Batch updates when adding multiple nodes/edges

### Viewport

- [ ] Not calling `fitView()` on every render
- [ ] Using `fitViewOptions` for initial fit only
- [ ] Animation durations are reasonable (< 500ms)

## Common Mistakes

### Missing Container Height

```tsx
// BAD - no height, flow won't render
<ReactFlow nodes={nodes} edges={edges} />

// GOOD - explicit dimensions
<div style={{ width: '100%', height: '100vh' }}>
  <ReactFlow nodes={nodes} edges={edges} />
</div>
```

### Missing CSS Import

```tsx
// Required for default styles
import '@xyflow/react/dist/style.css';
```

### Forgetting nodrag on Interactive Elements

```tsx
// BAD - clicking button drags node
<button onClick={handleClick}>Click</button>

// GOOD - prevents drag
<button className="nodrag" onClick={handleClick}>Click</button>
```

### Not Using Position Constants

```tsx
// BAD - string literals
<Handle type="source" position="right" />

// GOOD - type-safe constants
import { Position } from '@xyflow/react';
<Handle type="source" position={Position.Right} />
```

### Mutating Nodes/Edges Directly

```tsx
// BAD - direct mutation
nodes[0].position = { x: 100, y: 100 };
setNodes(nodes);

// GOOD - immutable update
setNodes(nodes.map(n =>
  n.id === '1' ? { ...n, position: { x: 100, y: 100 } } : n
));
```

## TypeScript Issues

### Missing Generic Types

```tsx
// BAD - loses type safety
const [nodes, setNodes] = useNodesState(initialNodes);

// GOOD - explicit types
type MyNode = Node<{ value: number }, 'custom'>;
const [nodes, setNodes] = useNodesState<MyNode>(initialNodes);
```

### Wrong Props Type

```tsx
// BAD - using wrong type
function CustomNode(props: any) { ... }

// GOOD - correct props type
function CustomNode(props: NodeProps<MyNode>) { ... }
```

## Review Questions

1. Are all custom components memoized?
2. Are nodeTypes/edgeTypes defined outside render?
3. Are callbacks wrapped in useCallback?
4. Is the container sized properly?
5. Are styles imported?
6. Is useReactFlow used inside a provider?
7. Are interactive elements marked with nodrag?
8. Are types used consistently throughout?

Versions

The database has no other skills named react-flow-code-review.

Database snapshot: 13.11.2026 · package version bb2bc19d2ad2 (SHA-256 digest of the entire package)

Downloads in the last 30 days: 0 · ranking

Report a problem with this skill: harmful content, incorrect descriptions or an author’s removal request.

Similar skills

  • 95react-flow
    Expert guidance for React Flow (@xyflow/react): building interactive node-based graphs, custom nodes and edges, handles, state management, layouting, TypeScript patterns, performance optimization, accessibility, SSR, and theming. Use when writing React Flow code, creating custom…
  • 90react-flow-best-practices
    Best practices for writing, reviewing, and refactoring React Flow / @xyflow/react v12 canvases. Use when work touches React Flow components, custom nodes, custom edges, handles, node data typing, viewport controls, MiniMap/Background/Panel usage, NodeToolbar, NodeResizer, or…
  • 100react-flow-implementation
    Implements React Flow node-based UIs correctly using @xyflow/react. Use when building flow charts, diagrams, visual editors, or node-based applications with React. Covers nodes, edges, handles, custom components, state management, and viewport control.
  • 100code-review
    Reviews code for quality, best practices, and potential issues. Use when asked to review, audit, or check code for problems.
  • 100code-review
    Reviews code changes for bugs, style issues, security vulnerabilities, and best practices. Use when reviewing PRs, checking code quality, or validating implementations.
  • 100react-flow
    React Flow (@xyflow/react) for workflow visualization with custom nodes and edges. Use when building graph visualizations, creating custom workflow nodes, implementing edge labels, or controlling viewport. Triggers on ReactFlow, @xyflow/react, Handle, NodeProps, EdgeProps, useReactFlow, fitView.

Feedback and reports

Your message goes to Bartosz Sokoliński. An email address is needed only for a reply. See the privacy policy.