
KMP 도입의 진짜 장벽은 Swift 가 아니라 Gradle 이었습니다. 일주일 작업의 60% 가 build.gradle.kts 와 버전 매트릭스에 빨려 들어가더라고요.
지난 주말에 6년차 안드로이드 개발자인 제가 사이드 프로젝트 Repository 모듈 6개를 코틀린 멀티플랫폼(Kotlin Multiplatform)으로 이식해봤어요. 클로드 코드(Claude Code) 로 build script 진단을 돌려가며, 친구들 디스코드 사이드 프로젝트 채널에 빌드 로그 스샷을 던지면서요. 한 줄로 적자면, "쓸 만은 한데, 처음 한 주는 코드보다 설정에 멘붕이 옵니다."
코틀린 멀티플랫폼 2.3 Stable 범위, 어디까지가 production 인가
코틀린 멀티플랫폼에서 production-ready 가 붙은 영역은 생각보다 좁습니다. 코어와 Kotlin/Native, 데스크탑은 일찌감치 안정 트랙이었고, Compose Multiplatform iOS 는 2025년 5월 1.8.0 으로 stable 에 올라섰어요. 즉 iOS UI 공유의 production 선언은 Kotlin 2.3(2025년 말) 이전에 이미 떨어진 셈입니다. 최신 Kotlin 2.3 시점의 JetBrains 공식 stability matrix 기준으로도, 여기까지가 안정 트랙으로 정리되어 있어요.
반면 Compose for Web (Wasm) 은 아직 베타, Swift export(차세대 Swift interop) 와 새 C/Objective-C interop 모드는 Experimental~Beta 단계라는 얘기입니다. 그래서 "KMP가 stable 됐대" 한 줄로 정리되면 곤란해요. "어디가 stable 인지"를 한 번은 직접 확인하셔야 합니다.
여기서 한 가지 짚을 부분은, stable 의 의미가 "API 호환성 보장" 이지 "네이티브와 성능·경험 동일" 이 아니라는 점입니다.

Kotlin/Native 런타임이 IPA에 얹히는 비용은 여전히 있는데, 프로젝트마다 편차가 커서 의존성 구성에 따라 수 MB~수십 MB까지 늘어나는 사례가 보고됩니다. 제 사이드 프로젝트에서도 어느 정도 증가는 체감했고, 정확한 수치는 모듈 구성·의존성에 따라 들쭉날쭉하더라고요. 그래서 "내 앱에서 얼마 늘어날지" 는 첫 빌드 직후 IPA 사이즈를 한 번 직접 재보시는 게 가장 빠릅니다.
KMP 도입 최적 지점은 네트워크·DB·도메인 로직
이번에 이식하면서 ROI가 가장 명확했던 자리는 데이터 계층이었습니다. 네트워크 코드는 Retrofit을 Ktor로 옮기면 됩니다. DTO랑 인터셉터를 다시 짜야 하긴 한데, 응답 모델을 commonMain 으로 통합해서 iOS와 그대로 공유할 수 있다는 점이 크더라고요.
로컬 DB는 Room의 KMP 지원이 안정화되면서 선택지가 두 갈래로 늘었습니다. Room 그대로 가도 되고, SQLDelight 로 갈아탈 수도 있어요. 단, 어느 쪽이든 양 플랫폼에서 마이그레이션 테스트는 반드시 돌려보셔야 합니다. 안드로이드에서 잘 도는 스키마가 iOS에서 다르게 깨지는 경우가 생길 수 있습니다.

