Dezen Technology
All articles
ArchitectureMar 30, 20268 min read

Server-driven UI: the case for shipping less

Server-driven UI moves ‘what to show’ into deploy-fast server code. The wins, the tradeoffs you give up deliberately, and the hybrid split we actually ship.

Server-driven UI: the case for shipping less

For two years, the loudest pattern in mobile and SaaS development has been “client owns the UI, server is just JSON.” A lot of teams shipped that way, ourselves included. And a lot of those same teams are now quietly walking portions of it back.

Server-driven UI — where the server tells the client what to render, not just what data to render — isn’t a step backwards. It’s an honest re-evaluation of where complexity should live. Here’s when we use it, when we don’t, and what we’ve learned.

Client SPA owns UI vs server-driven UI — comparison of what changes when product evolves

What “server-driven” actually means

Not server rendering. Not server actions. Server-driven UI means the server returns a structured description of the screen — a tree of UI nodes referencing client-side primitives — and the client interprets it. The client knows how to render a list, a card, a button, an input. The server decides which of those to put on the screen and in what order.

Examples in the wild: Airbnb’s mobile apps (Ghost Platform), Spotify (HubFrame), Lyft (Server Driven UI), Shopify (the new Polaris-on-the-wire). It’s the same pattern at different scales.

Why teams reach for it

1. Mobile release cycles are slow

If a screen lives in client code, changing it means an app store submission — a week minimum. If a screen lives in server-returned JSON, changing it is a deploy — minutes. For products iterating fast, that’s the entire game.

2. Multi-platform consistency

When iOS, Android and web all consume the same screen description, you get UI parity for free. No three implementations of the same screen drifting apart over six months.

3. A/B testing at the layout level

Want to test “CTA at the top” vs “CTA after benefits”? In client-owned UI, that’s a feature flag in client code. In server-driven UI, it’s a different layout the server returns. The experiment lives where experiments belong — on the server.

Where it falls down

1. Animation and interaction

A server can describe a layout. It can’t describe a spring animation, a gesture-driven swipe, a parallax effect, or a 60fps transition. Those still live in the client. So your server-driven UI ends up being “static parts on the server, delightful parts in the client” — which is fine, but you need to be explicit about where the line is.

2. Tooling regresses

Hot reload, type checking, design-system autocomplete, debug tooling — all of them assume the UI lives in client code. Server-driven UI gives that up. You can rebuild the equivalent (live preview servers, a type system for your UI schema), but it’s real work and not on by default.

3. Versioning is hard

A user with an old app version doesn’t have the new UI primitive you just added. The server has to know what primitives the client supports and degrade gracefully. This is solvable but it’s a permanent tax on every UI feature you ship.

The middle path: hybrid, by surface

Our default isn’t all-or-nothing. We split the app by surface:

  • Server-driven: home feeds, search results, settings screens, marketing-ish surfaces that change copy and structure frequently.
  • Client-driven: editor surfaces, animations, gesture-heavy flows, anything where the UX has its own opinionated rhythm.

That gives you the iterate-fast benefit where it matters, and keeps the polish budget where it matters. Both worlds, on purpose.

A minimal schema that scales

{
  "screen": "home",
  "blocks": [
    { "type": "header", "title": "Welcome back" },
    { "type": "card_list", "source": "/feed/recent" },
    {
      "type": "cta",
      "label": "Add a sample",
      "style": "primary",
      "action": { "type": "navigate", "to": "/samples/new" }
    }
  ]
}

Every type maps to a primitive in the client. Every action maps to a known client capability (navigate, open modal, submit form, deeplink). That’s the entire contract.

How we approach this

For the mobile work we ship via UI/UX Design and our product engineering practice, we default to client-driven for V1 (fastest iteration), then introduce a server-driven layer for the surfaces that need to evolve weekly. Don’t over-engineer it from the start; let the product’s iteration speed pull the architecture.

Takeaways

  • Server-driven UI is a way to move “what to show” into the server, where deploys are fast.
  • You give up animation, tooling, and easy versioning — deliberately.
  • The right split is hybrid: server-driven for high-iteration surfaces, client for the polish.
  • Keep the schema small and the action vocabulary closed. Otherwise it grows into a worse React.
Keep reading

More from the engine room

AI in QA: where it helps, where it doesn’t

May 27, 2026

AI in QA: where it helps, where it doesn’t

AI augments QA throughput — test generation, triage, visual regression. It doesn’t replace QA judgment: strategy, exploratory testing, and defining correctness stay human.

Read More
Controlling LLM costs in production

May 25, 2026

Controlling LLM costs in production

Four levers cut spend 10x without cutting quality: route by difficulty, cache, trim context, batch and stream. Measure cost-per-feature first; set budget guardrails always.

Read More
RAG vs fine-tuning: which do you actually need?

May 23, 2026

RAG vs fine-tuning: which do you actually need?

Facts → RAG. Behavior → maybe fine-tune. Most business AI features want RAG even when teams ask for fine-tuning. The decision rule and the order to try things in.

Read More
Agentic features in SaaS: the maturity ladder

May 21, 2026

Agentic features in SaaS: the maturity ladder

From manual to autonomous — four levels of autonomy and the guardrails each needs. Match autonomy to the cost of being wrong, not to how impressive it sounds.

Read More
Offline-first mobile: the app that works on the subway

May 19, 2026

Offline-first mobile: the app that works on the subway

The UI never waits on the network. Local DB, sync engine, server — with conflict resolution per data type. The architecture that makes mobile apps feel instant.

Read More
Lift-and-shift vs refactor: how to actually decide

May 17, 2026

Lift-and-shift vs refactor: how to actually decide

Lift-and-shift is fast, cheap to do, expensive to keep. Refactor is months of work with structural upside. The matrix — and why half-finished refactors are the worst path.

Read More
Monolith migration: the strangler-fig playbook

May 15, 2026

Monolith migration: the strangler-fig playbook

The big-bang rewrite is the most consistently bad idea in software. Proxy in front, extract one route at a time, shrink the monolith to nothing. No migration day.

Read More
SOC 2 readiness in plain English

May 13, 2026

SOC 2 readiness in plain English

Five Trust Service Criteria, Security mandatory and the rest optional. Type 1 vs Type 2. The pragmatic 6-month timeline — not the year-long ordeal it’s made out to be.

Read More

Let’s Build the Future Together!

Contact our team today and turn your ideas into reality.

Let’s Discuss
Contact Details : sales@dezentech.com Sy. No:40, Flat No:402, SIRISAMPADHA ARCADE I, Plot no:18-21, behind Union Bank of India, Khajaguda, Hyderabad, Telangana 500104