More and more people are coding with Kotlin. According to recent MongoDB research, Kotlin is the second-fastest-growing language when it comes to GitHub projects and discussions on Stack Overflow.
It's easy to understand why. Kotlin is pragmatic, modern, and statically-typed. It's winning the hearts of not just Android developers, but backend developers and, increasingly, Java developers too.
Matthew Bartos is X-Team's Kotlin guru. He's been handling Kotlin projects on both the backend and mobile side. In this article, he explores Kotlin's ambition to conquer more platforms.
One Language to Rule Them All
Kotlin/Native lets you create an executable, a static or dynamic library with C headers, or an Apple framework. It can also use existing C, Swift, or Objective-C libraries.
In this article, I will create an Android + iOS multiplatform project. But you don't have to stop there, because you can do all of the following with Kotlin:
- Android app: Kotlin/JVM
- iOS app: Kotlin/Native
- Backend: Kotlin/JVM & Ktor or Spring Boot
- Frontend: Kotlin/JS & React
- Desktop app: Kotlin/Native
Is This Yet Another Flutter?
No, this is not just another Flutter. I understand that developers have mixed opinions about multiplatform mobile frameworks. While sharing code between platforms is generally considered as time-saving and convenient, a shared UI is only considered a good choice for early-stage projects where designs don't need to be pixel-perfect.
Multiplatform Kotlin is probably the closest-to-native app development approach.
In previous articles, I've written about my experience with Multi-OS Engine. It's a similar concept to Kotlin Multiplatform, but it uses a bundled ART VM for translating JVM code to native iOS code. This means that even a simple iOS app is very heavy. But with Kotlin/Native, you get light, native LLVM iOS bytecode.
Multiplatform Kotlin lets you share the logic between the platforms, not the UI.
The typical Kotlin Multiplatform Mobile (KMM) project consists of 3 modules:
- Android: Native JVM Android app with native Android UI
- iOS: Native LLVM iOS app with native iOS UI
- Common: Pure Kotlin logic, used by both Android and iOS apps
Kotlin Multiplatform Mobile
Kotlin Multiplatform Mobile is a set of tools that make it easier to create Android + iOS multiplatform apps. Just keep in mind that KMM is in alpha development and still somewhat unstable. When you install the official KMM plugin and create a new project, it'll automatically set up these modules:
Following the MVP pattern, the app should have three layers of code:
- Model, responsible for data repositories like APIs or databases
- View, responsible for displaying data from Presenter and passing input to it
- Presenter, responsible for processing the data for View
You want to keep your Model and Presenter in the shared
common module and implement Views in both Android and iOS, where you want them to stay as small as possible.
You cannot use Android's
LiveData in the shared
common module, because it's written in Java. You also cannot use RxJava nor Retrofit. This module needs to contain pure Kotlin code, which complicates things a little bit.
But Kotlin Multiplatform has a solution for that in the form of two new keywords:
actual, which can easily be understood as
In your shared
common module, you can declare classes and functions marked with
expect. Then you need to properly implement them in both your
iosMain modules. For example:
expect val uiDispatcher: CoroutineContext
actual val uiDispatcher: CoroutineContext get() = Dispatchers.Main
actual val uiDispatcher: CoroutineContext get() = IosMainDispatcher
IosMainDispatcher is your custom class, which uses:
By extracting your logic to the shared
common module, you're now able to write blazing-fast unit tests that can cover a lot of successful and unsuccessful use cases. Use mocked API responses and create scenarios that will cover both platforms at the same time!
Kotlin Multiplatform holds a lot of promise, but it's still in its early days.
- Native performance - no additional runtime in your app bundle
- No legacy code - you can start integrating KMM anytime
- No shared UI - pixel-perfect native views
- It's easy to just add iOS to your existing Android app
- Not many pure Kotlin libraries available in the shared
- Still in alpha, not production-ready