# Circuit: Integrations Hub

> Your product in the middle of a 3×3 grid of integrations, the flow built from arrays with a packet color per tool. `highlight="neighbors"` lights only a tile's own trace, and the tiles lift on hover: the traces follow them.

A shadcn/ui block from the [@keyframeui](https://keyframeui.com) registry, listed on [shadcn.exchange](https://shadcn.exchange/r/keyframeui/circuit-hub-demo).

- Page, with a live preview: https://shadcn.exchange/r/keyframeui/circuit-hub-demo
- Screenshot: https://abzjhwgwpdpz7ua5.public.blob.vercel-storage.com/shots/keyframeui/circuit-hub-demo-light-3f9ac4f4c693016c.png
- Registry item: https://keyframeui.com/r/circuit-hub-demo.json
- Categories: diagram, svg, interaction, landing
- Listed: 2026-10-15, source last changed 2026-10-15

## Install

```bash
npx shadcn@latest add https://keyframeui.com/r/circuit-hub-demo.json
```

Run it in a project that has shadcn/ui set up. It adds the files below and installs what they depend on.

## Dependencies

- Registry items: `https://keyframeui.com/r/circuit.json`

## Notes from the registry

Live preview, examples and props: https://keyframeui.com/components/circuit#circuit-hub-demo

## Files

### `registry/demos/circuit-hub-demo.tsx`

```tsx
"use client";

import { Circuit } from "@/components/ui/circuit";

// A 3×3 grid with your product in the middle. Inputs and outputs sit around it,
// each with its own packet color.
const TILES = [
  { id: "github", label: "GitHub", tone: "#a1a1aa" },
  { id: "sentry", label: "Sentry", tone: "#f472b6" },
  { id: "figma", label: "Figma", tone: "#fb923c" },
  { id: "linear", label: "Linear", tone: "#818cf8" },
  null,
  { id: "slack", label: "Slack", tone: "#facc15" },
  { id: "stripe", label: "Stripe", tone: "#a78bfa" },
  { id: "email", label: "Email", tone: "#38bdf8" },
  { id: "notion", label: "Notion", tone: "#a1a1aa" },
];

const INPUTS = ["github", "sentry", "figma", "linear", "stripe"];
const OUTPUTS = ["slack", "email", "notion"];

const tile =
  "flex flex-col items-center justify-center gap-2 rounded-2xl border border-zinc-200 bg-white p-3 text-xs font-medium text-zinc-700 transition-[opacity,transform,border-color] duration-300 hover:-translate-y-0.5 dark:border-zinc-800 dark:bg-zinc-900 dark:text-zinc-300 data-[circuit-state=dimmed]:opacity-40 data-circuit-pulse:border-zinc-400 dark:data-circuit-pulse:border-zinc-600";

export function CircuitHubDemo() {
  const tone = (id: string) => TILES.find((t) => t?.id === id)?.tone;

  return (
    <div className="@container w-full max-w-xl">
      <Circuit
        highlight="neighbors"
        interval={3.2}
        flow={[
          ...INPUTS.map((id) => ({ from: id, to: "hub", color: tone(id) })),
          ...OUTPUTS.map((id) => ({ from: "hub", to: id, color: tone(id) })),
        ]}
        className="grid grid-cols-3 gap-x-8 gap-y-7 @md:gap-x-14 @md:gap-y-10"
      >
        {TILES.map((t) =>
          t ? (
            <div key={t.id} data-circuit={t.id} className={`${tile} aspect-[4/3]`}>
              <span className="size-6 rounded-lg" style={{ background: `color-mix(in oklab, ${t.tone} 22%, transparent)`, boxShadow: `inset 0 0 0 1px color-mix(in oklab, ${t.tone} 45%, transparent)` }} />
              {t.label}
            </div>
          ) : (
            <div
              key="hub"
              data-circuit="hub"
              className="flex aspect-[4/3] flex-col items-center justify-center gap-1 rounded-2xl bg-zinc-900 p-3 text-center text-white shadow-lg transition-shadow duration-300 dark:bg-white dark:text-zinc-900 data-circuit-pulse:shadow-[0_0_0_6px_rgb(161_161_170/0.25)]"
            >
              <span className="text-sm font-semibold tracking-tight">Relay</span>
              <span className="font-mono text-[10px] opacity-60">your app</span>
            </div>
          ),
        )}
      </Circuit>
    </div>
  );
}
```
