---
layout: ~/layouts/MdxDocLayout.astro
title: "Flow"
description: "A group of components for building directed flow diagrams with nodes and connectors."
sourceFile: "components/flow"
---

import ComponentExample from "~/components/docs/ComponentExample.astro";
import ComponentSection from "~/components/docs/ComponentSection.astro";
import CodeBlock from "~/components/docs/CodeBlock.astro";
import Heading from "~/components/docs/Heading.astro";
import {
  FlowBasicDemo,
  FlowParallelDemo,
  FlowCustomContentDemo,
  FlowComplexDemo,
  FlowAnchorDemo,
  FlowCenteredDemo,
  FlowPanningDemo,
  FlowDisabledDemo,
  FlowParallelAlignEndDemo,
  FlowParallelNestedListDemo,
  FlowSidebarBugDemo,
} from "~/components/demos/FlowDemo";

<ComponentSection>
  <ComponentExample
    code={`<Flow>
  <Flow.Node>Start</Flow.Node>
  <Flow.Parallel>
    <Flow.Node>Branch A</Flow.Node>
    <Flow.Node>Branch B</Flow.Node>
    <Flow.Node>Branch C</Flow.Node>
  </Flow.Parallel>
  <Flow.Node>End</Flow.Node>
</Flow>`}
  >
    <FlowParallelDemo client:visible />
  </ComponentExample>
</ComponentSection>

<ComponentSection>
  <Heading level={2}>Installation</Heading>
  <Heading level={3}>Barrel</Heading>
  <CodeBlock code={`import { Flow } from "@cloudflare/kumo";`} lang="tsx" />
  <Heading level={3}>Granular</Heading>
  <CodeBlock
    code={`import { Flow } from "@cloudflare/kumo/components/flow";`}
    lang="tsx"
  />
</ComponentSection>

<ComponentSection>
  <Heading level={2}>Usage</Heading>
  <p>
    The Flow components work together to create directed flow diagrams. Use
    `Flow` as the container,
    `Flow.Node` for individual
    steps, and
    `Flow.Parallel` to create
    branching paths.
  </p>
  <CodeBlock
    code={`import { Flow } from "@cloudflare/kumo";

export default function Example() {
  return (
    <Flow>
      <Flow.Node>Step 1</Flow.Node>
      <Flow.Node>Step 2</Flow.Node>
      <Flow.Node>Step 3</Flow.Node>
    </Flow>
  );
}`}
    lang="tsx"
  />
</ComponentSection>

<ComponentSection>
  <Heading level={2}>Examples</Heading>

<Heading level={3}>Sequential Flow</Heading>
<p>A simple linear flow with nodes connected in sequence.</p>
<ComponentExample
  code={`<Flow>
  <Flow.Node>Step 1</Flow.Node>
  <Flow.Node>Step 2</Flow.Node>
  <Flow.Node>Step 3</Flow.Node>
</Flow>`}
>
  <FlowBasicDemo client:visible />
