[App] Kotlin Multiplatform, Compose Multiplatform에 대해서
![[App] Kotlin Multiplatform, Compose Multiplatform에 대해서](/content/images/size/w960/2025/02/40D8A6FC-7C88-47BB-95EE-997729523644_1_105_c.jpeg)
원래는 블로그에 이 주제로 글을 작성할 생각이 없었다. 그러다 이 글을 쓰게 된데는 크게 두 가지 계기가 있다. 먼저, Android Weekly를 구독하여 보고 있는데 은근 KMP 관련 글이 많이 보였다. 또 하나로는 종종 심심할 때 JetBrains 블로그를 둘러보는 편인데 그러다 Kotlin Multiplatform Development Roadmap for 2025이라는 글을 봤다. 생각보다 Jetbrains에서 Kotlin Multiplatform 시스템을 비중있게 생각하고 있는 것 같아 나도 해당 주제를 다뤄보기로 했다.
사실 2023년에 대학교 컨퍼런스에서 해당 주제로 발표한 경험이 있다. 나는 과거부터 다양한 스택을 시도해왔었기 때문에 Android 개발자에게 어울리는 크로스플랫폼 스택이라는 점은 나에게 큰 메리트였고 나름 간단히 사용해 봤을 때도 만족스러웠다.
Application 개발에 대해서
먼저 애플리케이션 개발 방식은 크게 3가지로 나눌 수 있다.
- Native 방식
- Cross-platform 방식
- Hybrid 방식
Native 방식
Native 방식은 플랫폼 (Android, iOS)에 맞는 네이티브 언어와 SDK를 사용해 애플리케이션을 개발하는 방법이다. Android에서는 Kotlin 또는 Java를 사용하고 iOS에서는 Swift 또는 Objective-C를 사용하여 각 플랫폼에 최적화된 성능과 경험을 제공할 수 있다.
Cross-platform 방식
Cross-platform 방식은 하나의 코드베이스로 여러 플랫폼 (Android, iOS 등)을 지원하는 방법이다. 대표적인 Cross-platform 프레임워크로는 Flutter, React Native, Xamarin, Kotlin Multiplatform이 있다.
Hybrid 방식
Hybrid 방식은 웹 기술 (HTML, CSS, JavaScript)을 사용하여 애플리케이션을 개발하고, 웹 애플리케이션을 네이티브 컨테이너에 담아 앱처럼 배포하는 방식이다. 대표적인 Hybrid 프레임워크로는 Apache Cordova, Ionic이 있다.
위의 방식들 모두 각각의 장단점이 있지만 애플리케이션에서 각 스마트폰의 다양한 기능들을 활용해야 한다면 Native 방식 또는 Cross-platform 방식을 택하는게 일반적이다. 여기서 각 OS에서의 성능을 중요시한다면 Native 방식, 성능을 조금 포기하더라도 개발 비용을 더 중요시한다면 Cross-platform을 택한다.

위의 차트에서 볼 수 있듯이 iOS의 시장은 점점 커지고 있고 특히 우리나라를 기준으로 2-30대는 iOS의 사용률이 더 높기 때문에 Android, iOS 둘 중 하나의 시장만 잡는다고 되는게 아니다.
새로운 애플리케이션을 만들어야 되는 스타트업 입장에서는 성공이 확실치 않은 아이디어를 큰 비용을 들여 Android, iOS 둘 다 만들어야 한다면 추후 출시하고 실패했을 때의 손실은 감당하기 어려울 것이다. 자원이 넉넉하면 상관없겠지만 말이다. 그래서 Cross-platform 방식을 택했는데 추후 사용자가 많아지고 기능이 추가되며 각 OS에 깊게 접근해야 하는 경우가 생기면 이 때는 또 Native 방식으으의 전환을 고려해야 할 것이다. 이 각각의 단점들을 보완할 프레임워크인 Kotlin Multiplatform이 나타났다.
Kotlin Multiplatform(KMP)
Kotlin Multiplatform(이하 KMP)은 JetBrains가 개발한 Kotlin 언어의 기능 중 하나로, 여러 플랫폼에 걸쳐 코드를 재사용할 수 있게 해주는 기술이다. 이를 통해 Android, iOS, Web, Desktop 등 다양한 플랫폼에서 공통 모듈을 작성하여, 동일한 비즈니스 로직을 공유하고 UI와 네이티브 기능은 각 플랫폼에 맞게 구현할 수 있다. KMP는 2017년, Kotlin 1.2가 출시되면서 처음 언급되었다. 그리고 2020년부터 다양한 멀티 플랫폼 라이브러리가 등장하고 성능과 안전성이 개선되었다.
JetBrains에서는 KMP를 꽤 비중있게 다루고 있다. 2024년 5월 23일 Kotlin 2.0 Release와 함께 올린 블로그 글의 제목도 ’Celebrating Kotlin 2.0: Fast, Smart, and Multiplatform'이다. Jetbrains 블로그에는 Multiplatform 탭을 따로 만들어 놨을 정도이다. 또한, 최근 업데이트도 꾸준히 해주고 있다.

