Built-In Components
React Flow comes with several built-in components that can be passed as children to the <ReactFlow /> component.
import { ReactFlow, MiniMap, Controls, Background, Panel } from '@xyflow/react';
<ReactFlow>
<MiniMap />
<Controls />
<Background />
<Panel position="top-left">
<h1>My Flow</h1>
</Panel>
</ReactFlow>MiniMap
The MiniMap provides a bird’s-eye view of your flowgraph, making navigation easier, especially for larger flows. You can customize the appearance of nodes in the minimap by providing a nodeColor function.
Example: learn/mini-map
App.jsx
import { ReactFlow, MiniMap } from '@xyflow/react';
import '@xyflow/react/dist/style.css';
import { defaultNodes } from './nodes';
import { defaultEdges } from './edges';
const nodeColor = (node) => {
switch (node.type) {
case 'input':
return '#6ede87';
case 'output':
return '#6865A5';
default:
return '#ff0072';
}
};
function Flow() {
return (
<ReactFlow defaultNodes={defaultNodes} defaultEdges={defaultEdges} fitView colorMode="system">
<MiniMap nodeColor={nodeColor} nodeStrokeWidth={3} zoomable pannable />
</ReactFlow>
);
}
export default Flow;edges.js
export const defaultEdges = [
{ id: 'e1-2', source: '1', target: '2' },
{ id: 'e2-3', source: '2', target: '3', animated: true },
];index.css
html,
body {
margin: 0;
font-family: sans-serif;
}
#app {
width: 100vw;
height: 100vh;
}index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>React Flow Example</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="./index.jsx"></script>
</body>
</html>index.jsx
import { createRoot } from 'react-dom/client';
import App from './App';
import './index.css';
const container = document.querySelector('#app');
const root = createRoot(container);
root.render(<App />);nodes.jsx
export const defaultNodes = [
{
id: '1',
type: 'input',
data: { label: 'Input Node' },
position: { x: 250, y: 25 },
style: { backgroundColor: '#6ede87', color: 'white' },
},
{
id: '2',
// you can also pass a React component as a label
data: { label: <div>Default Node</div> },
position: { x: 100, y: 125 },
style: { backgroundColor: '#ff0072', color: 'white' },
},
{
id: '3',
type: 'output',
data: { label: 'Output Node' },
position: { x: 250, y: 250 },
style: { backgroundColor: '#6865A5', color: 'white' },
},
];Controls
React Flow comes with a set of customizable Controls for the viewport. You can zoom in and out, fit the viewport and toggle if the user can move, select and edit the nodes.
Example: learn/controls
App.jsx
import { ReactFlow, Controls } from '@xyflow/react';
import '@xyflow/react/dist/style.css';
import { defaultNodes } from './nodes';
import { defaultEdges } from './edges';
function Flow() {
return (
<ReactFlow defaultNodes={defaultNodes} defaultEdges={defaultEdges} fitView colorMode="system">
<Controls />
</ReactFlow>
);
}
export default Flow;edges.js
export const defaultEdges = [
{ id: 'e1-2', source: '1', target: '2' },
{ id: 'e2-3', source: '2', target: '3', animated: true },
];index.css
html,
body {
margin: 0;
font-family: sans-serif;
}
#app {
width: 100vw;
height: 100vh;
}index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>React Flow Example</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="./index.jsx"></script>
</body>
</html>index.jsx
import { createRoot } from 'react-dom/client';
import App from './App';
import './index.css';
const container = document.querySelector('#app');
const root = createRoot(container);
root.render(<App />);nodes.jsx
export const defaultNodes = [
{
id: '1',
type: 'input',
data: { label: 'Input Node' },
position: { x: 250, y: 25 },
},
{
id: '2',
// you can also pass a React component as a label
data: { label: <div>Default Node</div> },
position: { x: 100, y: 125 },
},
{
id: '3',
type: 'output',
data: { label: 'Output Node' },
position: { x: 250, y: 250 },
},
];Background
The Background component adds a visual grid pattern to your flowgraph, helping users maintain orientation. You can choose from different pattern variants, or if you need more advanced customization, you can explore the source code to implement your own pattern.
Example: learn/background
App.jsx
import { useState } from 'react';
import { ReactFlow, Background, Panel } from '@xyflow/react';
import '@xyflow/react/dist/style.css';
import { defaultNodes } from './nodes';
import { defaultEdges } from './edges';
function Flow() {
const [variant, setVariant] = useState('cross');
return (
<ReactFlow defaultNodes={defaultNodes} defaultEdges={defaultEdges} fitView colorMode="system">
<Background color="skyblue" variant={variant} />
<Panel>
<div>variant:</div>
<button onClick={() => setVariant('dots')}>dots</button>
<button onClick={() => setVariant('lines')}>lines</button>
<button onClick={() => setVariant('cross')}>cross</button>
</Panel>
</ReactFlow>
);
}
export default Flow;edges.jsx
export const defaultEdges = [
{ id: 'e1-2', source: '1', target: '2' },
{ id: 'e2-3', source: '2', target: '3', animated: true },
];index.css
html,
body {
margin: 0;
font-family: sans-serif;
}
#app {
width: 100vw;
height: 100vh;
}index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>React Flow Example</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="./index.jsx"></script>
</body>
</html>index.jsx
import { createRoot } from 'react-dom/client';
import App from './App';
import './index.css';
const container = document.querySelector('#app');
const root = createRoot(container);
root.render(<App />);nodes.jsx
export const defaultNodes = [
{
id: '1',
type: 'input',
data: { label: 'Input Node' },
position: { x: 250, y: 25 },
},
{
id: '2',
// you can also pass a React component as a label
data: { label: <div>Default Node</div> },
position: { x: 100, y: 125 },
},
{
id: '3',
type: 'output',
data: { label: 'Output Node' },
position: { x: 250, y: 250 },
},
];Panel
The Panel component allows you to add fixed overlays to your flowgraph, perfect for titles, controls, or any other UI elements that should remain stationary.
Example: learn/panel
App.jsx
import { ReactFlow, Background, Panel } from '@xyflow/react';
import '@xyflow/react/dist/style.css';
const nodes = [
{
id: '1',
data: { label: 'this is an example flow for the <Panel /> component' },
position: { x: 0, y: 0 },
},
];
function Flow() {
return (
<ReactFlow nodes={nodes} fitView colorMode="system">
<Panel position="top-left">top-left</Panel>
<Panel position="top-center">top-center</Panel>
<Panel position="top-right">top-right</Panel>
<Panel position="bottom-left">bottom-left</Panel>
<Panel position="bottom-center">bottom-center</Panel>
<Panel position="bottom-right">bottom-right</Panel>
<Panel position="center-left">center-left</Panel>
<Panel position="center-right">center-right</Panel>
<Background variant="cross" />
</ReactFlow>
);
}
export default Flow;index.css
html,
body {
margin: 0;
font-family: sans-serif;
}
#app {
width: 100vw;
height: 100vh;
}
.react-flow__panel {
padding: 5px 10px;
background: white;
box-shadow: rgba(0, 0, 0, 0.1) 0px 1px 3px 0px, rgba(0, 0, 0, 0.06) 0px 1px 2px 0px;
}index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>React Flow Example</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="./index.jsx"></script>
</body>
</html>index.jsx
import { createRoot } from 'react-dom/client';
import App from './App';
import './index.css';
const container = document.querySelector('#app');
const root = createRoot(container);
root.render(<App />);Advanced
For more advanced use cases and customization, we have even more built-in components you can check out in the API components overview