Microfrontend UI

A teaching surface for shell-and-remote architectures. A host frame renders N slots — one per mounted microfrontend — and each slot reports its own idle / loading / ready / error state. Pass the apps in, drive the states from a parent timeline, and you get an animation-friendly board for module-federation lessons, deploy-isolation demos, or any "many apps, one frame" narrative.

The component ships the shell only. It does not own scenario timing, an event log, deploy buttons, or any of the source lesson chrome — those concerns belong in the parent.

Preview

Host shell

1/3 ready
Headerreact
ready
Catalogvue
loading
Cartsvelte
idle
Customize

Installation

npx shadcn@latest add https://craftbits.dev/r/microfrontend-ui.json

Usage

import { MicrofrontendUI } from "@craft-bits/core";
 
<MicrofrontendUI
  apps={[
    { id: "header", label: "Header", framework: "react" },
    { id: "catalog", label: "Catalog", framework: "vue" },
    { id: "cart", label: "Cart", framework: "svelte" },
  ]}
  loadStates={{
    header: "ready",
    catalog: "loading",
    cart: "idle",
  }}
/>

Drive the slots from a parent timeline:

const [states, setStates] = useState({ header: "idle", catalog: "idle" });
 
<MicrofrontendUI
  apps={[
    { id: "header", label: "Header", framework: "react" },
    { id: "catalog", label: "Catalog", framework: "vue" },
  ]}
  loadStates={states}
/>

Anatomy

  • Host shell — a <section> linked to its visible title via aria-labelledby. A header row shows the title and a polite live n / total ready counter.
  • Slot grid — 1, 2, or 3 columns at md+. Scales with apps.length unless columns is set explicitly.
  • Slot — a card per mounted app. Left-edge accent reflects state, top row shows the app name and an optional framework tag pill, status row pairs a pulsing dot with a text label. An optional render per app injects body content.

Props

PropTypeDefaultDescription
appsMicrofrontendApp[]requiredOrdered mounted apps. Must contain at least one.
loadStatesRecord<string, MicrofrontendLoadState>{}Per-app load state keyed by app.id. Missing entries default to idle.
titleReactNode"Host shell"Visible heading above the slot grid.
columns1 | 2 | 3scales with apps.lengthSlot grid columns at md+.
classNamestringMerged onto the root via cn().

MicrofrontendApp

FieldTypeDescription
idstringStable identifier — slot key and loadStates key.
labelReactNodeApp name shown at the top of the slot.
frameworkstringOptional framework tag pill.
render(args) => ReactNodeOptional body override. Receives the slot's load state.

MicrofrontendLoadState

"idle" | "loading" | "ready" | "error"

Accessibility

  • The shell is a <section> linked to its visible title via aria-labelledby.
  • The n / total ready counter and per-slot status text live in aria-live="polite" regions so transitions are announced.
  • Color is never the sole signal — every state has a text label (idle, loading, ready, error).
  • The loading-pulse animation short-circuits to a static dot under prefers-reduced-motion.

Credits

  • Extracted from: terminal-dreams (src/components/frontend-design/sdp-microfrontend/ui/MicrofrontendUI.tsx). The original was a bundle of four lesson widgets — PredictionChallenge, RemoteFrameContainer, HostShellDashboard, LogConsole — wired through a MicrofrontendLab context. This primitive keeps the shell-and-slot viz and pushes prediction quizzes, dashboard counters, and event logs back to general-purpose primitives.