Client 뿐만 아니라 Server 까지 동일한 로직을 공유하여 개발을 진행할 수 있다.
주요 특징
- 공통 코드 작성: KMP를 사용하면 네트워크 요청, 데이터 저장, 비즈니스 로직 등 플랫폼 간 차이가 적은 로직을 한 번만 작성할 수 있다. 이를 통해 중복 코드를 줄이고 유지보수를 용이하게 한다.
- 플랫폼별 구현 허용: 공통 모듈 외에도 각 플랫폼(Android, iOS 등) 별로 필요한 UI나 네이티브 기능을 구현할 수 있는 유연성을 제공한다.
- Gradle 기반 빌드 시스템: KMP 프로젝트는 Gradle을 사용해 플랫폼 간 의존성을 관리하고 빌드할 수 있다. Gradle은 각 플랫폼의 요구 사항을 처리해 최적화된 코드 패키지를 생성한다.
- 멀티 플랫폼 라이브러리 사용: KMP의 생태계가 확장되면서 Ktor(네트워킹), SQLDelight(데이터베이스) 등 여러 멀티 플랫폼 라이브러리들이 등장해 개발을 더욱 쉽게 지원하고 있다.
KMP 구조

위의 사진에서 볼 수 있듯이 각 Kotlin, Swift Gradle이 공통의 Kotlin Gradle을 바라본다. 프로젝트를 처음 생성했을 때 파일 구조는 대략적으로 아래와 같다.

Android, iOS, Desktop 각 모듈이 공통 Shared 모듈을 바라보고 있는 형식이다. 메인 코드 작성은 Shared Module에서 하고 각 플랫폼에 맞는 코드는 각 모듈에 추가한다.
라이브러리

다양한 플랫폼 위에서 모두 동작해야 하기 때문에 정해진 라이브러리 내에서 개발을 진행해야 한다. 지원되는 라이브러리 목록은 Github에 잘 정리되어 있다.
사용 기업
몇 년 전까지만 하더라도 KMP는 불안정했고 자료도 많지 않아 사용하는 곳이 많지 않았다. 하지만 최근 관심도가 높아짐에 따라 다양한 사용 사례가 나왔다. 현재 KMP를 사용하고 있는 기업들은 아래와 같다.
- McDonald's
- 9GAG
- Quizlet
- Netflix
- Philips
- VMWare
한계
- iOS 애플리케이션 개발을 위해서는 Mac이 필수적이다. 결국 빌드는 XCode에서 해야 하기 때문이다.
- Android 개발자 입장에서는 Kotlin에 익숙하지만 iOS 개발자는 Kotlin을 새로 배워야 한다. 이에 따른 학습 비용이 발생한다.
- 아직 라이브러리가 한정되어 있고 자료도 상대적으로 적다.
- 결국은 Swift를 알아야 한다.
이러한 한계점들을 보완하기 위해 나온 것이 Compose Multiplatform이다.
Compose Multiplatform
Compose Multiplatform은 JetBrains가 개발한 UI 프레임워크로, Kotlin 기반의 선언형 UI 프레임워크인 Jetpack Compose를 여러 플랫폼에서 사용할 수 있도록 확장한 것이다. 이를 통해 Android, 데스크탑, 웹, 그리고 iOS 등 다양한 플랫폼에서 공통된 UI 코드를 작성할 수 있다. 보통 KMP와 결합하여 사용하는데, 이렇게 하면 비즈니스 로직부터 UI까지 Kotlin 하나로 개발이 가능하게 된다. Compose Multiplatform은 2021년 10월, JetBrains가 공식적으로 프로젝트를 발표하면서 처음 언급되었다.
주요 특징
- 공통 UI 코드 작성: 한 번의 UI 작성으로 여러 플랫폼에서 동일한 화면을 보여줄 수 있다. 이를 통해 코드를 재사용하고 유지보수를 쉽게 해준다.
- 선언형 UI: Jetpack Compose의 선언형 UI 모델을 그대로 사용하여, 더 직관적이고 반응형의 UI를 작성할 수 있다. 이는 상태 변화를 UI에 쉽게 반영할 수 있어 복잡한 UI를 효과적으로 관리할 수 있게 한다.
- 네이티브 플랫폼 통합: Compose Multiplatform은 각 플랫폼의 네이티브 UI와도 잘 통합된다. 예를 들어 Android에서는 기존 Jetpack Compose와 호환되며, iOS에서는 UIKit, 데스크탑에서는 Swing 또는 AWT와 함께 사용할 수 있다.
- 다양한 플랫폼 지원: Compose Multiplatform은 Android, Desktop, Web을 비롯해 iOS에서도 작동하도록 설계되었다. 여러 플랫폼을 위한 통일된 UI 코드를 만들면서도, 각 플랫폼에 맞는 네이티브 경험을 제공할 수 있다.
Kotlin Multiplatform + Compose Multiplatform 구조

