Generative UI Finally Speaks Material UI
A small A2UI renderer shows the model-emits-data pattern maturing, and why the protocol matters more than the package.
Every generative-UI project eventually rediscovers the same rule: the model should never be allowed to write code, only to describe intent. HTML from an LLM is an XSS vector and a design-system violation in one payload. So the field has settled on a different shape — the model emits a constrained JSON description, and a renderer you control maps it onto components you already ship. Google's A2UI protocol formalized that idea; Vercel's json-render productized it with a shadcn catalog. What's been missing is the boring, necessary last mile for teams that don't use shadcn.
generative-mui is one attempt at that last mile for Material UI. It's a two-package MIT library from a solo developer, published to npm on July 20, 2026 as @yessglory/generative-mui-core and @yessglory/generative-mui-react (v1.0.1 the next day). An agent streams A2UI v0.9.1 messages as JSON Lines; the library validates them with Zod, reduces them into an immutable store, and renders real MUI components inside your existing <ThemeProvider>. The repo has 11 stars. That number matters for how you should use it — but the design is worth studying regardless.
The protocol is the product
The important decision here isn't MUI, it's A2UI. Google shipped A2UI v0.9 in April with a pointed reframing: the optional component set was renamed from "Standard" to "Basic" because, in their words, frontend developers don't want new components — they already have a design system. The protocol's job is to carry intent in a flat adjacency list (components referenced by id, not nested) with a separate data model bound by JSON-Pointer, so an agent can patch one component without resending the tree. Four message types cover everything: createSurface, updateComponents, updateDataModel, deleteSurface.
Google's repo (now at 16.2k stars, Apache-2.0) ships official React, Lit, Angular, and Flutter renderers. But the official @a2ui/react renders the Basic Catalog with its own bare components. If your app is MUI, you'd write the catalog-to-Typography/TextField/Dialog mapping yourself, and that mapping is exactly what generative-mui does: 18 Basic Catalog components one-to-one, plus an opt-in extended catalog of 16 more (LineChart, BarChart, Table, Stepper, Autocomplete, Gauge, and so on) backed by @mui/x-charts.
That positioning is the right one. The alternative — a bespoke JSON schema per library — is how you get fragmentation. If your agent speaks A2UI, swapping the MUI renderer for the Lit one, or for json-render's A2UI adapter, is a client-side change. The model prompt doesn't move.
What "safe by construction" actually buys
The security story is where this implementation is more careful than most tutorials on the topic:
- Unregistered component types never execute code; they degrade to a skeleton.
sx,style, andclassNameare stripped even if the model emits them, so pixels and palette come from the host theme only. Switch themes and generated surfaces re-skin with everything else.- The local
regexvalidation function caps pattern and input length (1,000 and 10,000 characters) because both come from an untrusted agent and JavaScript has no synchronous regex timeout. Most people don't think about ReDoS until an agent emits(a+)+$. - Cycles and over-deep graphs (the model will eventually reference
rootfrom a child) fall back to a placeholder instead of blowing the stack, and a per-node error boundary keeps one bad renderer from unmounting the surface.
The store is a pure reduce(state, message) function wired to useSyncExternalStore, so it runs on the server, on the edge, and in tests. The core ← react dependency direction is enforced by eslint-plugin-boundaries, not by convention.
Two-way binding is the feature that separates a "chatbot with cards" from an app. A TextField bound to {"path":"/name"} writes into the store locally via writeLocal(); a Button with a required check on that path disables itself until the field is filled, with no round-trip to the model. Actions (action.event) go back to your agent through a single onAction callback. That's the loop that makes a generated booking form behave like one you wrote.
How you'd actually wire it
The client side is small:
import { A2uiSurface, SurfaceStore, extendedRegistry } from '@yessglory/generative-mui-react'
const store = new SurfaceStore()
store.apply(jsonlChunkFromAgent) // call again as chunks stream in
<A2uiSurface source={store} registry={extendedRegistry} onAction={sendToAgent} />
The agent side is where the real work lives. The core package exports a2uiTools() / a2uiExtendedTools() — tool definitions whose parameters are the A2UI adjacency list schema — plus describeCatalog() and rule blocks for your system prompt, and an extractJson() that tolerates markdown fences when the model answers in prose anyway. It's provider-agnostic data, though the shipped examples are all Gemini (a Vite SPA, a Next.js route handler, and one that drops generated content into MUI's new @mui/x-chat shell, itself still in alpha).
Plan on owning the prompt. Constrained output is a floor, not a ceiling: the model can still emit a Column with forty children or bind every field to /. Few-shot examples of your catalog in use, and periodic compact() calls to garbage-collect ids that merge-by-id never deletes, are part of the job.
Trade-offs you're signing up for
Peer deps are narrow. @mui/material ^7, @mui/x-charts ^8 || ^9, React 18 or 19. If you're on MUI v5 or v6, this isn't for you until you migrate.
A2UI isn't done. v0.9.1 is the current stable line and Google has a v1.0 release candidate in the repo with "planned" status across all official renderers. A third-party renderer pinned to 0.9.1 will need a rewrite of its Zod schemas when 1.0 lands; the drift test locking the schemas to a vendored catalog.json will help, but someone has to do it.
Bus factor of one. Four days of commits, one maintainer, 11 stars, no version compatibility guarantees beyond what's in package.json. This is a reference implementation, not infrastructure.
Latency is real. Google's own research paper this year found humans overwhelmingly prefer generated UIs to markdown when ignoring speed, and generated results matched expert-built pages only about half the time. Streaming skeletons help, but a chart that takes eight seconds to arrive loses to a sentence that takes one.
Where this fits
Don't confuse it with MCP Apps. The Model Context Protocol extension that shipped in January solves a different problem: third-party servers delivering their own HTML into a sandboxed iframe inside Claude or ChatGPT. A2UI-plus-renderer is the first-party case — your agent, your app, your design system, no iframe. Hosted middleware like Thesys C1 sits in between, returning components from its own design system. None of those preserve years of investment in a MUI theme. A native renderer does.
My read: the architecture is the correct one, and the fact that a solo developer can build a credible A2UI-to-MUI mapping in a few weeks is the strongest evidence that the protocol did its job. Use generative-mui today to prototype the loop with your own catalog, read the source, and expect to either fork it or wait for MUI to ship something equivalent once A2UI 1.0 stabilizes. The bet on A2UI is safe. The bet on this specific package isn't yet — but that's a maintenance question, not a design one.
Sources & further reading
- generative-mui: A2UI renderer for Material UI — github.com
- @yessglory/generative-mui-react — npmjs.com
- A2UI v0.9: The New Standard for Portable, Framework-Agnostic Generative UI — developers.googleblog.com
- A2UI: Agent-to-User Interface protocol and renderers — github.com
- Google Releases A2UI v0.9: Portable, Framework-Agnostic Generative UI — infoq.com
- json-render: The Generative UI framework — github.com
- MCP Apps are here: Rendering interactive UIs in AI clients — workos.com
- Generative UI: LLMs are Effective UI Generators — arxiv.org
Rachel has been embedded in the developer tooling ecosystem for nearly eight years, covering everything from IDE wars and package-manager drama to the quiet rise of AI-assisted coding. She has a soft spot for open-source maintainers and an unhealthy number of terminal emulators installed on a single laptop.
Discussion 0
No comments yet
Be the first to weigh in.