Kotlin Multiplatform: co to jest, shared module i expect/actual

Autor: IT Sectr Opublikowano: 2026-02-11 Czas czytania: 11 min

Kotlin Multiplatform (KMP) — technologia JetBrains, kompilująca wspólny kod Kotlin na iOS, Android, Web i Desktop. W przeciwieństwie do Flutter i React Native, KMP nie zastępuje natywnego UI — wspólna logika jest wyodrębniana w shared module, a interfejs każdej aplikacji pozostaje natywny. Kotlin Multiplatform documentation — główne źródło informacji o konfiguracji modułów i mechanizmie expect/actual.

Najważniejsze

  • KMP — wspólna logika w Kotlin z expect/actual dla platformowych API bez zastępowania natywnego UI
  • Shared module — moduł Gradle z kodem zapytań sieciowych, baz danych, walidacji i logiki biznesowej dla wszystkich platform
  • Expect/actual — mechanizm deklarowania platformowego API we wspólnym kodzie z implementacją dla każdego celu
  • iOS integration — shared module kompiluje się do Apple framework przez Kotlin/Native
  • KMP vs KMM — Kotlin Multiplatform Mobile (mobilny fokus) jest teraz częścią ogólnego Kotlin Multiplatform

Czym jest Kotlin Multiplatform?

Kotlin Multiplatform — technologia cross-kompilacji, pozwalająca pisać wspólny kod w Kotlin i kompilować go na różne platformy: JVM (Android), LLVM (iOS, macOS, watchOS), JavaScript (Web) i natywne binarne (Linux, Windows). KMP nie jest frameworkiem UI — rozwiązuje problem ponownego wykorzystania logiki biznesowej, a nie interfejsów.

Architektura KMP opiera się na shared module — module Gradle zawierającym commonMain z niezależnym od platformy kodem i source sets dla każdego celu (androidMain, iosMain, desktopMain). Według danych JetBrains z 2025 roku, ponad 40% nowych projektów Kotlin używa KMP do współdzielenia kodu między platformami.

Kotlin Multiplatform Mobile (KMM) — poprzednia nazwa dla scenariusza mobilnego iOS+Android. Od Kotlin 2.1+ termin KMM został zastąpiony ogólnym Kotlin Multiplatform, ponieważ technologia wyszła poza rozwój mobilny. Netflix, McDonald's i VMware używają KMP w produkcji do współdzielenia kodu między aplikacjami mobilnymi.

Mechanizm expect/actual: architektura

Expect/actual — kluczowy mechanizm KMP do pracy z kodem platformowym. W commonMain deklarowana jest expect-deklaracja (funkcja, klasa, property), a w każdym platform-specific source set (androidMain, iosMain) — actual-implementacja. Kompilator sprawdza, czy dla każdego expect istnieje actual na każdej docelowej platformie.

kotlin
// commonMain — deklaracja platformowego API
expect fun getPlatformName(): String

expect class PlatformContext(val appVersion: String)

// androidMain — actual pod Android
actual fun getPlatformName(): String = "Android \${Build.VERSION.SDK_INT}"

// iosMain — actual pod iOS
actual fun getPlatformName(): String =
    UIDevice.currentDevice.systemName

Hierarchia source sets w KMP pozwala tworzyć pośrednie poziomy: na przykład iosArm64Main (fizyczne urządzenia iOS) i iosSimulatorArm64Main (symulator) ze wspólnym iosMain. Kod z commonMain jest dostępny dla wszystkich platform, a kod z iosMain — tylko dla celów iOS. Zmniejsza to powielanie, gdy implementacja różni się nie dla każdej platformy, ale dla grupy platform.

W praktyce expect/actual jest używane do: uzyskiwania lokalnego magazynu (SharedPreferences vs NSUserDefaults), pracy z siecią (HttpEngine pod każdą platformę), dostępu do systemu plików, kryptografii i analityki. JetBrains zaleca minimalizowanie liczby expect/actual i przenoszenie jak największej ilości kodu do commonMain.

