Engineering

Server-driven UI was already the answer. LLMs made it urgent.

Server-driven UI and generative UI are one idea arriving from two directions, and a decade of mobile practice already tells you which parts are hard.

VVoqal · Engineering10 min readPart of Render spec

About this article

Mobile teams have been shipping interfaces described by a server for about a decade. The practice has a name, a canon, several public postmortems, and a spot in the Trial ring of the Thoughtworks Technology Radar as recently as Volume 34, April 2026.

Generative UI arrived separately, from the web, with new vocabulary and no memory of any of that. The two are the same mechanism. Only the author of the description changed.

The two lineages, and why they are one idea#

Server-driven UI means the backend sends a structured description of a screen, and the client renders it from components it already ships. Generative UI means a model produces that description. The wire format, the versioning problem, the payload budget and the schema design are identical in both cases.

The upper rail spent a decade solving the client half. The lower rail arrived with a new author for the payload and rediscovered the same problems.

The practical consequence is that the useful literature for generative UI on native mobile is not the 2026 generative-UI writing. It is the 2021 server-driven-UI writing, where practitioners argued about costs in public.

What a decade of server-driven UI taught mobile teams#

The best single document is MobileNativeFoundation discussion #47, opened in March 2021, where engineers from Airbnb, Lyft, Molotov and Zalando compared systems under their own names. What follows is quoted from there, except where noted.

Airbnb: one schema, every client#

Airbnb’s Ghost Platform is the canonical implementation. Their own deep dive on the Airbnb engineering blog is the primary source, though it blocks automated fetching, so the architecture below is quoted from InfoQ’s July 2021 write-up and is InfoQ’s paraphrase rather than Airbnb’s wording. InfoQ describes three types: “sections, which are independent groups of related UI components”, “screens, which define where and how sections will appear”, and “actions, which are used to handle user interaction”, with a GraphQL schema “powerful enough to account for reusable sections, dynamic layouts, subpages, actions, and more”.

One schema, shared across web, iOS and Android. That sharing is the whole return on the investment, and it is also what makes the schema the most expensive artefact in the system.

Lyft: clients you cannot force to upgrade#

Lyft’s own account of why they moved names three motivations: “to deal with business complexity, to increase release velocity, to be more flexible in how we staff and build features.” The third one is rarely mentioned and is often the real driver, because a server-described screen can be changed by whoever owns the server rather than by whoever owns the app.

Kevin Fang of Lyft supplies the constraint that most surprises people coming from the web. “While driver clients are force-updated periodically every 3 months or so, we officially support rider/consumer clients up to 2 years old and have limited control over whether users ever update their apps.”

The two-year-old client constrains every schema change you make this week, which is why it cannot be scheduled away as legacy.

He also names the cost of not having a typed layer: “We don’t use GraphQL right now, so server-driven APIs are causing a rapid expansion in the API surface area between the server and client. The implications are: Backwards compatibility and versioning become more challenging.”

Spotify: the framework that got archived#

Spotify built the Hub Framework and then stopped. The repository README carries a section headed Deprecated, which reads: “The Hub Framework is being phased out at Spotify, and therefore we will not be maintaining it further.” GitHub archived the repository on 17 January 2019.

No public postmortem explains why, so nobody should claim to know. What the archive does establish is that a company with the engineering depth to build this decided the return did not hold, which is worth carrying into your own estimate.

Molotov: the team that walked it back#

Molotov.tv’s Android developer, posting as ilansas, is more specific about the reason. They kept server-driven UI on web, desktop and smart TV, and on mobile “we decided to move away from it as it complexifies a lot our code, we still keep some parts though, like buttons, texts which are variable from a dialog to another for example.”

That partial retreat is the most useful data point in the thread. What they landed on was a smaller surface: the parts that genuinely vary, and nothing else.

The costs nobody mentions first#

Three, and all three are in the discussion thread rather than in any vendor’s material.

The third mitigation is the one that is not an engineering task. Narrowing what the schema can express is a decision about what your product refuses to do.

Payload size comes first. Ryan Brooks of Airbnb, on their own system: “SDUI request (ours uses GraphQL) and response sizes can get massive, especially for complex screens/sections. We mitigate this through Operation registry (GraphQL), deferred responses (essentially pagination for UI on a screen), and some other clever tricks.”

Versioning comes second, and is the Lyft problem above.

