Kotlin Multiplatform: 개념, shared module 및 expect/actual

저자: IT Sectr 게시일: 2026-02-11 읽는 시간: 11 분

Kotlin Multiplatform (KMP)은 JetBrains의 기술로, 공유 Kotlin 코드를 iOS, Android, Web 및 Desktop용으로 컴파일합니다. Flutter 및 React Native와 달리 KMP는 네이티브 UI를 대체하지 않습니다 — 공유 로직은 shared module로 추출되고 각 앱의 인터페이스는 네이티브로 유지됩니다. Kotlin Multiplatform documentation — 모듈 구성 및 expect/actual 메커니즘에 대한 주요 참고 자료입니다.

주요 포인트

  • KMP — 네이티브 UI를 대체하지 않고 플랫폼 API를 위한 expect/actual을 갖춘 Kotlin의 공유 로직
  • Shared module — 모든 플랫폼을 위한 네트워킹, 데이터베이스, 유효성 검사 및 비즈니스 로직 코드를 포함하는 Gradle 모듈
  • Expect/actual — 각 대상에 대한 구현과 함께 공유 코드에서 플랫폼 API를 선언하는 메커니즘
  • iOS 통합 — shared module이 Kotlin/Native를 통해 Apple 프레임워크로 컴파일됩니다
  • KMP vs KMM — Kotlin Multiplatform Mobile(모바일 중심)은 이제 Kotlin Multiplatform의 일부입니다

Kotlin Multiplatform이란?

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 메커니즘: 아키텍처

Expect/actual — 플랫폼별 코드 작업을 위한 KMP의 핵심 메커니즘입니다. commonMain에서 expect 선언(함수, 클래스, 속성)이 선언되고 각 플랫폼별 source set(androidMain, iosMain)에서 actual 구현이 제공됩니다. 컴파일러는 각 expect에 대해 각 대상 플랫폼에 actual이 있는지 확인합니다.

kotlin
// 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.systemName

KMP의 source sets 계층 구조를 통해 중간 수준을 만들 수 있습니다: 예를 들어, iosArm64Main(실제 iOS 기기) 및 iosSimulatorArm64Main(시뮬레이터)과 공유 iosMain입니다. commonMain의 코드는 모든 플랫폼에서 사용할 수 있지만 iosMain의 코드는 iOS 대상에서만 사용할 수 있습니다. 이는 구현이 각 플랫폼이 아닌 플랫폼 그룹에 따라 다를 때 중복을 줄입니다.

실제로 expect/actual은 다음 용도로 사용됩니다: 로컬 저장소 액세스(SharedPreferences vs NSUserDefaults), 네트워킹(플랫폼별 HttpEngine), 파일 시스템 액세스, 암호화 및 분석. JetBrains는 expect/actual 선언 수를 최소화하고 가능한 한 많은 코드를 commonMain으로 이동할 것을 권장합니다.

Shared module: 구조 및 Gradle

Shared moduleorg.jetbrains.kotlin.multiplatform 플러그인이 있는 표준 Gradle 모듈입니다. src/commonMain/kotlin/에 공유 코드가 포함되고 src/androidMain/kotlin/src/iosMain/kotlin/에 플랫폼별 구현이 포함됩니다. KMP 프로젝트에는 shared module에 의존하는 androidAppiosApp도 포함됩니다.

kotlin
// 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용 컴파일을 자동으로 구성합니다.

Ktorkotlinx.serialization — 공유 코드를 지원하는 표준 KMP 라이브러리입니다. Ktor는 각 플랫폼용 엔진(Android용 OkHttp, iOS용 Darwin)이 있는 HTTP 클라이언트를 제공합니다. kotlinx.serialization은 commonMain의 멀티플랫폼 구현 덕분에 expect/actual 없이 모든 플랫폼에서 작동합니다.

Kotlin/Native를 통한 iOS 통합

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 지원과 함께 콜백 기반 메서드가 생성됩니다.

swift
// 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 vs Flutter vs React Native