</ComponentExample>

  <Heading level={3}>Parallel Branches</Heading>
  <p>
    Use `Flow.Parallel` to create branching paths that run in parallel.
  </p>
  <ComponentExample
    code={`<Flow>

  <Flow.Node>Start</Flow.Node>
  <Flow.Parallel>
    <Flow.Node>Branch A</Flow.Node>
    <Flow.Node>Branch B</Flow.Node>
    <Flow.Node>Branch C</Flow.Node>
  </Flow.Parallel>
  <Flow.Node>End</Flow.Node>
</Flow>`}
  >
    <FlowParallelDemo client:visible />
  </ComponentExample>

  <Heading level={3}>Custom Node Styling</Heading>
  <p>
    Use the
    `render` prop to
    completely customize node appearance. The render prop accepts a React element
    that will be used instead of the default styled node.
  </p>
  <ComponentExample
    code={`<Flow>

  <Flow.Node render={<li className="rounded-full size-4 bg-kumo-ring" />} />
  <Flow.Node
    render={
      <li className="bg-kumo-contrast text-kumo-inverse rounded-lg font-medium py-2 px-3">
        my-worker
      </li>
    }
  />
</Flow>`}
  >
    <FlowCustomContentDemo client:visible />
  </ComponentExample>

  <Heading level={3}>Centered Alignment</Heading>
  <p>
    Use the
    `align` prop to
    vertically center nodes. This is useful when nodes have different heights.
  </p>
  <ComponentExample
    code={`<Flow align="center">

  <Flow.Node render={<li className="rounded-full size-4 bg-kumo-ring" />} />
  <Flow.Node>my-worker</Flow.Node>
  <Flow.Node
    render={
      <li className="py-6 px-3 rounded-md shadow bg-kumo-base ring ring-kumo-line">
        Taller node
      </li>
    }
  />
</Flow>`}
  >
    <FlowCenteredDemo client:visible />
  </ComponentExample>

  <Heading level={3}>Complex Flow</Heading>
  <p>
    Combine sequential and parallel nodes to build complex workflows.
  </p>
  <ComponentExample
    code={`<Flow>

  <Flow.Node>Trigger</Flow.Node>
  <Flow.Parallel>
    <Flow.Node>Validate Input</Flow.Node>
    <Flow.Node>Check Cache</Flow.Node>
  </Flow.Parallel>
  <Flow.Node>Process Request</Flow.Node>
  <Flow.Parallel>
    <Flow.Node>Log Analytics</Flow.Node>
    <Flow.Node>Update Cache</Flow.Node>
    <Flow.Node>Send Notification</Flow.Node>
  </Flow.Parallel>
  <Flow.Node>Complete</Flow.Node>
</Flow>`}
  >
    <FlowComplexDemo client:visible />
  </ComponentExample>

  <Heading level={3}>Custom Anchor Points</Heading>
  <p>
    By default, connectors attach to the center of each node. Use
    `Flow.Anchor` with
    its `render` prop
    to specify custom attachment points. The `type` prop controls whether the anchor serves as a `"start"` point (where connectors leave) or `"end"` point (where connectors arrive).
  </p>
  <ComponentExample
    code={`<Flow>

  <Flow.Node>Load balancer</Flow.Node>
  <Flow.Node
    render={
      <li className="shadow-none rounded-lg ring ring-kumo-line bg-kumo-overlay">
        <Flow.Anchor
          type="end"
          render={
            <div className="text-kumo-subtle h-10 flex items-center px-2.5">
              my-worker
            </div>
          }
        />
        <Flow.Anchor
          type="start"
          render={
            <div className="bg-kumo-base rounded ring ring-kumo-line shadow px-2 py-1.5 m-1.5 mt-0">
              Bindings
              <span className="text-kumo-subtle w-5 ml-3">2</span>
            </div>
          }
        />
      </li>
    }
  />
  <Flow.Parallel>
    <Flow.Node>DATABASE</Flow.Node>
    <Flow.Node>OTHER_SERVICE</Flow.Node>
  </Flow.Parallel>
</Flow>`}
  >
    <FlowAnchorDemo client:visible />
  </ComponentExample>

  <Heading level={3}>Panning Large Diagrams</Heading>
  <p>
    When a diagram exceeds its container, Flow automatically enables
    panning. Drag to pan the viewport, or use the scroll wheel. Scrollbars
    appear on hover to indicate available scroll area.
  </p>
  <ComponentExample
    code={`<Flow>

  <Flow.Node>Start</Flow.Node>
  <Flow.Node>Authenticate</Flow.Node>
  <Flow.Node>Validate</Flow.Node>
  <Flow.Node>Transform</Flow.Node>
  <Flow.Node>Process</Flow.Node>
  <Flow.Node>Store</Flow.Node>
  <Flow.Node>Notify</Flow.Node>
  <Flow.Node>Log</Flow.Node>
  <Flow.Node>Complete</Flow.Node>
  <Flow.Node>End</Flow.Node>
</Flow>`}
  >
    <FlowPanningDemo client:visible />
  </ComponentExample>

  <Heading level={3}>Disabled Nodes</Heading>
  <p>
    Use the
    `disabled` prop
    on a node to visually indicate it's inactive. Connectors linking to disabled
    nodes are rendered with reduced opacity.
  </p>
  <ComponentExample
    code={`<Flow>

  <Flow.Node>Request</Flow.Node>
  <Flow.Parallel>
    <Flow.Node>Primary Handler</Flow.Node>
    <Flow.Node disabled>Backup Handler (disabled)</Flow.Node>
  </Flow.Parallel>
  <Flow.Node>Response</Flow.Node>
</Flow>`}
  >
    <FlowDisabledDemo client:visible />
  </ComponentExample>

  <Heading level={3}>Parallel Node Alignment</Heading>
  <p>
    Use the
    `align` prop on
    `Flow.Parallel`
    to control how nodes with different widths are aligned. Use
    `"start"`
    (default) to align left, or
    `"end"` to align
    right.
  </p>
  <ComponentExample
    code={`<Flow>

  <Flow.Node>Start</Flow.Node>
  <Flow.Parallel align="end">
    <Flow.Node>Short</Flow.Node>
    <Flow.Node>Medium Length</Flow.Node>
    <Flow.Node>Very Long Node Name</Flow.Node>
  </Flow.Parallel>
  <Flow.Node>End</Flow.Node>
</Flow>`}
  >
    <FlowParallelAlignEndDemo client:visible />
  </ComponentExample>
