Cortex

Fan-Out Diagram

An animated architecture diagram where one source feeds a hub that fans out to many nodes, each with a live status.

Your app sends work to Agent platform, which runs 7 nodes: Sandbox 1, Claude Code, running; Sandbox 2, Codex, running; Sandbox 3, Browser agent, running; Sandbox 4, Custom, starting; Sandbox 5, Data agent, running; Sandbox 6, Claude Code, running; Sandbox 7, Custom, stopped.Agent platformYour appSandbox 1Claude CoderunningSandbox 2CodexrunningSandbox 3Browser agentrunningSandbox 4CustomstartingSandbox 5Data agentrunningSandbox 6Claude CoderunningSandbox 7Customstopped

Installation

Cortexcn
pnpm dlx shadcn@latest add @cortexcn/fan-out-diagram

Usage

import { FanOutDiagram } from "@/components/fan-out-diagram";
import { AppWindow, Code, Terminal } from "lucide-react";
<FanOutDiagram
  title="Agent platform"
  source={{ label: "Your app", icon: <AppWindow /> }}
  nodes={[
    { label: "Sandbox 1", meta: "Claude Code", icon: <Terminal />, status: "running" },
    { label: "Sandbox 2", meta: "Codex", icon: <Code />, status: "starting" },
  ]}
/>

A source card sends work to the hub, and the hub fans out to one row per node. Use it for the architecture section of a landing page, such as one sandbox per customer, one worker per queue, or one agent per task.

Examples

Job queue

Three rows are enough for a small system. A row's statusLabel replaces the status name, so an error row can say "retrying".

Webhooks sends work to Job queue, which runs 3 nodes: Worker 1, invoices, running; Worker 2, emails, running; Worker 3, refunds, retrying.Job queueWebhooksWorker 1invoicesrunningWorker 2emailsrunningWorker 3refundsretrying

Static

With animated={false}, the diagram draws in its final state, with no reveal and no moving packets.

Your app sends work to Agent platform, which runs 7 nodes: Sandbox 1, Claude Code, running; Sandbox 2, Codex, running; Sandbox 3, Browser agent, running; Sandbox 4, Custom, starting; Sandbox 5, Data agent, running; Sandbox 6, Claude Code, running; Sandbox 7, Custom, stopped.Agent platformYour appSandbox 1Claude CoderunningSandbox 2CodexrunningSandbox 3Browser agentrunningSandbox 4CustomstartingSandbox 5Data agentrunningSandbox 6Claude CoderunningSandbox 7Customstopped

Behavior

  • The first time the diagram scrolls into view, the panel, source, hub, lines and rows draw in, in that order. Then packets travel from the source to the hub and out along each line.
  • Packets and the pulse on running rows only move while the diagram is on screen. With reduced motion enabled, the diagram shows its final state and nothing moves.
  • The layout grows with the rows: one row per node, and the hub stays centred on them.
  • It lays out left to right when its container is at least 36rem (576px) wide, and top to bottom below that: source on top, then the hub, then the rows. It follows its container, not the screen, so it also stacks inside a narrow column on a desktop.
  • Icons are drawn in a 24 by 24 box. Any Lucide icon works, and so does an SVG <image> for a logo.
  • Screen readers get one description of the whole diagram, built from the labels. Pass ariaLabel to write your own.

Props

FanOutDiagram

PropTypeDefaultDescription
titlestring-Label in the panel's top-left corner
titleIconReactNode-Icon before the title
source{ label: string; icon?: ReactNode }-The card that sends work in
hubIconReactNode-Icon in the hub at the centre
nodesFanOutNode[]-The rows the hub fans out to, top to bottom
animatedbooleantrueDraw in on view and send packets along the lines
ariaLabelstringBuiltDescription for screen readers
classNamestring-Extra classes for the wrapper

FanOutNode

PropTypeDefaultDescription
labelstring-The row's name
metastring-Secondary text after the label
iconReactNode-Icon in the row's tile
status"running" | "starting" | "stopped" | "error"-Colours the status dot
statusLabelstringThe statusText next to the dot

Inspired by the architecture diagram on the Agent 37 Cloud site.