SDUI vs Compose Multiplatform: Solving Different Problems in Mobile Development

Compose Multiplatform shares your UI code across platforms. Server-driven UI lets you update that UI without app store releases. They're not alternatives — they're complementary layers. Here's how they fit together, and when you need one, the other, or both.

📋 In This Article

  1. The Confusion: Why People Compare Them
  2. What Compose Multiplatform Actually Solves
  3. What Server-Driven UI Actually Solves
  4. The Gap CMP Doesn't Close
  5. Using SDUI and CMP Together
  6. SDUI Rendered Through CMP: The Tradeoffs
  7. Why Native SDUI Renderers Still Win
  8. Which Do You Need?

The Confusion: Why People Compare Them

If you search "Compose Multiplatform vs server-driven UI," you'll find surprisingly little. That's because most people haven't realized they're asking the wrong question. The real question isn't which one — it's which layer.

Compose Multiplatform (CMP) answers: "How do I write my UI once and run it on Android, iOS, and desktop?"

Server-Driven UI (SDUI) answers: "How do I change my UI after users have already installed the app — without going through the app store?"

These are fundamentally different problems. But they sound similar because both involve "sharing UI" and "reducing work." That surface-level similarity creates confusion, especially when teams are evaluating their mobile architecture. We covered the SDUI vs cross-platform question broadly before — this article goes deep on the CMP-specific nuances.

What Compose Multiplatform Actually Solves

JetBrains' Compose Multiplatform extends Jetpack Compose to iOS, desktop, and web. If you already write Compose for Android, you can share 80-90% of your UI code across platforms. That's a real win:

CMP has matured significantly. As of 2026, production apps ship with shared Compose UI on both platforms. Basic components (text, buttons, lists, images), Material 3 theming, animations, and resource management all work well. It's a legitimate alternative to Flutter for teams already invested in Kotlin.

CMP's sweet spot: Business apps with forms, lists, detail screens, and dashboards — where the core UI is "boring" in the best way. If your app is 80% standard patterns, CMP can share nearly all of it.

What CMP Doesn't Change

Here's what stays exactly the same with Compose Multiplatform:

CMP reduces development cost. It does not reduce release friction. This distinction matters enormously.

What Server-Driven UI Actually Solves

Server-driven UI solves a completely different problem: the app store bottleneck. Your backend sends a description of what the UI should look like, and the app renders it. Change the backend response, the UI changes — no release, no review, no update lag.

SDUI doesn't care how your app renders components. It cares that the server decides which components appear, in what order, with what data. The rendering layer — whether native Compose, SwiftUI, CMP, or Flutter — is an implementation detail.

SDUI's sweet spot: Screens that change frequently (home feeds, onboarding, promotional pages), teams that need rapid iteration, and apps where release velocity is a competitive advantage.

The Gap CMP Doesn't Close

Here's the scenario that trips teams up: You adopt Compose Multiplatform. Development speed improves. You're writing features once. Life is good.

Then your marketing team asks: "Can we change the homepage banner for a flash sale?"

Answer with CMP alone: No. You need to change the code, compile, submit to both stores, wait for review, wait for users to update. The banner change ships in 3-7 days. The sale is over.

Or your PM says: "We want to test two different onboarding flows to see which converts better."

Answer with CMP alone: Build both flows, add feature flags, compile, submit, wait. The feature flag approach works but ships dead code, grows complexity, and still requires a release for every new variant.

CMP solves the "write once" problem. It doesn't solve the "deploy instantly" problem. That's the gap.

Capability CMP Alone SDUI Alone CMP + SDUI
Share UI code across platforms
Update UI without app release
A/B test layouts server-side
Personalize screens per user ⚠️ Feature flags
Reduce development cost ⚠️ Per-platform renderers
Reduce release risk
Fix UI bugs instantly
Native platform performance ⚠️ Skia (non-native) ✅ Native renderers ⚠️ Depends on renderer

Using SDUI and CMP Together

The most interesting architecture is the combined one. Use CMP for your static screens — settings, profile, complex workflows that change rarely and benefit from shared code. Use SDUI for your dynamic screens — home feeds, promotions, onboarding, anything that needs server-side control.

Mobile App Architecture
Settings
CMP Shared Code
Profile
CMP Shared Code
Home Feed
Server-Driven
Onboarding
Server-Driven
Component Registry
Renders both CMP and SDUI screens
Native Compose (Android)
Native SwiftUI (iOS)