Shared module: struktura i Gradle

Shared module — standardowy moduł Gradle z pluginem `org.jetbrains.kotlin.multiplatform`. Zawiera wspólny kod w `src/commonMain/kotlin/` i implementacje platformowe w `src/androidMain/kotlin/` oraz `src/iosMain/kotlin/`. Projekt KMP podłącza także `androidApp` i `iosApp`, które zależą od shared module.

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")
            }
        }
    }
}

Konfiguracja Gradle dla KMP wymaga jawnego wskazania celów iOS — x64 (symulator Intel), arm64 (fizyczne urządzenia) i simulatorArm64 (symulator Apple Silicon). Dla każdego celu generowany jest osobny Apple framework. Plugin `kotlin("multiplatform")` automatycznie konfiguruje kompilację pod JVM i LLVM w zależności od zadeklarowanych targetów.

Ktor i kotlinx.serialization — standardowe biblioteki KMP wspierające wspólny kod. Ktor dostarcza klienta HTTP z silnikami dla każdej platformy (OkHttp dla Androida, Darwin dla iOS). kotlinx.serialization działa na dowolnych platformach bez expect/actual dzięki wieloplatformowej implementacji w commonMain.

Integracja z iOS przez Kotlin/Native

Kotlin/Native — kompilator Kotlin do kodu natywnego przez LLVM. Dla iOS shared module kompiluje się do Apple framework (.framework), który jest podłączany przez Xcode. Wywoływanie wspólnego kodu z Swift/Objective-C odbywa się przez wygenerowane nagłówki Objective-C, dlatego API shared module musi być kompatybilne z Objective-C.

Ograniczenia integracji iOS: Kolekcje Kotlin (List, Map) są konwertowane na NSArray/NSDictionary. Funkcje z parametrami domyślnymi nie są eksportowane — potrzebne są overloady. Dla suspend-funkcji generowane są metody oparte na callback z `@ObjCName` i wsparciem async/await od Kotlin 2.0+.

swift
// Aplikacja iOS: wywołanie shared module z Swift
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)")
            }
        })
    }
}

Integracja shared module w Xcode odbywa się przez embed-and-framework — wygenerowany `.xcframework` jest dodawany do projektu Xcode. Plugin Gradle może automatycznie aktualizować framework przy budowie przez embedAndSignAppleFrameworkForXcode. Do testowania na symulatorze wystarczy iosSimulatorArm64 lub iosX64 binary.

KMP vs Flutter vs React Native

Wybór między KMP, Flutter i React Native zależy od priorytetu: ponowne wykorzystanie logiki czy pełna wieloplatformowość. KMP zapewnia natywny UI na każdej platformie, ale wymaga dwóch baz kodowych dla interfejsu. Flutter i React Native używają jednego UI, ale tracą na natywności.

CechaKMPFlutterReact Native
Framework UINatywny (Android XML/Jetpack Compose + SwiftUI)Dart + własny renderer SkiaReact + natywne komponenty
Wspólny kodLogika biznesowa, sieć, bazy danych, walidacja100% oprócz natywnych pluginów100% oprócz natywnych modułów
WydajnośćNatywna (bez pośredniej warstwy)Wysoka (Skia Engine)Średnia (JSI Bridge)
Wsparcie iOSKotlin/Native (doskonałe)DoskonałeDobre
Próg wejściaŚredni (Kotlin + platformy natywne)Niski (jeden język + jeden UI)Niski (JS/TS + React)

Kiedy wybrać KMP: projekt wymaga wydajnego UI (gry, mapy, animacje), istniejący kod natywny trzeba wykorzystać ponownie, zespół zna już Kotlin i platformy natywne. Kiedy wybrać Flutter/RN: MVP lub startup z ograniczonym budżetem, zespół jednego profilu, UI nie wymaga głębokiej natywnej personalizacji.

