Skip to content

ADR-0003: Studio is a Vite React SPA on Kumo; Astro only renders sites

Context

The initial plan proposed Astro + React islands for Studio with Kumo UI. Verified today: React context does not cross Astro islands (Kumo’s portal/toast/command-palette providers cannot be shared), children from .astro into React arrive as strings, and an interactive admin degenerates into one client:only island per page. Kumo is MIT, @cloudflare/kumo 2.14 on @base-ui/react 1.8, Tailwind 4, Phosphor; it ships a machine-readable component registry and CLI.

Decision

apps/studio is a Vite 8 + React 19 single-page app (TanStack Router + Query, Tailwind 4 via @tailwindcss/vite), served as static assets from a Worker next to the API. Kumo is the component layer, consumed only through packages/ui (@cloudhal/ui): Kumo components from npm, Kumo blocks copied in and owned, Cloudhal blocks (DiffViewer, SnapshotTimeline, PolicyBadge, AgentRunPanel, ApprovalDialog) built on top. Direct @base-ui/react imports are lint errors. Astro 7 is used only for astro-renderer (visitor sites) and apps/site (docs/marketing).

Alternatives considered

Alternative Pros Cons Why not
Astro + React islands One framework for everything Isolated React roots, string children, no shared providers Breaks Kumo’s compound components
TanStack Start (SSR) Server functions, streaming Heavier, moving fast, SSR of an authenticated admin adds little Revisit only if SSR becomes a requirement
shadcn/ui (Base UI style) instead of Kumo Code-owned, huge ecosystem No agent-facing registry/CLI; more assembly Kept as the fallback behind the @cloudhal/ui barrel

Consequences

  • Positive: one React root, providers everywhere, Kumo’s registry feeds the studio-ui skill.
  • Negative: Kumo 2.x deprecates things weekly; the barrel is mandatory to contain churn.
  • Risks: Kumo stalls → swap to shadcn behind the barrel; Base UI package rename already happened once (@base-ui-components/react is frozen; use @base-ui/react).