---
title: Why generative UI
description: The technical argument for letting an agent render interfaces instead of answering in prose — what generation buys, what the typed action payload tells you, and where generative UI is the wrong tool.
---

Your agent already works. The question this page answers is narrower: should it render an interface, or keep answering in text? The case for rendering is not that UI looks better. It is that a form returns a **typed payload** where prose returns a sentence you have to parse, and that generating the form costs you no frontend.

## The problem: prose round-trips

An agent that only speaks has one way to collect structured input — ask, read the reply, guess what the user meant, ask again. Every field is a turn, every turn is an LLM call, and the answer arrives as free text that nothing validated.

ggui replaces that loop with one exchange. The agent declares a contract; the user fills the interface; the gesture comes back as a validated payload. The server checks the submitted data against the contract's `actionSpec` before your agent ever sees it (see [How ggui works](/how-it-works/#3-interact--the-user-fills-the-ui)). Five prose turns collapse into one render and one drain.

## What generation buys

**One contract, many surfaces.** A render is an MCP-Apps resource (`ui://ggui/render/<id>`), not a page you deploy. The same contract mounts inline in Claude Desktop and claude.ai, in your own React web app through `<AppRenderer>`, and in React Native through `<McpAppIframe>` — see [React host helpers](/sdk/react/) and [React Native host helpers](/sdk/react-native/). You describe the data once; the surface is the host's problem.

**No frontend build.** There is no component to author, no route to add, no deploy to ship a screen your agent needed for the first time this morning. The generator takes the contract — `PropsSpec` + `ActionSpec` + `StreamSpec` + `ContextSpec` — and returns a compiled, contract-typed React module ([UI Generator](/architecture/ui-generator/)).

**Blueprint reuse makes repeat renders cheap.** ggui is blueprint-first: matching runs before generating. An exact canonical-key lookup is deterministic and calls no model at all; when that misses, a fast reranking model chooses among cached candidates, and only a miss on both falls through to a cold generation that then caches its own result. On a cache hit the render is served with **zero generation calls** ([generation pipeline](/architecture/overview/#generation-pipeline)). The more an app reuses contract shapes, the more of its traffic takes the matched path.

**Quality is measured, not asserted.** Generation quality runs nightly across a three-tier model matrix and is scored by a three-provider judge panel at temperature 0, with a pass threshold of 70 and the per-cell spread published alongside the mean. The methodology, the corpus, and how to reproduce a run are in [Benchmark methodology](/architecture/benchmarks/).

## What you learn

This is the part that is easy to undersell. Web analytics infers intent from behavior — clicks, scroll depth, funnel drop-off, a session replay you watch and interpret. A ggui action does not need interpreting, because the user's intent is the wire format.

Every gesture your agent drains from `ggui_consume` is a `ConsumeEventEntry`:

| Field        | What it tells you                                                                    |
| ------------ | ------------------------------------------------------------------------------------ |
| `intent`     | Which `actionSpec` entry the user fired — the named thing they chose to do           |
| `actionData` | The typed payload, already validated against `actionSpec[intent].schema`             |
| `uiContext`  | The contract's `contextSpec` slot values snapshotted at the instant of the gesture   |
| `actionId`   | An 8-hex correlation id matching the iframe's toast key and the server's `drain_ack` |
| `firedAt`    | ISO 8601 timestamp of the gesture, from the iframe                                   |

That is ground truth about what a person decided, not an inference about what they probably meant. It arrives in your agent's own loop, so you can act on it in the same turn — and store it, aggregate it, or feed it back into the next render however you like.

:::caution[Vision — not shipped]
There is no aggregate analytics surface in the ggui console today. The console gives you the per-app blueprint library, gadgets, keys, theme, marketplace, and a credits ledger with per-render charges — not funnels, cohorts, or an action-event explorer. If you want aggregates over gestures, collect the `ggui_consume` rows yourself. A first-party analytics view is a direction, not a product you can switch on.
:::

## The honest limits

- **Cold generation is not instant.** A render that misses the cache runs the generator and typically takes 10–20 s ([How ggui works](/how-it-works/#2-render--the-ui-gets-generated-or-matched)). A cache hit removes the generation call, which is a real cost saving — but as measured on the current warm path it does not yet buy you a proportional latency saving. Design the first render of a new shape as something the user is willing to wait a beat for.
- **The code was written by a model, and it runs in a sandbox.** Generated components mount in an iframe with `allow-scripts allow-forms` and deliberately without `allow-same-origin`, so the frame cannot read the embedding page; capabilities like camera or clipboard-write are granted only when the contract asked for them. Inside a third-party host, that host owns the sandbox and its CSP, and that surface is opaque to ggui. Read [Trust & security](/hosted/trust/) before you decide this is acceptable for your data.
- **Inline mounting depends on the host.** A host that does not advertise the MCP Apps capability still gets a working `ggui_render` — it just cannot mount the resource inline ([Connect other MCP hosts](/clients/connect-other-hosts/#things-every-host-needs)).
- **Generation is not deterministic.** Two cold generations of the same intent are not guaranteed to produce the same component. Determinism comes from the exact-key blueprint path, not from the model.

## When not to use it

Generative UI is the wrong tool when the interface itself is the product:

- **Brand-critical static surfaces.** Marketing pages, pricing tables, anything a designer signed off on pixel by pixel. Build those; ggui has nothing to add.
- **Pixel-exact or regulated flows.** If a screen must be byte-stable across renders — a legal disclosure, a certified checkout, a screen an auditor compares against a spec — you want a committed component, not a generated one.
- **One screen, used constantly, never varying.** If your agent renders the same shape a thousand times a day, the generation is pure overhead. Register that shape as a blueprint so the deterministic exact-key path serves it every time, or build it as a normal component and let your agent link to it.
- **No structured decision to collect.** If the user's next move really is a sentence, prose is the right interface. UI earns its place when there is a choice to make, a field to fill, or state to watch.

The test is simple: does the turn end with the user _deciding_ something? If yes, a render turns that decision into typed data. If no, keep talking.

## Next

- [How ggui works](/how-it-works/) — the five moments of an exchange, end to end.
- [Build an agent on hosted ggui](/quickstart/hosted-agent/) — the shortest path to a first render against `https://mcp.ggui.ai`.
- [Trust & security](/hosted/trust/) — what is stored, what reaches a model, and where the sandbox ends.