An architecture exploration where the server decides what the UI renders and the client just draws it.
Server-Driven UI (SDUI)
1. What is Server-Driven UI?
Server-Driven UI (SDUI) is an architecture where the server decides what UI should be displayed, while the client application mainly acts as a renderer.
In a traditional application, the client contains most of the screen structure:
Client code
↓
"Show banner"
"Show product list"
"If user is logged in → show X"
↓
Rendered UI
With SDUI, the server can return a description of the UI:
{
"screen": "home",
"components": [
{
"type": "banner",
"title": "50% OFF"
},
{
"type": "product_list",
"items": ["Pizza", "Burger", "Biryani"]
}
]
}
The client already knows how to render banner and product_list, but
the server controls which components appear and in what order.
2. High-Level Architecture
flowchart LR
U[User] --> C[Mobile / Web Client]
C -->|Request screen| API[Backend / SDUI API]
API --> B[Business Logic]
API --> S[UI Schema / Screen Definition]
B --> D[(Database)]
S -->|JSON UI description| API
API -->|Screen schema| C
C --> R[Component Registry]
R --> V[Native UI Components]
V --> U
The basic flow
User opens app
|
v
Client asks server for screen
|
v
Server determines:
- which components
- their order
- content
- configuration
- available actions
|
v
Server returns UI schema / JSON
|
v
Client parses schema
|
v
Component Registry finds matching component
|
v
Native UI is rendered
The important idea is:
The server sends instructions about WHAT to render; the client owns HOW each supported component is rendered.
3. Traditional UI vs SDUI
Traditional client-driven UI
┌───────────────┐
│ Backend │
│ │
│ Data + APIs │
└───────┬───────┘
│
│ data
v
┌───────────────┐
│ Client │
│ │
│ Screen logic │
│ UI logic │
│ Experiments │
└───────┬───────┘
│
v
UI
The client decides the structure of the screen.
If the company wants to change the screen significantly, client code may need to change and the application may need a new release.
Server-Driven UI
┌────────────────────┐
│ Backend │
│ │
│ Business logic │
│ UI decisions │
│ Experiments │
│ Screen definition │
└─────────┬──────────┘
│
UI Schema / JSON
│
v
┌────────────────────┐
│ Client │
│ │
│ Schema parser │
│ Component registry │
│ Renderer │
└─────────┬──────────┘
│
v
UI
The server decides the composition of the screen, while the client provides the reusable building blocks.
4. Key Components of an SDUI System
4.1 UI Schema
The schema is the contract between the server and client.
Example:
{
"type": "screen",
"id": "home",
"children": [
{
"type": "banner",
"title": "20% off today"
},
{
"type": "carousel",
"items": ["item1", "item2", "item3"]
},
{
"type": "button",
"label": "Order Now",
"action": "open_orders"
}
]
}
The schema tells the client:
- What components exist
- Their hierarchy
- Their properties
- Their ordering
- Available actions
- Sometimes layout information
- Sometimes visibility rules
4.2 Component Registry
The client maintains a registry mapping server component types to native components.
Conceptually:
"banner" → BannerComponent
"carousel" → CarouselComponent
"button" → ButtonComponent
"product_list" → ProductListComponent
The server cannot magically create arbitrary UI.
It can only request components that the client already understands.
This is a very important limitation of SDUI.
4.3 Renderer
The renderer walks through the schema and converts it into actual UI.
Conceptually:
JSON
↓
Parse
↓
Find component type
↓
Look up Component Registry
↓
Create native component
↓
Render
For example:
{
"type": "button",
"label": "Order Now"
}
becomes:
Button(
text = "Order Now"
)
4.4 Actions / Events
UI components usually need to interact with the backend.
For example:
{
"type": "button",
"label": "Order Now",
"action": {
"type": "navigate",
"destination": "/orders"
}
}
Another example:
{
"type": "button",
"label": "Apply Coupon",
"action": {
"type": "api",
"endpoint": "/coupon/apply"
}
}
A mature SDUI system therefore needs an action/event model, not just a component model.
4.5 Schema Versioning
This is one of the most important production concerns.
Suppose:
Server supports:
banner
carousel
product_list
new_fancy_component
But an old mobile application only understands:
banner
carousel
product_list
The server cannot safely send new_fancy_component to that old client.
Therefore SDUI systems often need:
- Schema versions
- Component versions
- Client capability information
- Backward-compatible fallbacks
Example:
Client v5
↓
"I understand:"
banner
carousel
product_list
Server
↓
Only sends compatible components
5. What Problem Does SDUI Solve?
The main problem is slow UI iteration across multiple clients.
Imagine a company has:
iOS
Android
Web
and wants to change:
Home Screen
↓
Banner
↓
Product carousel
↓
Recommendation list
With a traditional architecture, UI behavior is often implemented separately on multiple clients.
A product change can require:
Design
↓
iOS development
↓
Android development
↓
Web development
↓
Testing
↓
App releases
↓
Users update
SDUI changes the workflow:
Design / Product decision
↓
Backend changes UI configuration
↓
Server returns new schema
↓
Existing clients render it
This can significantly shorten the feedback loop for UI changes that fit within the existing component vocabulary.
6. Why Companies Use SDUI
6.1 Faster experimentation
A company can change:
Banner A
to:
Banner B
or change the ordering:
Banner
Products
Recommendations
to:
Recommendations
Banner
Products
without necessarily shipping new client code.
This is particularly useful for:
- A/B testing
- Promotions
- Personalization
- Regional experiences
- Feature rollouts
- Dynamic onboarding
- Checkout/payment flows
6.2 Multiple platforms
Without SDUI:
Backend
|
+---- iOS implementation
|
+---- Android implementation
|
+---- Web implementation
With SDUI:
Backend
|
UI Schema
/ | \
/ | \
iOS Android Web
| | |
Renderer Renderer Renderer
The UI schema can provide a common description while each platform still renders using its own native components.
6.3 Centralized business/UI decisions
For some flows, the server knows information that the client shouldn't have to independently calculate.
For example:
User
|
+-- country = India
+-- payment method = UPI
+-- account = eligible
+-- experiment = B
|
v
Backend
|
v
Return appropriate payment UI
The client doesn't need to reproduce all of those business rules.
7. Example: Swiggy-style Dynamic Home Screen
A food-delivery application is a natural SDUI use case because the home screen can change frequently.
For example:
Server
|
| User = Sagar
| Location = Bangalore
| Time = Dinner
| Experiment = B
|
v
UI Schema
|
+--> Location header
|
+--> Promotional banner
|
+--> "20 min delivery" carousel
|
+--> Restaurant list
|
+--> Recommendations
|
v
Mobile Client
|
v
Rendered Home Screen
Swiggy has publicly described a Dynamic Widget / server-driven UI system, where backend responses can control dynamic widgets and their presentation.
The important architectural idea is that the server can compose a screen from a set of known widgets instead of requiring every screen change to be implemented entirely inside the client.
8. Companies That Have Used or Documented Similar Approaches
The exact implementation differs between companies; SDUI is not one standardized technology.
Swiggy
Swiggy has publicly written about its Dynamic Widget / Server-Driven UI system.
The approach is aimed at dynamically composing UI widgets and allowing product changes to be controlled through backend-driven responses.
Reference:
Airbnb
Airbnb has publicly documented server-driven experiences, including its authentication system.
In its current authentication architecture, the server determines which authentication challenge/screen should be shown and the client renders the returned screen. Airbnb states that this reduced client code and allowed many experiments to be run without requiring client changes.
Airbnb reported a 60% reduction in code for this authentication system and a 100 KB reduction in the web client bundle.
Source:
DoorDash
DoorDash has publicly discussed its Mosaic framework and server-driven UI patterns, particularly for internal/support tooling.
The broader pattern is the same: reusable client components are combined according to backend-controlled configuration.
Lyft
Lyft has also publicly discussed server-driven UI approaches, including its Canvas framework, to enable faster UI experimentation and iteration.
Nubank
Nubank has publicly discussed Backend Driven Content, including using server-controlled content/configuration with Flutter components.
Important distinction
Not every company above necessarily uses SDUI for its entire application.
A company might use server-driven UI for only:
Authentication
Checkout
Home screen
Promotional widgets
Payments
Onboarding
Internal tools
This is often more practical than making every part of the application server-driven.
9. SDUI Is NOT the Same as a WebView
This is a common misconception.
WebView
Server
|
v
HTML / CSS / JS
|
v
WebView
The application essentially embeds a web page.
SDUI
Server
|
v
UI Schema
|
v
Native Component Registry
|
v
Native UI
For example:
"button"
↓
Native iOS Button
or:
"button"
↓
Native Android Button
The server describes the UI, but the client still renders it using its own component system.
10. Advantages
10.1 Faster UI releases
Many changes can happen server-side without waiting for a full client release.
10.2 Faster A/B testing
The backend can return different UI trees:
Experiment A
Banner
Products
Recommendations
versus:
Experiment B
Recommendations
Banner
Products
The client doesn't necessarily need separate hardcoded implementations for every experiment.
10.3 Cross-platform consistency
The same high-level UI schema can drive:
iOS
Android
Web
while each platform maintains native rendering.
10.4 Centralized business logic
Business decisions can stay closer to backend systems.
This avoids duplicating complex rules across:
iOS code
Android code
Web code
10.5 Smaller client logic
The client can become more focused on:
Parse
↓
Validate
↓
Render
↓
Send actions
rather than containing large amounts of screen orchestration logic.
11. Disadvantages
11.1 Increased backend complexity
You haven't eliminated complexity.
You moved some of it.
Instead of:
Complex client
+
Simple API
you may end up with:
Simpler client
+
Complex SDUI backend
+
Schema system
+
Renderer
+
Versioning
+
Fallbacks
+
Observability
11.2 Network dependency
Traditional UI can often render known screens immediately.
With SDUI:
Open screen
↓
Request schema
↓
Wait for server
↓
Render
Poor connectivity can therefore become a UX problem.
Caching and local fallbacks become important.
11.3 Debugging becomes harder
A UI bug might involve:
Backend
↓
Schema
↓
Network
↓
Client parser
↓
Component registry
↓
Native component
Instead of simply:
Client code → UI
This increases the debugging surface.
11.4 Schema compatibility
Old clients may not understand new components.
Example:
Server:
"new_card"
Old client:
❌ doesn't know "new_card"
Therefore teams need:
- Schema versioning
- Capability negotiation
- Graceful fallback
- Backward compatibility
- Controlled rollout
11.5 Payload size
If the server sends a large UI tree on every request:
Huge JSON
↓
Network cost
↓
Parsing cost
↓
Rendering cost
Caching, compression, incremental updates, and careful schema design become important.
11.6 Not everything should be server-driven
Some UI is inherently client-heavy.
Examples:
Camera
Maps
Complex animations
Games
Video playback
Offline-first workflows
Highly interactive editors
For these, pushing too much control to the server can make the architecture unnecessarily complicated.