Kotlin/Native — to kompilator kodu Kotlin bezpośrednio do natywnego kodu maszynowego, działający bez maszyny wirtualnej. W przeciwieństwie do wersji JVM, Kotlin/Native używa backendu LLVM do generowania plików wykonywalnych dla iOS, Android NDK, macOS, Windows, Linux i WebAssembly. Technologia ta stanowi fundament Kotlin Multiplatform i umożliwia wykonywanie wspólnego kodu na platformach, gdzie JVM jest niedostępna. Według JetBrains, 2025, Kotlin/Native obsługuje 13 platform docelowych i pozwala na ponowne wykorzystanie do 90% kodu w projektach KMM.
Najważniejsze
Kotlin/Native — to technologia kompilacji kodu Kotlin do natywnego kodu maszynowego, opracowana przez firmę JetBrains. Główna różnica w stosunku do Kotlin/JVM polega na braku konieczności posiadania maszyny wirtualnej — gotowy plik wykonywalny zawiera tylko kod maszynowy i minimalne środowisko uruchomieniowe. Pozwala to uruchamiać aplikacje Kotlin na urządzeniach i systemach, gdzie JVM nie jest obsługiwana, w tym iPhone, Apple Watch i systemy wbudowane.
Historia Kotlin/Native rozpoczęła się od projektu — eksperymentalnego kompilatora, który w 2017 roku został zintegrowany z główną gałęzią Kotlin. W 2019 roku na KotlinConf ogłoszono wsparcie dla iOS jako platformy docelowej, co stało się punktem zwrotnym dla programowania mobilnego. Od wersji Kotlin 1.9.20 kompilator Kotlin/Native osiągnął stabilność i jest domyślnie zawarty w Kotlin Multiplatform.
Kluczową cechą Kotlin/Native jest użycie wspólnej reprezentacji pośredniej IR, która jest kompilowana do kodu maszynowego dla każdej platformy osobno. Zapewnia to jednolity frontend kompilacji dla wszystkich backendów Kotlin: JVM, JS i Native.
Kompilacja Kotlin/Native przechodzi przez kilka etapów transformacji. Kod źródłowy w Kotlin najpierw jest przekształcany w reprezentację wewnętrzną, następnie optymalizowany i przekazywany do backendu LLVM w celu generowania kodu maszynowego. Ostatnim etapem jest linkowanie z bibliotekami uruchomieniowymi i utworzenie pliku wykonywalnego lub biblioteki dynamicznej.
Architektura obejmuje trzy kluczowe komponenty: frontend (parsowanie i sprawdzanie typów), generator IR (budowanie reprezentacji pośredniej) i backend LLVM (generowanie kodu maszynowego). Ten schemat jest podobny do podejścia stosowanego w kompilatorach Clang dla C++ i Rust.
// Kompilacja Kotlin/Native przez wiersz poleceń
kotlinc-native hello.kt -o hello -opt
// Budowanie dla iOS arm64 przez Kotlin Multiplatform
./gradlew :shared:linkDebugFrameworkIosArm64
Do zarządzania pamięcią Kotlin/Native używa własnego Memory Managera, opartego na zliczaniu referencji z detektorem cyklicznym. Od Kotlin 1.7.20 nowy menedżer pamięci działa domyślnie i nie wymaga adnotacji @ThreadLocal ani @SharedImmutable. Garbage collector działa bez zatrzymywania wątków, co jest krytyczne dla iOS, gdzie system może wymusić zamknięcie aplikacji przy długotrwałym blokowaniu głównego wątku.
Proces kompilacji dzieli się na pięć etapów: parsowanie (analiza kodu źródłowego), analiza semantyczna (sprawdzanie typów i rozwiązywanie nazw), generowanie IR (budowanie reprezentacji pośredniej), optymalizacja (upraszczanie i usuwanie martwego kodu) oraz generowanie kodu przez LLVM. Każdy etap może być wykonywany równolegle dla różnych modułów, co przyspiesza budowę dużych projektów.
| Etap | Czas trwania | Rezultat |
|---|---|---|
| Parsowanie | ~10% czasu | Drzewo AST kodu źródłowego |
| Analiza semantyczna | ~20% czasu | Typizowane AST |
| Generowanie IR | ~15% czasu | Kotlin IR (Intermediate Representation) |
| Optymalizacja | ~25% czasu | Zoptymalizowany IR |
| Kod generacja LLVM | ~30% czasu | Kod maszynowy + plik wykonywalny |
Kotlin/Native obsługuje 13 platform docelowych, podzielonych na kategorie. Dla programowania mobilnego dostępne są iOS (arm64), Android (arm32, arm64, x86_64) i watchOS. Platformy desktopowe obejmują macOS (x64, arm64), Windows (mingw x64) i Linux (x64, arm64, arm32). Do programowania serwerowego i wbudowanego dostępne są WebAssembly oraz Kotlin/Native na LLVM bez systemu operacyjnego (standalone). Każda platforma wymaga osobnego frameworka lub biblioteki na wyjściu.
Dla iOS Kotlin/Native generuje uniwersalny framework (.framework), który może być podłączony do projektu Xcode. Dla Android NDK tworzone są natywne biblioteki .so, które można wywoływać przez JNI. Platforma watchOS jest obsługiwana od Kotlin 1.6.0, a tvOS — od wersji 1.7.0. Każda architektura wymaga osobnej kompilacji, ale Kotlin Multiplatform automatyzuje ten proces przez plugin Gradle.
macOS i Linux są używane do tworzenia natywnych aplikacji desktopowych w Kotlin z wykorzystaniem frameworka Compose Multiplatform. Platforma Windows (MinGW) jest obsługiwana od Kotlin 1.3.70 i umożliwia tworzenie aplikacji Windows bez instalacji JVM. Do programowania serwerowego Kotlin/Native może być używany w środowiskach, gdzie JVM jest niedostępna, na przykład w kontenerach Docker z minimalnym obrazem opartym na scratch lub Alpine.
| Kategoria | Platforma | Architektura |
|---|---|---|
| Mobilne | iOS | arm64, simulator (x64, arm64) |
| Mobilne | Android NDK | arm32, arm64, x86, x86_64 |
| Noszone | watchOS | arm64, simulator (x64) |
| Desktop | macOS | x64, arm64 |
| Desktop | Windows | mingw x64 |
| Desktop | Linux | x64, arm64, arm32 |
iOS jest główną platformą docelową Kotlin/Native w kontekście KMM. Kompilator tworzy framework iOS zawierający cały wspólny kod, który następnie jest podłączany do projektu Xcode. Framework obsługuje zarówno statyczne, jak i dynamiczne łączenie. Kotlin/Native generuje opakowania Objective-C dla klas i funkcji Kotlin, zapewniając bezpośrednią integrację z kodem w Swift i Objective-C.
Integracja z iOS wymaga konfiguracji Xcode do podłączenia wygenerowanego frameworka. Kotlin Multiplatform automatyzuje ten proces za pomocą zadania embedAndSignAppleFrameworkForXcode, które jest uruchamiane z Xcode Build Phases. Do debugowania Kotlin/Native obsługuje breakpointy w kodzie wspólnego modułu podczas uruchamiania aplikacji na symulatorze iOS.
// Kod Kotlin skompilowany do frameworka iOS
package com.itsectr.shared
class GreetingProvider {
fun createGreeting(): String {
return "Hello from Kotlin/Native!"
}
fun formatVersion(major: Int, minor: Int): String {
return "v$major.$minor"
}
}
Interop z kodem iOS działa w obie strony. Kotlin/Native generuje nagłówki Objective-C dla klas Kotlin, które automatycznie stają się dostępne ze Swift. Komunikacja zwrotna jest zapewniana przez adnotację @ObjCName do eksportowania funkcji Kotlin pod określoną nazwą Objective-C. Kolekcje Kotlin automatycznie konwertują się na NSArray i NSDictionary, a korutyny Kotlin są opakowywane w Combine publishers przez bibliotekę SKIE. Do pracy z frameworkami iOS z Kotlin używany jest cinterop — narzędzie do generowania wiązań Kotlin do nagłówków Objective-C.
Aby rozpocząć pracę z Kotlin/Native, wymagana jest konfiguracja build.gradle.kts z określeniem pluginu Kotlin Multiplatform i platform docelowych. Rozważmy minimalną konfigurację dla projektu KMM z obsługą iOS i Android.
plugins {
kotlin("multiplatform") version "2.0.21"
}
kotlin {
iosArm64()
iosSimulatorArm64()
sourceSets {
commonMain.dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0")
}
iosMain.dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0")
}
}
}
Po skonfigurowaniu budowania można dodać kod zależny od platformy. Kotlin/Native zapewnia dostęp do funkcji iOS przez opakowania Kotlin. Na przykład pobranie UUID urządzenia na iOS wymaga wywołania NSUUID z Foundation.
import platform.Foundation.NSUUID
fun getDeviceId(): String {
return NSUUID().UUIDString()
}
fun currentTimestampMillis(): Long {
return (platform.Foundation.NSDate().timeIntervalSince1970 * 1000).toLong()
}
Do wygenerowania frameworka iOS używane jest zadanie Gradle linkDebugFrameworkIosArm64 lub linkReleaseFrameworkIosArm64 dla produkcji. Po kompilacji framework znajduje się w build/bin/iosArm64/debugFramework/. Podłączenie do projektu Xcode odbywa się przez Pods Podfile lub dodanie frameworka w sekcji General → Frameworks, Libraries and Embedded Content.
// Budowanie frameworka release dla iOS arm64
./gradlew :shared:linkReleaseFrameworkIosArm64
// Budowanie uniwersalnego frameworka x86_64 + arm64
./gradlew :shared:linkReleaseFrameworkIosX64 \
:shared:linkReleaseFrameworkIosArm64
// Utwórz XCFramework dla App Store
./gradlew :shared:assembleReleaseXCFramework
Kotlin/Native i Kotlin/JVM różnią się architekturą, wydajnością i obszarem zastosowania. Kotlin/JVM kompiluje kod do bajtkodu wykonywanego na JVM, co daje dostęp do ogromnego ekosystemu bibliotek Java, ale wymaga zainstalowanej maszyny wirtualnej. Kotlin/Native generuje plik wykonywalny bez zewnętrznych zależności, ale z bardziej ograniczonym ekosystemem bibliotek.
Wydajność czasu uruchamiania Kotlin/Native jest wyższa, ponieważ nie wymaga ładowania JVM. Według benchmarków JetBrains, aplikacja Hello World na Kotlin/Native uruchamia się w 0.003 sekundy, podczas gdy Kotlin/JVM potrzebuje 0.5–1 sekundy na załadowanie maszyny wirtualnej. Jednak rozmiar pliku wykonywalnego Kotlin/Native może być 2–3 razy większy z powodu dołączonego środowiska uruchomieniowego.
| Cecha | Kotlin/Native | Kotlin/JVM |
|---|---|---|
| Platformy docelowe | iOS, macOS, Windows, Linux, WebAssembly, embedded | Serwery, Android, desktop (JVM) |
| Zależności | Bez środowiska uruchomieniowego (samodzielny) | Wymaga JVM (JDK/JRE) |
| Czas uruchamiania | ~3 ms | ~500–1000 ms |
| Ekosystem | Ograniczony (Kotlin + Interop) | Pełny (Kotlin + Java + Android SDK) |
| Rozmiar binarki | ~1–5 MB (ze środowiskiem) | ~100–500 KB (JAR) |
Wybór między Kotlin/Native a Kotlin/JVM zależy od platformy docelowej. Jeśli projekt jest skierowany na iOS lub wymaga minimalnego zużycia zasobów, Kotlin/Native jest jedyną opcją. Do programowania Android Kotlin/JVM pozostaje standardem, chociaż Kotlin/Native jest używany do komponentów NDK, gdzie potrzebna jest natywna wydajność. W projektach wieloplatformowych Kotlin Multiplatform łączy oba podejścia: wspólny kod jest kompilowany przez Kotlin/Native dla iOS i przez Kotlin/JVM dla Android.
Często zadawane pytania
Kotlin/Native kompiluje kod do natywnego kodu maszynowego bez maszyny wirtualnej, a Kotlin/JVM — do bajtkodu wymagającego zainstalowanej JVM. Kotlin/Native jest używany dla iOS, systemów wbudowanych i WebAssembly, Kotlin/JVM — dla Android i serwerów.
Tak, Kotlin/Native może być używany jako samodzielny kompilator do tworzenia aplikacji konsolowych, natywnych pluginów lub bibliotek dla dowolnej obsługiwanej platformy. KMM tylko upraszcza organizację kodu wieloplatformowego.
Memory Manager Kotlin/Native używa zliczania referencji z automatycznym detektorem cyklicznym. Od Kotlin 1.7.20 garbage collector nie wymaga adnotacji @ThreadLocal i działa bez zatrzymywania głównego wątku iOS.
Przez cinterop dostępne są wszystkie frameworki iOS: Foundation, UIKit, CoreData, CoreBluetooth, MapKit i setki innych. JetBrains dostarcza gotowe wiązania dla standardowych bibliotek iOS w składzie Kotlin/Native.
Do debugowania używane jest Xcode z podłączonym frameworkiem Kotlin/Native. Breakpointy w kodzie Kotlin działają podczas uruchamiania na symulatorze iOS. Dla urządzenia wymagana jest kompilacja Debug i profil deweloperski Apple.
Podsumowanie
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.
Przeczytaj również