Narzędzia i biblioteki KMP

Ekosystem narzędzi KMP obejmuje biblioteki dla wszystkich warstw aplikacji: sieć (Ktor), serializacja (kotlinx.serialization), bazy danych (SQLDelight), nawigacja (Decompose), DI (Koin) i przechowywanie danych (multiplatform-settings). JetBrains wspiera Compose Multiplatform — framework UI w Kotlin działający na wszystkich platformach.

kotlin
// Repository na KMP z SQLDelight + Ktor
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 — framework UI dla KMP oparty na Jetpack Compose. Pozwala pisać interfejs w Kotlin dla Android, iOS, Desktop i Web. W 2025 roku Compose Multiplatform osiągnął stabilny status dla Android i Desktop; cel iOS jest w beta. Dla projektów produkcyjnych z natywnym UI zaleta KMP pozostaje główną różnicą od Flutter.

Często zadawane pytania

Czym Kotlin Multiplatform różni się od Kotlin Multiplatform Mobile?

KMM — to mobilny scenariusz KMP dla iOS i Android. Od wersji Kotlin 2.1+ JetBrains połączyła oba terminy w Kotlin Multiplatform, ponieważ technologia wspiera nie tylko platformy mobilne, ale także Desktop i Web. Projekty KMM nadal działają, ale teraz są częścią ogólnego KMP.

Czy można używać KMP z SwiftUI?

Tak. KMP kompiluje się do Apple framework przez Kotlin/Native z nagłówkami Objective-C. SwiftUI importuje ten framework jako zwykłą bibliotekę. Shared module eksportuje klasy i funkcje Kotlin, które są wywoływane z Swift z pewnymi ograniczeniami (na przykład kolekcje Kotlin są konwertowane na typy Foundation).

Jak testować shared module na iOS?

Na iOS shared module jest testowany przez testy Kotlin/Native w source set iosTest. Do testów UI używa się XCTest w Xcode z zaimportowanym frameworkiem. Testy Kotlin pisze się w commonTest z kotlin.test i wykonuje na symulatorze iOS przez task Gradle iosSimulatorArm64Test.

Jakie biblioteki są dostępne w KMP?

Główne biblioteki KMP: Ktor (sieć), kotlinx.serialization (JSON), SQLDelight (bazy danych), Koin (DI), Decompose (nawigacja), multiplatform-settings (SharedPreferences/NSUserDefaults), Apollo GraphQL, Firebase (przez KMP-NativeCoroutines). Compose Multiplatform dostarcza UI dla wszystkich platform.

Czy KMP wspiera Gradle 8?

Tak. KMP jest w pełni kompatybilny z Gradle 8.5+. Od Kotlin 2.1 oficjalne pluginy wspierają Gradle 8. Konfiguracja przez build.gradle.kts z kotlin("multiplatform") wymaga Gradle 7.6+, ale zalecana jest wersja 8.5 dla optymalnej wydajności budowania.

Podsumowanie

  • Kotlin Multiplatform — wieloplatformowa technologia JetBrains dla wspólnego kodu bez zastępowania natywnego UI
  • Expect/actual — mechanizm deklarowania platformowych API w commonMain z implementacjami dla każdego celu
  • Shared module — moduł Gradle z commonMain i platformowymi source sets (androidMain, iosMain)
  • Kotlin/Native kompiluje shared module do Apple framework, wywoływanego z Swift i Objective-C
  • KMP vs Flutter/RN — ponowne wykorzystanie logiki + natywny UI przeciwko jednolitej bazie kodu i UI
  • Compose Multiplatform — framework UI w Kotlin dla Android, iOS, Desktop i Web
  • Ekosystem — Ktor, SQLDelight, Koin, kotlinx.serialization, Decompose dla wszystkich warstw aplikacji

Opracujemy aplikację mobilną pod klucz

IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.

Omów projekt

Przeczytaj również