The layers don't have to be UI. Four plain planes, from your app down to the database, that stay open at the end. Each carries its name on its front edge, the strip that stays in view.
@keyframeui
registry/demos/exploded-ui-architecture-demo.tsx
"use client";
import * as React from "react";
import { cn } from "@/lib/utils";
import { ExplodedUI } from "@/components/ui/exploded-ui";
// Sized off the plane's width, so each plane scales like an image.
const screen =
"[--spacing:0.4cqw] [--text-xs:1.2cqw] [--text-sm:1.4cqw] [--text-base:1.6cqw] [--text-lg:1.9cqw] [--text-2xl:2.6cqw] [--radius-md:0.6cqw] [--radius-lg:0.8cqw] [--radius-xl:1.2cqw]";
// The planes don't have to be UI. Each tier carries its name on its front
// edge, the strip that stays in view once the stack is open.
export function ExplodedUIArchitectureDemo() {
const scrollRef = React.useRef<HTMLDivElement>(null);
return (
<div className="relative w-full overflow-hidden rounded-xl border border-zinc-200 bg-white text-zinc-950 dark:border-zinc-800 dark:bg-zinc-950 dark:text-zinc-50">
<div ref={scrollRef} className="relative h-[var(--demo-height,36rem)] overflow-y-auto overscroll-contain">
<header className="mx-auto max-w-2xl px-6 pt-16 pb-4 text-center sm:pt-20">
<p className="font-mono text-xs tracking-wide text-zinc-500 uppercase">How it works</p>
<h2 className="mt-3 text-3xl font-semibold tracking-tight text-balance sm:text-4xl">
One request, four layers, 40 milliseconds
</h2>
</header>
<ExplodedUI
walkthrough
end="exploded"
spread={0.15}
containerRef={scrollRef}
stageClassName="h-[var(--demo-height,36rem)]"
className={cn("aspect-[16/10] w-full max-w-2xl", screen)}
>
<ExplodedUI.Layer label="Database" description="Postgres with read replicas in three regions.">
<Database />
</ExplodedUI.Layer>
<ExplodedUI.Layer label="Edge network" description="Requests land at the nearest of 300 cities.">
<Edge />
</ExplodedUI.Layer>
<ExplodedUI.Layer label="SDK" description="Typed, retried and cached for you.">
<Sdk />
</ExplodedUI.Layer>
<ExplodedUI.Layer label="Your app" description="Calls one function. That's the whole integration.">
<App />
</ExplodedUI.Layer>
</ExplodedUI>
<section className="mx-auto max-w-xl px-6 py-16 text-center">
<p className="text-zinc-600 dark:text-zinc-400">
Read the <a href="#docs" className="font-medium text-zinc-950 underline decoration-zinc-300 underline-offset-4 dark:text-zinc-50 dark:decoration-zinc-700">architecture guide</a> for the details.
</p>
</section>
</div>
</div>
);
}
function Plane({
name,
meta,
className,
children,
}: {
name: string;
meta: string;
className?: string;
children: React.ReactNode;
}) {
return (
<div className={cn("relative flex size-full flex-col p-6 text-xs", className)}>
<div className="min-h-0 flex-1">{children}</div>
<div className="mt-4 flex items-baseline gap-3">
<span className="text-2xl font-semibold tracking-tight">{name}</span>
<span className="font-mono opacity-60">{meta}</span>
</div>
</div>
);
}
const rows = [
["usr_8f2a", "maya@northwind.io", "Team", "2m ago"],
["usr_31cd", "jonas@globex.com", "Pro", "14m ago"],
["usr_77be", "ada@initech.dev", "Team", "1h ago"],
["usr_02f9", "lin@umbrella.co", "Free", "3h ago"],
];
function Database() {
return (
<Plane
name="Database"
meta="postgres 16 · 3 replicas"
className="bg-emerald-50 text-emerald-950 dark:bg-emerald-950 dark:text-emerald-50"
>
<div className="overflow-hidden rounded-lg bg-white/70 font-mono ring-1 ring-emerald-900/10 dark:bg-emerald-900/30 dark:ring-emerald-100/10">
{rows.map((row, i) => (
<div
key={row[0]}
className={cn("grid grid-cols-[1fr_2fr_1fr_1fr] gap-4 px-4 py-2.5", i > 0 && "border-t border-emerald-900/10 dark:border-emerald-100/10")}
>
{row.map((cell) => (
<span key={cell} className="truncate">
{cell}
</span>
))}
</div>
))}
</div>
</Plane>
);
}
// Points of presence, as percentages of the map.
const pops = [
[18, 38],
[27, 62],
[47, 30],
[52, 46],
[63, 58],
[78, 36],
[84, 70],
];
function Edge() {
return (
<Plane
name="Edge network"
meta="300 cities · p50 12ms"
className="bg-indigo-50 text-indigo-950 dark:bg-indigo-950 dark:text-indigo-50"
>
<div className="relative size-full">
<svg viewBox="0 0 100 100" preserveAspectRatio="none" aria-hidden className="absolute inset-0 size-full overflow-visible">
{pops.map(([x, y], i) =>
i === 3 ? null : (
<path
key={i}
d={`M ${pops[3][0]} ${pops[3][1]} Q ${(pops[3][0] + x) / 2} ${Math.min(pops[3][1], y) - 18} ${x} ${y}`}
fill="none"
stroke="currentColor"
strokeOpacity="0.35"
strokeWidth="1.2"
strokeDasharray="2 3"
vectorEffect="non-scaling-stroke"
/>
),
)}
</svg>
{pops.map(([x, y]) => (
<span
key={`${x}-${y}`}
className="absolute size-3 -translate-1/2 rounded-full bg-indigo-500 ring-4 ring-indigo-500/20"
style={{ left: `${x}%`, top: `${y}%` }}
/>
))}
</div>
</Plane>
);
}
function Sdk() {
return (
<Plane name="SDK" meta="@acme/sdk · 9kb" className="bg-zinc-900 text-zinc-100">
<pre className="font-mono text-sm leading-relaxed">
<span className="text-fuchsia-300">import</span> {"{ createClient }"} <span className="text-fuchsia-300">from</span>{" "}
<span className="text-emerald-300">"@acme/sdk"</span>;{"\n\n"}
<span className="text-fuchsia-300">const</span> acme = <span className="text-sky-300">createClient</span>({"{ region: "}
<span className="text-emerald-300">"auto"</span>
{" }"});{"\n"}
<span className="text-fuchsia-300">const</span> user = <span className="text-fuchsia-300">await</span> acme.users.
<span className="text-sky-300">get</span>(id);
</pre>
</Plane>
);
}
const projects = [
{ name: "Storefront", status: "Ready", tone: "bg-emerald-500", when: "2m ago" },
{ name: "Admin", status: "Building", tone: "bg-amber-500", when: "just now" },
{ name: "Docs", status: "Ready", tone: "bg-emerald-500", when: "1h ago" },
{ name: "Marketing", status: "Ready", tone: "bg-emerald-500", when: "3h ago" },
{ name: "Mobile API", status: "Ready", tone: "bg-emerald-500", when: "1d ago" },
{ name: "Billing", status: "Queued", tone: "bg-zinc-400", when: "1d ago" },
];
function App() {
return (
<Plane name="Your app" meta="next.js · react" className="bg-white text-zinc-950 dark:bg-zinc-800 dark:text-zinc-50">
<div className="flex items-center gap-6 text-zinc-500 dark:text-zinc-400">
<span className="flex items-center gap-2 text-sm font-semibold text-zinc-950 dark:text-zinc-50">
<span className="size-5 rounded-md bg-zinc-950 dark:bg-white" />
Northwind
</span>
<span className="text-zinc-950 dark:text-zinc-50">Projects</span>
<span>Usage</span>
<span>Settings</span>
<span className="ml-auto size-7 rounded-full bg-linear-to-br from-amber-300 to-rose-400" />
</div>
<div className="mt-6 flex items-center justify-between">
<span className="text-lg font-semibold tracking-tight">Projects</span>
<span className="rounded-md bg-zinc-950 px-3 py-1.5 font-medium text-white dark:bg-white dark:text-zinc-950">
New project
</span>
</div>
<div className="mt-4 grid grid-cols-3 gap-3">
{projects.map((project) => (
<div key={project.name} className="rounded-lg bg-zinc-50 p-3 ring-1 ring-zinc-950/5 dark:bg-zinc-900 dark:ring-white/10">
<span className="mb-3 block h-12 rounded-md bg-linear-to-br from-zinc-200 to-zinc-100 dark:from-zinc-700 dark:to-zinc-800" />
<span className="font-medium">{project.name}</span>
<span className="mt-2 flex items-center gap-1.5 text-zinc-500 dark:text-zinc-400">
<span className={cn("size-1.5 rounded-full", project.tone)} />
{project.status} · {project.when}
</span>
</div>
))}
</div>
</Plane>
);
}
Live preview, examples and props: https://keyframeui.com/components/exploded-ui#exploded-ui-architecture-demo






