Kotlin Multiplatform + Compose Multiplatform 조합으로 처음부터 끝까지 Kotlin 언어를 활용하여 Android, iOS, Desktop, Web을 개발할 수 있다. 게다가 Spring/SpringBoot 스택을 사용한다면 서버도 Kotlin으로 개발할 수 있다.

KMP와 동일한 프로젝트 구조이다. 하지만 이제는 UI 코드가 각 플랫폼 Module이 아닌 Shared Module에 들어간다.
지원 버전

2024년 5월 23일 Compose Multiplatform 1.6.10이 Release 되면서 iOS는 Alpha -> Beta로 승격되었고 Web은 Experimental에서 Alpha로 승격되었다.
사용 사례


한계
- Android, iOS, Web, Desktop 등 모두 권장되는 UI/UX가 다르기 때문에 각 플랫폼에 맞는 화면 구성을 원한다면 코드의 단일화에는 한계가 있다.
- iOS 버전은 현재 Beta이고 Web 버전은 아직 Alpha이다. 최근 iOS는 Alpha에서 Beta로, Web은 Experimental에서 Alpha로 승격된 것을 보면 업데이트가 적극적으로 이루어지고 있는 것 같지만 아직은 활용하기에 어려울 수 있다.
- Kotlin Multiplatform하고 함께 사용하기 때문에 아직 지원되는 라이브러리가 많지 않다.
Kotlin Multiplatform, Compose Multiplatform 구현
해당 글을 기술 소개를 중점적으로 하기 때문에 과연 어떻게 코드를 작성해야 동작하는지 핵심적인 내용에 대해 간단히 소개해보려 한다.
Platform
import kotlin.random.Random
class Greeting {
private val platform: Platform = getPlatform()
fun greet(): String {
val firstWord = if (Random.nextBoolean()) "Hi!" else "Hello!"
return "$firstWord Guess what this is! > ${platform.name.reversed()}!"
}
}
위의 코드에서 Platform
이라는 객체가 보일텐데 platform.name
변수에서 해당 코드가 동작하고 있는 플랫폼이 무엇인지 알 수 있다. 해당 변수의 값에 따라 조건문을 사용하여 어떤 방식으로 동작하게 할지 개발 단계에서 결정한다.
expect/actual
Kotlin Multiplatform, Compose Multiplatform에서는 expect/actual이라는 키워드를 사용하여 코드를 작성한다.
expect
- 함수 이름이나 클래스 앞에 선언 가능하다.
- 뜻 그대로 구현이 기대되는 함수 또는 클래스에 선언한다.
actual
- 플랫폼에 따라
expect
로 common의 코드에서 선언한 동일한 함수나 클래스 이름으로 선언한다. - 뜻 그대로 실제 동작 방식에 대한 구현이 필요하다.
Example
// commonMain/kotlin/App.kt
@Composable
expect fun MapUI(
modifier: Modifier,
gps: GpsPosition,
title: String,
parentScrollEnableState: MutableState<Boolean>
)
commonMain/kotlin/App.kt
// androidMain/kotlin/main.android.kt
@Composable
actual fun MapUI(
modifier: Modifier
) {
GoogleMap()
}
androidMain/kotlin/main.android.kt
// iosMain/kotlin/main.ios.kt
@OptIn(ExperimentalForeignApi::class)
@Composable
actual fun MapUI(
modifier: Modifier
) {
UIKitView(
modifier = modifier,
factory = {
MKMapView(
)
}
)
}
iosMain/kotlin/main.ios.kt
마치며
Android 애플리케이션 개발자들에게는 매우 매력적인 프레임워크이지 않을까 싶다. Flutter와 더불어 최근 업데이트가 활발하게 되고 있는 것 같은 Cross-platform 프레임워크이다. 나는 2023년부터 해당 프레임워크에 관심을 갖고 주의깊게 봐왔는데 불과 1년 반 정도밖에 되지 않았음에도 눈에 띄도록 많은 업데이트가 진행되었다. 처음에는 이 기술이 과연 적극적으로 사용이 될까 싶었는데 이정도 개발 속도면 예상보다 빨리 보편적으로 사용될 것이라 생각한다. 내년에 진행 예정인 프로젝트에 사용해보려 한다.