도메인 로직은 가장 쉽습니다. 순수 코틀린 함수면 그냥 옮겨져요. 다만 Swift에서 Kotlin의 Flow를 구독하려면 SKIE 같은 래퍼를 한 번 학습해야 한다는 점은 미리 알아두셔야 합니다.
Compose Multiplatform iOS UI 공유는 망설일 자리
UI까지 공유할지는 별개의 문제입니다. 제 사이드 프로젝트는 Material 디자인 톤이 강해서 한 번 진지하게 검토해봤는데, 결국 안 갖다 쓰기로 했어요. iOS HIG를 어느 정도 따라가려면 SwiftUI View 호스팅, 제스처 충돌 처리, 키보드·세이프 에어리어 미세 조정까지 추가 비용이 적지 않게 발생하더라고요.
플랫폼 의존 기능도 마찬가지입니다. 카메라, GPS, 위젯, 푸시 알림 핸들링 — 이런 영역은 expect/actual 로 추상화하는 비용이 차라리 네이티브로 두 벌 짜는 것보다 큰 경우가 많습니다. 특히 OS 업데이트에 민감한 기능은 KMP 추상화 층이 한 박자씩 늦게 따라오는 모습이에요.
그리고 Gradle 멀티 모듈 설정과 버전 매트릭스 관리, Apple의 인증서·프로비저닝·TestFlight 흐름은 KMP가 줄여주지 않는 영역입니다. 이건 KMP의 약점이 아니라, 그냥 두 생태계의 공통 비용이라고 보시면 되겠습니다.
Repository 모듈 1주 이식 일지, Gradle이 진짜 장벽이었어요
날짜별로 시간이 어디로 갔는지 적어봤습니다.
1. 1~2일차 — 모듈 분리
코드 변경보다 build.gradle.kts 설정과 KSP 버전 호환성 맞추는 데 시간의 60%를 썼습니다. Kotlin·KSP·AGP 호환 매트릭스를 한 번 정리해두지 않으면 매 sync마다 빨간 줄이 떴어요. 새벽에 클로드 코드한테 매트릭스 표를 한 장 출력시켜 책상 옆에 띄워두니 그제서야 sync 가 조용해지더라고요.
2. 3~4일차 — 라이브러리 교체
Retrofit → Ktor, Room → SQLDelight, DTO는 kotlinx.serialization 으로 통일했습니다. 이 구간은 의외로 깔끔하게 흘러갔어요. 응답 모델 한 벌로 양 플랫폼 데이터 흐름이 정리되는 그림이 슬슬 잡힙니다.
3. 5~7일차 — iOS 빌드
첫 빌드가 4분 30초 걸렸고, Xcode 디버거에서 Kotlin 객체 inspect 가 제한적이었습니다. SKIE를 끼워서 Swift에서 Flow 구독은 됐는데, 안정성 때문에 콜백으로 한 번 더 감쌌습니다. iOS 쪽 친구한테 빌드 스샷을 던졌더니 "이거 첫 빌드 시간은 다들 그러더라" 라는 답이 돌아왔어요.
개인적으로는 KMP를 처음 붙이는 분이라면, 첫 주는 "기능 이식" 이 아니라 "build script + 버전 매트릭스 손에 익히기" 로 시간을 잡고 들어가시는 게 현실적이라고 봅니다. 저처럼 1주차에 기능까지 다 옮기겠다고 덤비면, 새벽 두 시에 Could not resolve 로그 앞에서 멍해질 일이 생깁니다.
사이드 프로젝트 KMP 도입 판단 트리
복잡하게 짤 것 없이 네 줄로 정리됩니다.
- UI 인가? → Yes 면 네이티브로 유지. Material 톤이 강한 앱만 예외적으로 Compose Multiplatform iOS 검토.
- 하드웨어·OS 의존 기능인가? → Yes 면 플랫폼별로 구현. 카메라·위젯·푸시는 그냥 두 벌.
- 비즈니스 로직·데이터인가? → Yes 면 commonMain. 네트워크·DB·도메인·테스트 코드가 여기 들어옵니다.
- 의존성 하나가 양쪽 빌드를 동시에 깨뜨릴 위험이 큰가? → Yes 면 네이티브 fallback 경로를 미리 깔아둘 것.
제 사이드 프로젝트의 경우 6개 모듈 중 4개(데이터·로직)는 commonMain 으로, 2개(UI·플랫폼 API)는 네이티브로 남겼습니다. "전부 공유" 도 "전부 분리" 도 아닌, 데이터 계층만 깎아내는 절반의 선택이 1인 유지보수에는 가장 현실적이었어요.
KMP 의 production 선언이 거짓말은 아닙니다. 다만 그 선언이 "내 사이드 프로젝트 어디까지 KMP로 가도 되는가" 의 답까지 주지는 않더라고요. 그 답은 첫 주를 build script 와 인증서 사이에서 통째로 날리지 않으려면, 결국 본인 모듈 6개에 직접 자를 대고 그어보는 데서 나오는 것 같습니다.

새벽 두 시 빨간 줄 앞에서 멍해진 그 한 시간이, 지금 와서 돌아보면 이번 이식에서 가장 비싸게 산 한 시간이었어요.
'Android 개발 > Kotlin' 카테고리의 다른 글
| Kotlin 2.4 RC context parameters로 LoggerContext 6인자 날린 후기 (0) | 2026.06.10 |
|---|---|
| IntelliJ IDEA 2026.1 코루틴 인스펙션, 6년차 코드를 17번 찌르다 (0) | 2026.06.08 |
| Kotlin 2.3.20 name-based destructuring, 안드 코드 7곳에 끼워본 일주일 (0) | 2026.06.01 |
| Kotlin 2.4.0-RC 풀렸다 — context parameters 안정화·name-based destructuring 본인 코드에 한 시간 적용 (0) | 2026.05.27 |
| 코루틴 처음 만났을 때 가장 헷갈렸던 것들 (0) | 2026.05.04 |