Third is scope creep, and Zalando’s Vijaya Kandel frames it as the question to keep asking. His team builds a backend-driven UI framework, and his advice is to “find where your needs are on the parameterization range”, which is “effective guide for us to answer are we reinventing the web browser or providing OS tailored experience”. He poses it as an open question rather than a settled goal, which is the honest form. Every schema that grows an escape hatch is one step further along that range, and the end of the range is a browser you now maintain.

What changes when a model chooses the sections#

Two things get easier and one thing gets much harder.

Easier: the backend no longer needs business logic for which section to show. That logic was always the awkward part, because it encoded product judgment in a place product people could not see. A model choosing from a catalogue replaces a decision tree that someone had to maintain.

Also easier: the release-cycle argument gets sharper. Thoughtworks put it plainly in the Radar entry: “by separating rendering into a generic container while providing structure and data via the server, mobile teams can bypass lengthy app store review cycles for every iteration.” When the server is a model, the iteration can be a prompt change, which is faster still. Shipping interface changes without a release was always the strongest argument for this architecture and it survives the transition intact.

Harder: the thing filling your schema is now probabilistic. A backend that emits a malformed section has a bug you can fix once. A model that emits a malformed section has a distribution, and the fix is validation rather than a patch.

A widget configuration surface showing a catalogue grouped by purpose, a live preview of a stat widget, its trigger phrases, and an editable sample-data panel feeding the preview.
Editing the sample payload on the left redraws the preview on the right, with no build involved. The data shown is the surface's own sample set.

Why the schema gets more important#

If a backend team owns both ends of the contract, an under-specified schema is survivable, because the two sides can agree informally and fix mismatches in review. A model has not read your review comments. It has read your schema, and it will produce anything the schema permits.

This inverts the usual instinct. Teams adopting server-driven UI tend to make the schema permissive so they do not have to change it often. Teams whose schema is filled by a model should make it as restrictive as the product allows, because every field the schema does not have is a failure mode that cannot occur. The design of that contract is where most of the real arguments happen, and it deserves more care than the model selection does.

What to keep, and what to drop#

Keep the typed schema shared across platforms, because it is the reason the investment pays. Keep the tolerant client rules, unknown fields ignored and unknown kinds dropped, because the two-year-old client is real. Keep deferred delivery of sections, because response size is the cost that arrives without warning.

Drop the ambition to express everything. Molotov kept the parts that varied and dropped the rest, and that is the shape most teams should aim at from the start rather than arriving at after a rewrite. Drop the idea that a permissive schema is a kindness to your future self, because with a model on the other end it is the opposite. And drop the assumption that this is new: the whole architecture, from speech through tools to rendered views, has one genuinely novel layer, and the rendering layer is not it.

Common questions#

What is server-driven UI?#

Server-driven UI is an architecture where the backend sends a structured description of a screen, made of named sections and their data, and the mobile client renders that description using components compiled into the app. The client decides how a section looks. The server decides which sections appear and in what order.

How is server-driven UI different from generative UI?#

They differ in who writes the description. Server-driven UI has backend code produce it. Generative UI has a model produce it. The client contract, the versioning discipline and the payload budget are the same, which is why server-driven UI’s documented costs apply to generative UI without adjustment.

Can you ship UI changes without an App Store release?#

You can change which sections appear, their order and their content, because those come from the server. You cannot add a section type the app has never seen, because the rendering code for it is not in the binary. Thoughtworks describes the benefit as bypassing app store review for every iteration, which is accurate for the first kind of change and not the second.

Why did Spotify abandon its server-driven UI framework?#

The public record says only that it happened. The Hub Framework README states it was being phased out and would not be maintained further, and the repository was archived on 17 January 2019. No reasoning was published, so any explanation you read elsewhere is inference.

What are the downsides of server-driven UI?#

Response sizes grow quickly as sections multiply, backwards compatibility gets harder when clients stay in use for years, and the schema tends to widen until the team is maintaining something close to a browser. Practitioners at Airbnb, Lyft, Molotov and Zalando each named one of those in a single 2021 discussion.

Sources#

Filed underServer-driven UIRender specWidgetsTool design

Next

The catalogue of every widget kind the agent can ask your app to draw, and the payload each one takes.

See every widget kind the agent can render

The rest of Render spec

Open the cluster

Server-driven native UI: the agent names the widgets, your app draws them, and shipping a new answer shape stops requiring an app release.

Elsewhere on the map