KMP, Flutter 및 React Native 중 선택은 우선순위(코드 재사용 또는 완전한 크로스 플랫폼)에 따라 다릅니다. KMP는 각 플랫폼에서 네이티브 UI를 제공하지만 인터페이스에 두 개의 코드베이스가 필요합니다. Flutter와 React Native는 단일 UI를 사용하지만 네이티브성을 희생합니다.

특징KMPFlutterReact 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 도구 및 라이브러리

KMP 도구 생태계에는 모든 애플리케이션 계층을 위한 라이브러리가 포함됩니다: 네트워킹(Ktor), 직렬화(kotlinx.serialization), 데이터베이스(SQLDelight), 탐색(Decompose), DI(Koin) 및 데이터 저장소(multiplatform-settings). JetBrains는 모든 플랫폼에서 실행되는 Kotlin UI 프레임워크인 Compose Multiplatform을 지원합니다.

kotlin
// 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와의 주요 차이점으로 남아 있습니다.

자주 묻는 질문

Kotlin Multiplatform과 Kotlin Multiplatform Mobile의 차이점은 무엇인가요?

KMM — iOS 및 Android용 KMP의 모바일 시나리오입니다. Kotlin 2.1+부터 JetBrains는 두 용어를 Kotlin Multiplatform으로 통합했습니다. 기술이 모바일 플랫폼뿐만 아니라 Desktop 및 Web도 지원하기 때문입니다. KMM 프로젝트는 계속 작동하지만 이제 전체 KMP의 일부입니다.

KMP를 SwiftUI와 함께 사용할 수 있나요?

네. KMP는 Objective-C 헤더와 함께 Kotlin/Native를 통해 Apple 프레임워크로 컴파일됩니다. SwiftUI는 이 프레임워크를 일반 라이브러리처럼 가져옵니다. Shared module은 Kotlin 클래스와 함수를 내보내며 일부 제한 사항과 함께 Swift에서 호출됩니다(예: Kotlin 컬렉션은 Foundation 유형으로 변환됨).

iOS에서 shared module을 테스트하는 방법은?

iOS에서 shared module은 iosTest source set의 Kotlin/Native 테스트를 통해 테스트됩니다. UI 테스트의 경우 가져온 프레임워크와 함께 Xcode에서 XCTest가 사용됩니다. Kotlin 테스트는 commonTest에서 kotlin.test로 작성되고 iosSimulatorArm64Test Gradle 작업을 통해 iOS 시뮬레이터에서 실행됩니다.

KMP에서 사용 가능한 라이브러리는 무엇인가요?

주요 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을 지원하나요?

네. KMP는 Gradle 8.5+와 완전히 호환됩니다. Kotlin 2.1부터 공식 플러그인은 Gradle 8을 지원합니다. build.gradle.kts와 kotlin("multiplatform")을 통한 구성에는 Gradle 7.6+가 필요하지만 최적의 빌드 성능을 위해 버전 8.5가 권장됩니다.

요약

  • Kotlin Multiplatform — 네이티브 UI를 대체하지 않고 공유 코드를 위한 JetBrains의 크로스 플랫폼 기술
  • Expect/actual — 각 대상에 대한 구현과 함께 commonMain에서 플랫폼 API를 선언하는 메커니즘
  • Shared module — commonMain 및 플랫폼별 source sets(androidMain, iosMain)이 있는 Gradle 모듈
  • Kotlin/Native가 shared module을 Apple 프레임워크로 컴파일하여 Swift 및 Objective-C에서 호출 가능
  • KMP vs Flutter/RN — 로직 재사용 + 네이티브 UI 대 단일 코드베이스 및 UI
  • Compose Multiplatform — Android, iOS, Desktop 및 Web용 Kotlin UI 프레임워크
  • 생태계 — 모든 애플리케이션 계층을 위한 Ktor, SQLDelight, Koin, kotlinx.serialization, Decompose

턴키 방식의 모바일 애플리케이션을 개발해 드립니다

IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.

프로젝트 논의

더 읽어보기