В чём разница между Kotlin Multiplatform и Kotlin Multiplatform Mobile (KMM)?
KMM — бывшее маркетинговое название мобильного подмножества KMP (Android+iOS). В 2023 году с выходом KMP Stable бренд KMM упразднили, теперь всё называется Kotlin Multiplatform.
Краткий ответ
KMM (Kotlin Multiplatform Mobile) — это бывшее маркетинговое название для подмножества KMP, ориентированного исключительно на мобильные платформы (Android + iOS). В 2023 году JetBrains объединила брендинг: KMM официально стал частью KMP, и термин KMM больше не используется в официальной документации.
История терминологии
До 2023 года JetBrains продвигала два отдельных продукта:
- KMP (Kotlin Multiplatform) — общий фреймворк для любых платформ: JVM, JS, Native (iOS, macOS, Linux, Windows, tvOS, watchOS, WebAssembly).
- KMM (Kotlin Multiplatform Mobile) — плагин для Android Studio и набор инструментов, заточенный под Android + iOS. Отдельный сайчик kotlinlang.org/lp/mobile, отдельные шаблоны.
В ноябре 2023 года KMP вышел из Beta в статус Stable. Вместе с этим JetBrains упразднила отдельный бренд KMM, унифицировав всё под KMP. Плагин KMM для Android Studio был переименован в Kotlin Multiplatform.
Техническая разница (которой почти нет)
С технической точки зрения KMM и мобильный таргет KMP — одно и то же. KMM никогда не был отдельным компилятором или рантаймом. Разница была только в:
- Шаблонах проектов (мобильные пресеты в Android Studio)
- Документации (отдельный сайт)
- Плагине Android Studio (kotlinlang.org/docs/multiplatform-plugin-releases.html)
Структура современного KMP-проекта (мобиль)
// build.gradle.kts (shared модуль)
kotlin {
androidTarget {
compilations.all {
kotlinOptions {
jvmTarget = "17"
}
}
}
listOf(
iosX64(),
iosArm64(),
iosSimulatorArm64()
).forEach { iosTarget ->
iosTarget.binaries.framework {
baseName = "Shared"
isStatic = true
}
}
sourceSets {
commonMain.dependencies {
implementation(libs.kotlinx.coroutines.core)
implementation(libs.ktor.client.core)
implementation(libs.sqldelight.runtime)
}
androidMain.dependencies {
implementation(libs.ktor.client.android)
implementation(libs.sqldelight.android.driver)
}
iosMain.dependencies {
implementation(libs.ktor.client.darwin)
implementation(libs.sqldelight.native.driver)
}
}
}
Что изменилось с переходом на KMP
- Документация переехала с kotlinlang.org/lp/mobile на kotlinlang.org/docs/multiplatform.html
- Плагин Android Studio теперь называется «Kotlin Multiplatform» (а не KMM Plugin)
- Wizard для создания проектов доступен на kmp.jetbrains.com
- Статус Stable означает стабильное Gradle DSL, стабильный компилятор, официальный support
Compose Multiplatform — отдельная история
Нередко путают KMP с Compose Multiplatform (CMP). KMP — это инфраструктура для переиспользования кода. CMP — это UI-фреймворк поверх KMP, который позволяет писать UI на Compose и деплоить на Android, iOS, Desktop и Web. CMP разрабатывается JetBrains и находится в активной разработке (iOS-таргет — Alpha/Beta в 2024).
Подводные камни
- Устаревшая документация: поиск по «KMM» выдаёт статьи 2021–2022 годов с устаревшими Gradle-конфигурациями. Всегда проверяйте дату публикации.
- Плагин KMM больше не обновляется: если у вас старый проект с зависимостью на KMM-плагин, его нужно мигрировать на новый Kotlin Multiplatform плагин.
- Путаница с таргетами: в старых проектах можно встретить ios() (deprecated) вместо iosX64() + iosArm64() + iosSimulatorArm64(). Kotlin 2.0 перешёл на новую иерархию таргетов.
- isStatic = true для iOS фреймворка: динамические фреймворки поддерживаются, но статические проще в интеграции и рекомендованы для большинства проектов.
- Kotlin/Native и coroutines: до Kotlin 1.9.20 была проблема с «frozen objects» — объекты нельзя было мутировать из нескольких потоков. С new memory manager (по умолчанию с 1.7.20) эта проблема снята, но старый код может содержать @SharedImmutable и @ThreadLocal аннотации.
- Версионирование Kotlin и KSP: KSP (Kotlin Symbol Processing) должен точно совпадать с версией Kotlin. Обновление Kotlin без обновления KSP ломает сборку.
Common mistakes
- Объяснять «KMP и KMM» только как синтаксис и не описывать поведение runtime/compiler.
- Игнорировать важный риск: Не стоит строить архитектуру вокруг устаревающего брендинга KMM вместо targets и source sets проекта.
- Давать пример без edge case: отмены, null, recomposition, platform boundary или ошибки.
What the interviewer is testing
- Формулирует суть темы «KMP и KMM» своими словами и связывает ее с кодом.
- Называет механизм: Сейчас фокус документации смещен к Kotlin Multiplatform как общей технологии, где mobile является частным случаем.
- Видит production-последствие: Не стоит строить архитектуру вокруг устаревающего брендинга KMM вместо targets и source sets проекта.