</ComponentSection>

<ComponentSection>
  <Heading level={2}>Known Issue: Sidebar / Layout Shift</Heading>
  <p>
    Toggling the sidebar shifts the Flow container's viewport position. Because
    connector coordinates are computed from stale `getBoundingClientRect` values
    stored in state (captured before the layout shift), the connector lines jump
    out of alignment until the next remeasure is triggered. Scroll the page
    while the sidebar is open to hit the same bug via the scroll path.
  </p>
  <ComponentExample
    code={`// Toggle the sidebar — connectors misalign on open/close
<FlowSidebarBugDemo />`}
  >
    <FlowSidebarBugDemo client:visible />
  </ComponentExample>
</ComponentSection>

<ComponentSection>
  <Heading level={2}>Other Examples</Heading>

  <Heading level={3}>Nested Node Lists in Parallel</Heading>
  <p>
    Use
    `Flow.List`
    inside
    `Flow.Parallel`
    to create parallel branches where each branch contains a sequence of connected
    nodes.
  </p>
  <ComponentExample
    code={`<Flow>
  <Flow.Parallel>
    <Flow.List>
      <Flow.Node>Client Users</Flow.Node>
      <Flow.Node>Engineering Team Access</Flow.Node>
    </Flow.List>
    <Flow.List>
      <Flow.Parallel>
        <Flow.Node>All Authenticated Users</Flow.Node>
        <Flow.Node>Client Users</Flow.Node>
        <Flow.Node>Site Users</Flow.Node>
      </Flow.Parallel>
      <Flow.Node>Contractor Access</Flow.Node>
    </Flow.List>
  </Flow.Parallel>
  <Flow.Node>Destinations</Flow.Node>
</Flow>`}
  >
    <FlowParallelNestedListDemo client:visible />
  </ComponentExample>
</ComponentSection>

<ComponentSection>
  <Heading level={2}>Components</Heading>

<Heading level={3}>Flow</Heading>
<p>
  The root container for flow diagrams. Provides panning and scrolling for large
  diagrams.
</p>
<div class="overflow-x-auto">
  <table class="w-full">
    <thead>
      <tr class="border-b border-kumo-line">
        <th class="px-4 py-3 text-left font-semibold">Prop</th>
        <th class="px-4 py-3 text-left font-semibold">Type</th>
        <th class="px-4 py-3 text-left font-semibold">Description</th>
      </tr>
    </thead>
    <tbody class="text-kumo-strong">
      <tr class="border-b border-kumo-line">
        <td class="px-4 py-3 font-mono">align</td>
        <td class="px-4 py-3 font-mono">"start" | "center"</td>
        <td class="px-4 py-3">
          Vertical alignment of nodes. `"start"` (default) aligns to top,
          `"center"` vertically centers nodes.
        </td>
      </tr>
      <tr class="border-b border-kumo-line">
        <td class="px-4 py-3 font-mono">className</td>
        <td class="px-4 py-3 font-mono">string</td>
        <td class="px-4 py-3">Additional CSS classes for the container</td>
      </tr>
      <tr class="border-b border-kumo-line">
        <td class="px-4 py-3 font-mono">children</td>
        <td class="px-4 py-3 font-mono">ReactNode</td>
        <td class="px-4 py-3">Flow.Node and Flow.Parallel components</td>
      </tr>
    </tbody>
  </table>
</div>

<Heading level={3}>Flow.Node</Heading>
<p>
  A single node in the flow diagram. Renders as a styled card with automatic
  connector points. Use the `render` prop to customize the element.
