The screenshots of generative UI are taken after the model stops. By then the chart has a title, the number has settled, and the filter sits where the layout expected it. That frame is the easy version of the product. The version a person actually watches is the stretch before it, when those pieces were still arriving and one of them was already wrong.

I have shipped views that looked correct in the final payload and clumsy on the way there. A card waited for every prop, so the useful number sat behind a skeleton. A chart remounted each time the model restated it, so the bar grew from zero again. A late filter pushed the paragraph someone was reading down the page. The model had done its job. The component had been designed against a mock of the ending.

The caller is still writing

A component on an ordinary screen can assume its props arrive together. Title, series, filters, the sentence for an empty result. A generative component has a caller that composes those props in public. First a title. Then a pause. Then a series with one point. Then a revision of the number the person has already read. Then a filter the model decided it needed after the chart was on screen.

A component that refuses to paint until the object is complete makes the person watch a placeholder through the only stretch that was interesting. A component that paints every intermediate object as final lets a figure change underneath them with no sign that the model is still working. Both come from the same assumption: that a render means the answer is done.

Arrival

First paint

  • Revenuepartial
  • By regionslot held

Revision

  • Revenuerevising
  • By regionpartial

Still open

  • Revenuesettled
  • By regionsettled
  • Notepartial
The same answer, three moments. Settled parts stay put. The note is still being written.

Give every part an identity

Models restate. A stream that rebuilds the whole tree produces a new chart element on every pass, and the renderer treats it as a new chart. Focus drops. The entrance animation runs again. A number someone was comparing flickers back through its arrival.

The contract I want is small. Each part has an id the model must keep. A revision updates that id. A new id is a new part. Removing an id is a decision, and it should be rare once a person could have read the part. The component keys on the id, so a restatement is an update and the screen stays where they left it.

ts
type Part = {
  id: string;
  kind: "metric" | "chart" | "filter" | "note";
  status: "partial" | "revising" | "settled";
  props: unknown;
};

The kind is a closed set. An open kind is how a model invents a one-off card in the middle of a sentence. Status is how the component knows whether the props in hand are allowed to look finished.

Mark what is still moving

Partial, revising, and settled are different facts, and the part should look like the fact it is in. Partial can show the digits it has, with a quiet mark that more may come. Revising means someone may already have trusted the previous value, so the change has to read as a change: the prior figure held for a moment, the new one marked until the model closes the part. Settled means the mark leaves and the type takes its normal weight.

The mark belongs on the part. One chart can be settled while the note beside it is still being written. A single spinner across the card collapses those facts into one wait. Interrupted is its own ending: what arrived stays readable, and the screen says the rest will not come.

Layout for a length you do not know

The component cannot know how many parts are coming, or which one the model will regret. Reserve the slot when the id first appears, even if the props are still thin. A chart with a title and no series yet should already occupy the chart's place, so the series can fill it without moving the note above it.

Arrival down the page keeps a map a person can hold. The order of ids is the order of the answer. Once a part has settled, a later sentence does not get to move it upward because the composition would look tidier. They have already learned where things are. A rearrangement after that is a jump in the middle of reading.

Review it while it is slow

I review these components against a payload that arrives one part at a time. Include a revision of a number already on screen, a stop halfway through, and a filter that shows up after the chart. A mock of the finished JSON approves a static component and a loading state. The product is the gap between them.

Real time here is the sequence the component has agreed to render honestly. Props that can be thin. An id that survives a restatement. A status a person can see. A layout that keeps its word about where a part will stay.