Kotlin Multiplatform is a powerful tool that allows developers to write shared code for Android and iOS applications. By leveraging the Kotlin language and its unique compiler architecture, KMP offers a way to build robust native applications. In this blog post, we will delve deep into how KMP works internally, exploring the various components such as the Kotlin compiler, front-end and back-end compilers, JVM and LLVM compilers, iOS targets, and the Commonizer.
How the Kotlin Compiler Works
The Kotlin compiler is a program that translates code written in Kotlin into a lower-level code that a machine can understand. The compiler consists of two main components:
- Frontend Compiler: This component is responsible for parsing the Kotlin code, verifying syntax and semantics, and building an intermediate representation (IR) of the code.
- Backend Compiler: The backend compiler takes the IR produced by the frontend compiler and translates it into machine code or bytecode for the target platform (JVM, Native, or JavaScript).

Kotlin Frontend Compiler
The Kotlin frontend compiler processes the Kotlin source code and performs a series of steps such as lexical analysis, parsing, semantic analysis, and type checking. It builds a syntax tree that represents the structure of the code, which is then transformed into an intermediate representation (IR). This IR is used by the backend compilers to generate platform-specific executables.
Multiple Backend Compilers
Kotlin has different backend compilers that target specific platforms:
- Kotlin/JVM Compiler: Generates Java bytecode that runs on the JVM or Android.
- Kotlin/Native Compiler: Uses LLVM to generate native binaries for platforms like iOS, macOS, and Linux.
- Kotlin/JS Compiler: Translates Kotlin code into JavaScript, allowing it to run on web browsers and Node.js.
Each of these backends works with the common IR produced by the frontend compiler, ensuring that code can be shared across different platforms.
Job Offers
How the JVM Compiler Works
The Kotlin/JVM Compiler translates Kotlin code into Java bytecode, which is compatible with the Java Virtual Machine (JVM). This allows Kotlin to interoperate seamlessly with Java and leverage the vast Java ecosystem.
The generated bytecode can run on any JVM, including Android’s Dalvik and ART (Android Runtime) environments. On Android, additional steps are required to convert the Java bytecode into Dalvik bytecode (.dex) to run on the Dalvik Virtual Machine (DVM) or the Android Runtime (ART).
How the LLVM Compiler Works
The Kotlin/Native Compiler uses the LLVM (Low-Level Virtual Machine) infrastructure to compile Kotlin code into native binaries. This approach is particularly useful for platforms like iOS, where a direct compilation to native code is required.
LLVM provides an intermediate representation that can be further optimized and transformed into platform-specific machine code. Kotlin/Native leverages this capability to produce binaries and frameworks for iOS, which can interoperate with Swift and Objective-C codebases.
iOS Targets
KMP supports multiple iOS targets to cater to different CPU architectures. The main targets are:
- Arm64: Used by all modern iOS devices.
- x64: Used for iOS simulators running on Intel-based Macs.
- Arm32: An older architecture no longer in common use.
KMP allows developers to share code between these different iOS architectures without duplicating platform-specific implementations, thanks to its flexible targeting system.
Commonizer
The Commonizer tool in KMP helps developers avoid duplicating code when targeting multiple architectures or platforms. It automatically infers common dependencies and creates intermediate source sets that can be shared between targets, such as iOS and macOS.
The Commonizer allows developers to write shared code for similar platforms and reduces the boilerplate code needed for different targets, making it easier to maintain and scale KMP projects.
Conclusion
Kotlin Multiplatform Mobile (KMP) offers a unique way to build cross-platform applications by reusing code across different platforms while maintaining native performance and interoperability. By understanding the internal workings of the Kotlin compiler, frontend and backend compilers, JVM and LLVM compilation processes, iOS targets, and the Commonizer, developers can better leverage KMP to build robust, high-performance applications.
This article is previously published on proandroiddev.com