In this model, your component library is the shared foundation. Whether a screen is statically defined in your CMP codebase or dynamically composed by the server, it uses the same set of components. The SDUI architecture patterns guide covers this in depth.

The Component Bridge Pattern

Here's how it works in practice. You define your design system components in CMP's shared code. Then your SDUI layer maps server responses to those same components:

commonMain/components/ProductCard.kt
@Composable
fun ProductCard(
    title: String,
    price: String,
    imageUrl: String,
    badge: String? = null,
    onTap: () -> Unit = {}
) {
    // This component works in CMP shared code
    // AND in your SDUI component registry
    Card(
        modifier = Modifier.clickable { onTap() }
    ) {
        AsyncImage(model = imageUrl, contentDescription = title)
        Column(modifier = Modifier.padding(12.dp)) {
            badge?.let {
                Badge(text = it)
            }
            Text(text = title, style = MaterialTheme.typography.titleMedium)
            Text(text = price, style = MaterialTheme.typography.bodyLarge)
        }
    }
}
SDUI component registry mapping
// Your SDUI registry maps "ProductCard" to the same Composable
val registry = ComponentRegistry {
    register("ProductCard") { props ->
        ProductCard(
            title = props.getString("title"),
            price = props.getString("price"),
            imageUrl = props.getString("imageUrl"),
            badge = props.getStringOrNull("badge"),
            onTap = props.getAction("onTap")
        )
    }
}

Now ProductCard can appear in a statically-defined CMP screen (hardcoded in your Kotlin code) or in a server-driven layout. Same component, same rendering, same design fidelity. The only difference is who decides it should appear — your code or your server.

SDUI Rendered Through CMP: The Tradeoffs

Some newer tools (like sdui.design) take a different approach: they build SDUI renderers on top of Compose Multiplatform. The server sends a JSON layout, and a CMP-based renderer draws it on all platforms through Skia.

This has clear appeal:

But there are significant tradeoffs:

Skia vs Native Rendering

CMP renders through Skia on iOS — it paints pixels directly rather than using native UIKit/SwiftUI components. This means:

The Irony of CMP-Based SDUI

Here's the subtle irony: one of CMP's limitations is that it still requires app store releases. SDUI exists to solve that exact limitation. Building SDUI on CMP means your dynamic layer inherits CMP's non-native rendering tradeoffs — the very tradeoffs that native SDUI avoids.

You're using a cross-platform abstraction (CMP) to power a server-driven abstraction (SDUI) to avoid the limitations of... cross-platform development. It works, but it's two levels of indirection where one might suffice.

Why Native SDUI Renderers Still Win

Companies like Airbnb, Lyft, and Netflix all built their SDUI systems with native platform renderers — not cross-platform ones. There are good reasons:

The argument against native renderers is "you have to build two." That's true. But the SDUI renderer is a one-time infrastructure cost, and the typed DSL backend is already shared — you write the screen layout once, and both native renderers display it.

Pyramid's approach: Native renderers (Jetpack Compose for Android, SwiftUI for iOS) with a shared typed DSL backend. You write screen layouts in Kotlin — not JSON — with full IDE autocomplete. The same layout renders through native components on both platforms. Try the demo →

Which Do You Need?

You Need CMP (Not SDUI) If:

You Need SDUI (Not CMP) If:

You Need Both If:

Most mature mobile teams eventually need some form of SDUI, regardless of whether they use CMP. The question is how much of your app surface area should be server-driven. The SDUI readiness assessment can help you figure out where you fall.

Don't adopt CMP instead of SDUI to solve release problems. CMP solves the build once problem, not the deploy instantly problem. If your bottleneck is app store releases, SDUI is the answer — whether your app is native, CMP, Flutter, or React Native.

The Future: Convergence

The Kotlin ecosystem is headed toward convergence. Compose Multiplatform will continue improving iOS fidelity. SDUI tools will get better at cross-platform component sharing. The teams that win will use both strategically — CMP for development speed, SDUI for deployment speed.

The complete SDUI framework comparison covers every option in the market today, including native and CMP-based approaches. And the build vs. buy calculator can help you estimate whether you should build your own SDUI layer or adopt a platform.

Native SDUI That Works With Your Stack

Pyramid renders through native Compose and SwiftUI — not cross-platform abstractions. Your components, your design system, your performance. Backend devs compose screens in a typed Kotlin DSL with full IDE support.

Related Articles