</p>
<div class="overflow-x-auto">
  <table class="w-full">
    <thead>
      <tr class="border-b border-kumo-line">
        <th class="px-4 py-3 text-left font-semibold">Prop</th>
        <th class="px-4 py-3 text-left font-semibold">Type</th>
        <th class="px-4 py-3 text-left font-semibold">Description</th>
      </tr>
    </thead>
    <tbody class="text-kumo-strong">
      <tr class="border-b border-kumo-line">
        <td class="px-4 py-3 font-mono">render</td>
        <td class="px-4 py-3 font-mono">ReactElement</td>
        <td class="px-4 py-3">
          Custom element to render instead of the default styled node
        </td>
      </tr>
      <tr class="border-b border-kumo-line">
        <td class="px-4 py-3 font-mono">disabled</td>
        <td class="px-4 py-3 font-mono">boolean</td>
        <td class="px-4 py-3">
          When true, connectors linking to this node are rendered with reduced
          opacity
        </td>
      </tr>
      <tr class="border-b border-kumo-line">
        <td class="px-4 py-3 font-mono">children</td>
        <td class="px-4 py-3 font-mono">ReactNode</td>
        <td class="px-4 py-3">Content to display inside the node</td>
      </tr>
    </tbody>
  </table>
</div>

<Heading level={3}>Flow.Anchor</Heading>
<p>
  A component that marks a custom attachment point for connectors within a
  Flow.Node. Use this to control exactly where connector lines attach instead of
  the default node center by providing a custom element via the `render` prop.
</p>
<div class="overflow-x-auto">
  <table class="w-full">
    <thead>
      <tr class="border-b border-kumo-line">
        <th class="px-4 py-3 text-left font-semibold">Prop</th>
        <th class="px-4 py-3 text-left font-semibold">Type</th>
        <th class="px-4 py-3 text-left font-semibold">Description</th>
      </tr>
    </thead>
    <tbody class="text-kumo-strong">
      <tr class="border-b border-kumo-line">
        <td class="px-4 py-3 font-mono">type</td>
        <td class="px-4 py-3 font-mono">"start" | "end"</td>
        <td class="px-4 py-3">
          Whether this anchor serves as a "start" point (outgoing connectors) or
          "end" point (incoming connectors). When omitted, serves as both.
        </td>
      </tr>
      <tr class="border-b border-kumo-line">
        <td class="px-4 py-3 font-mono">render</td>
        <td class="px-4 py-3 font-mono">ReactElement</td>
        <td class="px-4 py-3">Custom element to render for the anchor point</td>
      </tr>
      <tr class="border-b border-kumo-line">
        <td class="px-4 py-3 font-mono">children</td>
        <td class="px-4 py-3 font-mono">ReactNode</td>
        <td class="px-4 py-3">Content to render at the anchor point</td>
      </tr>
    </tbody>
  </table>
</div>

<Heading level={3}>Flow.Parallel</Heading>
<p>
  A container for parallel branches. Child Flow.Node components are displayed in
  parallel with junction connectors.
</p>
<div class="overflow-x-auto">
  <table class="w-full">
    <thead>
      <tr class="border-b border-kumo-line">
        <th class="px-4 py-3 text-left font-semibold">Prop</th>
        <th class="px-4 py-3 text-left font-semibold">Type</th>
        <th class="px-4 py-3 text-left font-semibold">Description</th>
      </tr>
    </thead>
    <tbody class="text-kumo-strong">
      <tr class="border-b border-kumo-line">
        <td class="px-4 py-3 font-mono">align</td>
        <td class="px-4 py-3 font-mono">"start" | "end"</td>
        <td class="px-4 py-3">
          Controls horizontal alignment of nodes within the parallel group.
          `"start"` (default) aligns left, `"end"` aligns right.
        </td>
      </tr>
      <tr class="border-b border-kumo-line">
        <td class="px-4 py-3 font-mono">children</td>
        <td class="px-4 py-3 font-mono">ReactNode</td>
        <td class="px-4 py-3">
          Flow.Node or Flow.List components to display in parallel
        </td>
      </tr>
    </tbody>
  </table>
</div>

  <Heading level={3}>Flow.List</Heading>
  <p>
    A container for a sequence of Flow.Node components with automatic
    connectors between them. Use inside Flow.Parallel to create branches
    with multiple sequential steps.
  </p>
  <div class="overflow-x-auto">
    <table class="w-full">
      <thead>
        <tr class="border-b border-kumo-line">
          <th class="px-4 py-3 text-left font-semibold">Prop</th>
          <th class="px-4 py-3 text-left font-semibold">Type</th>
          <th class="px-4 py-3 text-left font-semibold">Description</th>
        </tr>
      </thead>
      <tbody class="text-kumo-strong">
        <tr class="border-b border-kumo-line">
          <td class="px-4 py-3 font-mono">children</td>
          <td class="px-4 py-3 font-mono">ReactNode</td>
          <td class="px-4 py-3">Flow.Node components to display in sequence</td>
        </tr>
      </tbody>
    </table>
  </div>
</ComponentSection>
