# How to build generative UI

> Building generative UI means wiring three parts together: a current picture of the visit, a rule or model that decides what to show, and a renderer that draws the chosen components. The decision is only as good as the state behind it.

_Last updated 2026-10-24. From The Generative UI Guide, https://generativeui.guide_

A generated interface has three parts. Build them in this order and each one has a clear job.

## 1. State: a current picture of the visit

State is what the decision reads: pages seen in the last few minutes, the last action and
how long ago, items viewed, a search that returned nothing, a basket left idle. It has to be
current to the last few seconds and available to read on the request, before the page
renders.

This is usually the hard part. Batch data, a segment computed overnight, describes who the
visitor was yesterday, not what they are doing now. Building generative UI on batch state
produces a layout for the wrong person. Teams either build a low-latency store for session
state themselves or use a tool made for it.
[Snowplow Signals](https://signals.snowplow.io/learning/generative-ui) is one such tool: it
computes attributes from behavioral events as they happen and serves them to the application
in a few milliseconds. Whatever you use, the requirement is the same: the state has to be
fresh and fast to read.

## 2. Decision: choosing what to render

Something has to turn the state into a choice of components. There are three common ways,
in rough order of flexibility:

- **Rules.** Code maps state to components. Predictable, easy to test, and every new case is
  a new rule to write.
- **A model choosing from a catalog.** A model reads the state and returns a specification
  naming components you built. It handles cases no one wrote a rule for, and the output stays
  inside your catalog.
- **An agent.** A model reasons over the context on each request and returns the layout. An
  agent with no grounding guesses; given a current, structured picture of the visit, it can
  compose a screen that fits. The interesting work is less the model than the context you
  feed it.

Most teams start with rules and move parts of the decision to a model as the cases multiply.

## 3. Render: drawing the chosen components

The decision produces a description of the screen. A renderer turns that into the interface,
using components the client already ships.

[json-render](https://github.com/vercel/json-render), a library from Vercel, is a common
choice. You describe a catalog of your own components and their props. A model returns a JSON
specification that references only those components, and json-render draws the result. The
model never writes markup, so the page cannot contain anything you did not ship.

json-render is one of several ways to move a decision to a screen, and the wider set sorts
into three layers. A declarative payload describes the interface as data for the client to
draw: json-render, Google's A2UI, and Thesys's OpenUI Lang all take this shape. A transport
carries that payload, and the events around it, between an agent and the front end; AG-UI is
the common one. And for an interface that has to appear inside someone else's assistant, MCP
Apps ships a sandboxed component the host renders. Most customer-facing generative UI needs
only the first layer, a catalog and a renderer. The others matter when the interface lives
inside an agent or another company's product.

One reason the catalog approach dominates for real customers is that it inherits the qualities
of the components it draws from. If your components are accessible and on brand, every
generated screen is too, because the model only arranges them. An interface built from
model-written markup has no such guarantee; each screen is new code that nobody reviewed. That
is the practical case for constraining the output to a catalog, beyond security.

The split matters: json-render draws, it does not decide. Something upstream still chooses
what goes in the specification, and that choice is only as good as the state behind it.

## Putting it together

A typical request flows through all three parts:

1. The server reads the current state for the visit.
2. A rule, a model, or an agent turns that state into a specification of components.
3. The renderer draws the specification into the screen the visitor sees.

Two practical limits hold the whole thing together. The decision has to return within the
request, so the state read and the decision step both have to be fast. And the output has to
stay inside the components the client can render, so a typed contract or a fixed catalog
keeps the decision honest. Get those two right and the rest is tuning the rules and the data
that drive generation.
