Kotlin Multiplatform (KMP)은 JetBrains의 기술로, 공유 Kotlin 코드를 iOS, Android, Web 및 Desktop용으로 컴파일합니다. Flutter 및 React Native와 달리 KMP는 네이티브 UI를 대체하지 않습니다 — 공유 로직은 shared module로 추출되고 각 앱의 인터페이스는 네이티브로 유지됩니다. Kotlin Multiplatform documentation — 모듈 구성 및 expect/actual 메커니즘에 대한 주요 참고 자료입니다.
주요 포인트
Kotlin Multiplatform은 크로스 컴파일 기술로, Kotlin으로 공유 코드를 작성하고 다양한 플랫폼(JVM(Android), LLVM(iOS, macOS, watchOS), JavaScript(Web) 및 네이티브 바이너리(Linux, Windows))용으로 컴파일할 수 있습니다. KMP는 UI 프레임워크가 아닙니다 — 인터페이스가 아닌 비즈니스 로직 재사용 문제를 해결합니다.
KMP 아키텍처는 shared module을 중심으로 구축됩니다 — 플랫폼 독립적인 코드가 포함된 commonMain과 각 대상(androidMain, iosMain, desktopMain)의 source sets를 포함하는 Gradle 모듈입니다. 2025년 JetBrains 데이터에 따르면, 새로운 Kotlin 프로젝트의 40% 이상이 플랫폼 간 코드 공유를 위해 KMP를 사용합니다.
Kotlin Multiplatform Mobile (KMM) — iOS+Android 모바일 시나리오의 이전 이름입니다. Kotlin 2.1+부터 KMM 용어는 Kotlin Multiplatform으로 대체되었습니다. 기술이 모바일 개발을 넘어 확장되었기 때문입니다. Netflix, McDonald's 및 VMware는 모바일 애플리케이션 간 코드 공유를 위해 프로덕션에서 KMP를 사용합니다.
Expect/actual — 플랫폼별 코드 작업을 위한 KMP의 핵심 메커니즘입니다. commonMain에서 expect 선언(함수, 클래스, 속성)이 선언되고 각 플랫폼별 source set(androidMain, iosMain)에서 actual 구현이 제공됩니다. 컴파일러는 각 expect에 대해 각 대상 플랫폼에 actual이 있는지 확인합니다.
// commonMain — 플랫폼 API 선언
expect fun getPlatformName(): String
expect class PlatformContext(val appVersion: String)
// androidMain — Android용 actual
actual fun getPlatformName(): String = "Android \${Build.VERSION.SDK_INT}"
// iosMain — iOS용 actual
actual fun getPlatformName(): String =
UIDevice.currentDevice.systemNameKMP의 source sets 계층 구조를 통해 중간 수준을 만들 수 있습니다: 예를 들어, iosArm64Main(실제 iOS 기기) 및 iosSimulatorArm64Main(시뮬레이터)과 공유 iosMain입니다. commonMain의 코드는 모든 플랫폼에서 사용할 수 있지만 iosMain의 코드는 iOS 대상에서만 사용할 수 있습니다. 이는 구현이 각 플랫폼이 아닌 플랫폼 그룹에 따라 다를 때 중복을 줄입니다.
실제로 expect/actual은 다음 용도로 사용됩니다: 로컬 저장소 액세스(SharedPreferences vs NSUserDefaults), 네트워킹(플랫폼별 HttpEngine), 파일 시스템 액세스, 암호화 및 분석. JetBrains는 expect/actual 선언 수를 최소화하고 가능한 한 많은 코드를 commonMain으로 이동할 것을 권장합니다.
Shared module — org.jetbrains.kotlin.multiplatform 플러그인이 있는 표준 Gradle 모듈입니다. src/commonMain/kotlin/에 공유 코드가 포함되고 src/androidMain/kotlin/ 및 src/iosMain/kotlin/에 플랫폼별 구현이 포함됩니다. KMP 프로젝트에는 shared module에 의존하는 androidApp 및 iosApp도 포함됩니다.
// build.gradle.kts — shared module
plugins {
kotlin("multiplatform")
id("com.android.library")
}
kotlin {
androidTarget()
listOf(
iosX64(),
iosArm64(),
iosSimulatorArm64()
).forEach {
it.binaries.framework {
baseName = "shared"
isStatic = true
}
}
sourceSets {
val commonMain by getting {
dependencies {
implementation("io.ktor:ktor-client-core:3.1.0")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3")
}
}
val androidMain by getting {
dependencies {
implementation("io.ktor:ktor-client-okhttp:3.1.0")
}
}
val iosMain by creating {
dependencies {
implementation("io.ktor:ktor-client-darwin:3.1.0")
}
}
}
}KMP용 Gradle 구성에서는 iOS 대상(x64(인텔 시뮬레이터), arm64(실제 기기) 및 simulatorArm64(Apple Silicon 시뮬레이터))을 명시적으로 선언해야 합니다. 각 대상에 대해 별도의 Apple 프레임워크가 생성됩니다. kotlin("multiplatform") 플러그인은 선언된 대상에 따라 JVM 및 LLVM용 컴파일을 자동으로 구성합니다.
Ktor 및 kotlinx.serialization — 공유 코드를 지원하는 표준 KMP 라이브러리입니다. Ktor는 각 플랫폼용 엔진(Android용 OkHttp, iOS용 Darwin)이 있는 HTTP 클라이언트를 제공합니다. kotlinx.serialization은 commonMain의 멀티플랫폼 구현 덕분에 expect/actual 없이 모든 플랫폼에서 작동합니다.
Kotlin/Native — LLVM을 통해 네이티브 코드를 생성하는 Kotlin 컴파일러입니다. iOS의 경우 shared module이 Apple 프레임워크(.framework)로 컴파일되어 Xcode를 통해 연결됩니다. Swift/Objective-C에서 공유 코드 호출은 생성된 Objective-C 헤더를 통해 이루어지므로 shared module API는 Objective-C와 호환되어야 합니다.
iOS 통합 제한 사항: Kotlin 컬렉션(List, Map)은 NSArray/NSDictionary로 변환됩니다. 기본 매개변수가 있는 함수는 내보내지지 않습니다 — 오버로드가 필요합니다. suspend 함수의 경우 @ObjCName 및 Kotlin 2.0+부터 async/await 지원과 함께 콜백 기반 메서드가 생성됩니다.
// iOS 앱: Swift에서 shared module 호출
import shared
class ViewModel: ObservableObject {
let repository = UserRepository()
func loadUsers() {
repository.fetchUsers(completionHandler: { result, error in
if let users = result as? [User] {
print("Users: \(users.count)")
}
})
}
}Xcode에 shared module 통합은 embed-and-framework를 통해 이루어집니다 — 생성된 .xcframework가 Xcode 프로젝트에 추가됩니다. Gradle 플러그인은 embedAndSignAppleFrameworkForXcode를 통해 빌드 중에 프레임워크를 자동으로 업데이트할 수 있습니다. 시뮬레이터에서 테스트하려면 iosSimulatorArm64 또는 iosX64 바이너리로 충분합니다.
KMP, Flutter 및 React Native 중 선택은 우선순위(코드 재사용 또는 완전한 크로스 플랫폼)에 따라 다릅니다. KMP는 각 플랫폼에서 네이티브 UI를 제공하지만 인터페이스에 두 개의 코드베이스가 필요합니다. Flutter와 React Native는 단일 UI를 사용하지만 네이티브성을 희생합니다.
| 특징 | KMP | Flutter | React Native |
|---|---|---|---|
| UI 프레임워크 | 네이티브(Android XML/Jetpack Compose + SwiftUI) | Dart + 자체 Skia 렌더러 | React + 네이티브 컴포넌트 |
| 공유 코드 | 비즈니스 로직, 네트워킹, DB, 유효성 검사 | 네이티브 플러그인 제외 100% | 네이티브 모듈 제외 100% |
| 성능 | 네이티브(미들웨어 없음) | 높음(Skia Engine) | 중간(JSI Bridge) |
| iOS 지원 | Kotlin/Native(우수) | 우수 | 좋음 |
| 진입 장벽 | 중간(Kotlin + 네이티브 플랫폼) | 낮음(하나의 언어 + 하나의 UI) | 낮음(JS/TS + React) |
KMP를 선택해야 하는 경우: 프로젝트에 고성능 UI(게임, 지도, 애니메이션)가 필요하고, 기존 네이티브 코드를 재사용해야 하며, 팀이 이미 Kotlin과 네이티브 플랫폼을 알고 있는 경우입니다. Flutter/RN을 선택해야 하는 경우: 예산이 제한된 MVP 또는 스타트업, 단일 프로필 팀, UI에 깊은 네이티브 사용자 정의가 필요하지 않은 경우입니다.
KMP 도구 생태계에는 모든 애플리케이션 계층을 위한 라이브러리가 포함됩니다: 네트워킹(Ktor), 직렬화(kotlinx.serialization), 데이터베이스(SQLDelight), 탐색(Decompose), DI(Koin) 및 데이터 저장소(multiplatform-settings). JetBrains는 모든 플랫폼에서 실행되는 Kotlin UI 프레임워크인 Compose Multiplatform을 지원합니다.
// SQLDelight + Ktor를 사용한 KMP 리포지토리
class UserRepository(
private val httpClient: HttpClient,
private val db: AppDatabase
) {
suspend fun syncUsers(): List<User> {
val remote = httpClient.get("https://api.example.com/users")
.body<List<UserDto>>()
db.userQueries.replaceAll(remote.map { it.toDomain() })
return db.userQueries.selectAll().executeAsList()
}
}Compose Multiplatform — Jetpack Compose를 기반으로 하는 KMP용 UI 프레임워크입니다. Android, iOS, Desktop 및 Web용 Kotlin으로 인터페이스를 작성할 수 있습니다. 2025년에 Compose Multiplatform은 Android 및 Desktop에서 안정적인 상태에 도달했습니다. iOS 대상은 베타 버전입니다. 네이티브 UI를 사용하는 프로덕션 프로젝트의 경우 KMP의 장점이 Flutter와의 주요 차이점으로 남아 있습니다.
자주 묻는 질문
KMM — iOS 및 Android용 KMP의 모바일 시나리오입니다. Kotlin 2.1+부터 JetBrains는 두 용어를 Kotlin Multiplatform으로 통합했습니다. 기술이 모바일 플랫폼뿐만 아니라 Desktop 및 Web도 지원하기 때문입니다. KMM 프로젝트는 계속 작동하지만 이제 전체 KMP의 일부입니다.
네. KMP는 Objective-C 헤더와 함께 Kotlin/Native를 통해 Apple 프레임워크로 컴파일됩니다. SwiftUI는 이 프레임워크를 일반 라이브러리처럼 가져옵니다. Shared module은 Kotlin 클래스와 함수를 내보내며 일부 제한 사항과 함께 Swift에서 호출됩니다(예: Kotlin 컬렉션은 Foundation 유형으로 변환됨).
iOS에서 shared module은 iosTest source set의 Kotlin/Native 테스트를 통해 테스트됩니다. UI 테스트의 경우 가져온 프레임워크와 함께 Xcode에서 XCTest가 사용됩니다. Kotlin 테스트는 commonTest에서 kotlin.test로 작성되고 iosSimulatorArm64Test Gradle 작업을 통해 iOS 시뮬레이터에서 실행됩니다.
주요 KMP 라이브러리: Ktor(네트워킹), kotlinx.serialization(JSON), SQLDelight(DB), Koin(DI), Decompose(탐색), multiplatform-settings(SharedPreferences/NSUserDefaults), Apollo GraphQL, Firebase(KMP-NativeCoroutines 통해). Compose Multiplatform은 모든 플랫폼에 UI를 제공합니다.
네. KMP는 Gradle 8.5+와 완전히 호환됩니다. Kotlin 2.1부터 공식 플러그인은 Gradle 8을 지원합니다. build.gradle.kts와 kotlin("multiplatform")을 통한 구성에는 Gradle 7.6+가 필요하지만 최적의 빌드 성능을 위해 버전 8.5가 권장됩니다.
요약
턴키 방식의 모바일 애플리케이션을 개발해 드립니다
IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.