---
id: mobile-compose-multiplatform-deep
title: Compose Multiplatform — iOS / Android / Desktop / Web
category: Coding
status: draft
source_trust_level: B
verification_status: conceptual
created_at: 2026-05-09
updated_at: 2026-05-09
tags: [mobile, kmp, compose, vibe-coding]
tech_stack: { language: "Kotlin", applicable_to: ["iOS", "Android"] }
applied_in: []
aliases: [Compose Multiplatform, CMP, JetBrains, KMP UI, cross-platform Compose]
---

# Compose Multiplatform Deep

> Kotlin 의 cross-platform UI. **iOS + Android + Desktop + Web 가 같은 code**. JetBrains official.

## 📖 핵심 개념
- Compose UI 가 cross-platform.
- iOS 가 Skia render.
- Android 가 native.
- Desktop / Web (canvas).

## 💻 코드 패턴

### Setup
```kotlin
// composeApp/build.gradle.kts
kotlin {
    androidTarget()
    iosX64()
    iosArm64()
    iosSimulatorArm64()
    
    sourceSets {
        commonMain.dependencies {
            implementation(compose.runtime)
            implementation(compose.foundation)
            implementation(compose.material3)
        }
    }
}
```

### Common UI
```kotlin
// commonMain/App.kt
@Composable
fun App() {
    var count by remember { mutableStateOf(0) }
    
    MaterialTheme {
        Column(modifier = Modifier.fillMaxSize().padding(16.dp)) {
            Text("Count: $count", style = MaterialTheme.typography.headlineMedium)
            Button(onClick = { count++ }) {
                Text("+")
            }
        }
    }
}
```

→ iOS / Android / Desktop 가 같은 code.

### iOS entry
```swift
// iosApp/iOSApp.swift
import SwiftUI
import composeApp

@main
struct iOSApp: App {
    var body: some Scene {
        WindowGroup {
            ComposeView()
        }
    }
}

struct ComposeView: UIViewControllerRepresentable {
    func makeUIViewController(context: Context) -> UIViewController {
        Main_iosKt.MainViewController()
    }
    
    func updateUIViewController(_ uiViewController: UIViewController, context: Context) {}
}
```

### Android entry
```kotlin
// androidApp/MainActivity.kt
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            App()
        }
    }
}
```

### Platform-specific UI (expect / actual)
```kotlin
// commonMain
@Composable
expect fun PlatformBanner()

// androidMain
@Composable
actual fun PlatformBanner() {
    Text("Android")
}

// iosMain
@Composable
actual fun PlatformBanner() {
    Text("iOS")
}
```

### Image / resource
```kotlin
@Composable
fun MyImage() {
    Image(
        painter = painterResource(Res.drawable.logo),
        contentDescription = null
    )
}
```

→ `composeResources/drawable/logo.png` 가 모든 platform.

### Compose Multiplatform 의 limitation
```
- Some Android-only API (e.g. Bluetooth).
- iOS 의 native control (UIKit) 가 안.
- Web 가 Canvas (a11y 제한).

→ 핵심 UI = CMP. Platform-specific = expect/actual.
```

### Performance
```
iOS: Skia 가 render. Native UIKit 보다 약간 느린.
Android: native = 빠름.
Desktop: 좋음.
Web: Canvas, slow startup.

→ iOS 가 acceptable, but native 보다 약간 ↓.
```

### Navigation
```kotlin
// Voyager / Decompose / 자체
import cafe.adriel.voyager.navigator.*

@Composable
fun App() {
    Navigator(HomeScreen()) { navigator ->
        // ...
    }
}
```

### State management
```kotlin
// commonMain
class CounterViewModel {
    private val _count = MutableStateFlow(0)
    val count: StateFlow<Int> = _count.asStateFlow()
    
    fun increment() { _count.value++ }
}

@Composable
fun Counter(viewModel: CounterViewModel) {
    val count by viewModel.count.collectAsState()
    Button(onClick = { viewModel.increment() }) { Text("$count") }
}
```

→ KMP-NativeCoroutines 가 iOS Swift 친화.

### vs Flutter
```
Flutter:
- Dart 언어.
- Skia render (모든 platform).
- 큰 ecosystem.
- Mature.

CMP:
- Kotlin 언어.
- Skia (iOS), native (Android).
- 작은 ecosystem.
- Stable 가 새 (2024).

→ Flutter 가 mature.
CMP 가 Kotlin 친화.
```

### vs React Native
```
RN:
- JS / TS.
- Native bridge.
- 큰 ecosystem.
- New Architecture (Fabric).

CMP:
- Kotlin native (no bridge).
- Compose-native.

→ RN 가 web team 친화.
CMP 가 mobile-first team 친화.
```

### Production
- **Kotlin Multiplatform Mobile** (JetBrains).
- **Cash App** (some module).
- **Kotzilla**.
- 점진 adoption (early).

### Use case
```
✓ Logic + UI 둘 다 share.
✓ Kotlin team 가 native UI 도.
✓ Internal app (UX 가 less critical).
✓ Prototype.

✗ Pixel-perfect platform UI.
✗ 매우 큰 user base.
✗ iOS-first.
```

### Hot reload
```
Compose Multiplatform 의 hot reload (2024+):
- Save 가 instant update.
- State 보존.

→ Dev experience ↑.
```

### Web (Canvas)
```kotlin
// jsMain or wasmJsMain
fun main() {
    onWasmReady {
        Window("My App") {
            App()
        }
    }
}
```

→ Browser 안 Compose. Canvas-based.

### Desktop
```kotlin
fun main() = application {
    Window(onCloseRequest = ::exitApplication, title = "My App") {
        App()
    }
}
```

→ Native window. Mac / Linux / Windows.

### Future
```
2026: CMP iOS stable + production.
- 더 많은 library cross-platform.
- Performance 가 native 가까이.
- Mature ecosystem.
```

### vs React Native New Architecture
```
RN: New Arch 가 Fabric (modern).
CMP: 항상 native 식.

→ Performance 비슷.
DevX 가 다름.
```

### 함정
```
- iOS 의 navigation 가 native 와 다름.
- Lifecycle 가 platform 별.
- iOS framework size 가 큰.
- Native API access 가 expect/actual 필요.
- Debugging cross-platform 어려움.
```

### Real-world tips
```
1. Common 가 80%.
2. Platform-specific 가 native UI (where possible).
3. KMP-NativeCoroutines 의 Swift integration.
4. Voyager / Decompose 의 navigation.
5. Test 가 매 platform.
```

## 🤔 의사결정 기준
| 상황 | 추천 |
|---|---|
| Kotlin team + 둘 다 | CMP |
| Mature ecosystem | RN / Flutter |
| iOS-first | Native |
| Internal app | CMP |
| Pixel-perfect platform | Native (iOS) + CMP (Android) |

## ❌ 안티패턴
- **iOS native control 가정 (UIKit)**: CMP 가 Skia.
- **Library 가 Android-only**: expect/actual.
- **No platform test**: iOS 가 깨짐.
- **모든 거 common**: native UX 잃음.
- **iOS framework size 무시**: bundle 폭발.

## 🤖 LLM 활용 힌트
- CMP = Compose UI cross-platform.
- KMP shared logic + CMP shared UI.
- iOS = Skia render (native 약간 다름).
- KMP-NativeCoroutines 의 Swift bridge.

## 🔗 관련 문서
- [[Mobile_KMP_Compose]]
- [[Mobile_KMP_Deep]]
- [[Android_Compose_Performance]]
