⏩ Want to go straight to the comparison? It’s down the page. Up next you’ll first find an introduction to KMP.
What is Kotlin?
Kotlin was unveiled in 2011 and in 2017 multiplatform support was added to the language.
Google noticed many Android developers loved this new language and started using it more and more. In 2019, they named it the official language for Android development.
What is Kotlin Multiplatform (KMP)?
Kotlin Multiplatform is a technology built into Kotlin. You write code once and make it run on multiple platforms, from back-end to front-end. This promise sounds similar to Flutter, but it’s very different. It’s not “just another cross-platform technology”, because with KMP you can take Kotlin code you already wrote, documented and tested, and make it multiplatform. For example, any modern Android codebase will be 100% Kotlin and many back-ends are written in Kotlin as well.
Previously, the Android and iOS part of KMP was known as
Kotlin Multiplatform Mobile, or KMM. This name is now superseded by the common KMP name.
What can be shared with Kotlin Multiplatform?
What you generally see with “cross-platform” technologies, is that you need to rebuild all layers in it. Kotlin Multiplatform takes a different approach: you don’t have to make all your code work on multiple platforms, but you can. KMP is not a framework, it’s a technology. You can take existing code and make it multiplatform, whether it’s just a piece of data logic or it’s your whole domain layer. This is a fundamental difference from other cross-platform technologies like React Native and Xamarin.
Frameworks are built with it, though, like Compose UI. That’s Android’s default UI framework, which is now made to work on iOS (alpha), desktop (stable) and even the web (experimental), too.
Who uses Kotlin Multiplatform?
Many companies have already been using KMP in production for several years. I’ve dedicated a special post to showcasing some of them and collecting the resources they’ve posted online about it:
To name just a few: McDonald’s, Netflix, Quizlet and Memrise. Google, creator of Flutter, is migrating Workspace (which consists of Google Docs, Slides, Sheets, Drive and more) towards Kotlin Multiplatform to share logic (from their existing J2ObjC cross-platform tool). They’re going with KMP, because it can handle the requirement to keep their existing native user interface.
Flutter versus Kotlin Multiplatform
Time for the comparison! I’ll focus on three key areas: reuse, interoperability and flexibility. After that, I’ll list some unique advantages of each.
♻️ Flutter versus KMP — 1/3: Reuse
|Knowledge||⬜ New knowledge||✅ Android + back-end devs|
|Existing code||⬜ Only new code||✅ Reusable|
|Existing libraries||⬜ All rewritten||✅ Migration + grants|
Knowledge: Android developers and many back-end developers are already writing Kotlin code for one platform. Learning to make that code compatible with multiple platforms is a lot simpler compared to the task of learning a new language and framework.
Existing code: you can use Kotlin code you already wrote, documented and tested over years in production in your Android/back-end app and make it multiplatform.
Existing libraries: libraries need to be rewritten to work on Flutter. You cannot always use existing, battle-proven libs you currently use, but often need to find new ones. On the Kotlin Multiplatform side, there’s a big migration going on where existing libraries and frameworks are updated to work on multiple platforms. An example of this is the Apollo GraphQL library, or the Compose UI framework being migrated to KMP. JetBrains also has a Grants program where library developers get financial support to help with this migration.
♾️ Flutter versus KMP — 2/3: Interoperability
|✅ Android: It just works™️|
✳️ iOS: Swift calls Objective-C, 🔜 Swift
Since we’re dealing with existing codebases, we want to communicate from the existing, native, code to the cross-platform code. How easy is that? Complete Flutter screens can be integrated into an existing app as a “Flutter screen” (or, on Android, Fragment/View), which requires setting up Engines and configuring them. If you want to re-use your existing domain/data layer(s) for the screens you’re sharing, you’ll need to set up Channels as well, to pass data and events around. Those channels are in JSON format by default, but a tool called Pigeon exist to make it statically typed.
With KMP on Android, there is no integration to write. It’s Kotlin code, which you already use. Shared code can be added as a Gradle module or dependency and calling it is like calling any other code.
On iOS, apps are built in Swift, whereas Kotlin Multiplatform generates an Objective-C header to talk to. This has some limitations, but JetBrains is working on making this Swift. Still, communication is already statically typed by default. It’s like calling any other Objective-C library, without having to setup any engines or channels.
⚡ Flutter versus KMP — 3/3: Flexibility
|Flexibility||⬜ All-in framework||✅ Share what makes sense: data, domain, ui or all of it|
|Exit plan||⬜ None||✅ Android app + back-end code|
Flutter is an all-in framework. You can connect it to your existing domain layer, but the integration mentioned above makes this hard. With Kotlin Multiplatform, you can share what makes sense for you, whether that’s just a small part of domain logic, some UI (with Compose) or all of it.
An important thing to consider with new technologies is the exit plan. If you try Flutter but figure out it’s not working for you, what are you left with? A codebase with unusable* Dart code. Any Kotlin Multiplatform code can always be used in Android and back-end apps. This makes KMP a safe bet to try.
✨ Flutter versus KMP — USPs
|USPs||✅ Hot reload|
✅ Platform styling
|✅ App size|
Adding to the comparison above, each technology has its own Unique Selling Points. Flutter has “Hot Reload“, an awesome technology to see live updates of code in a running emulator or device. Kotlin Multiplatform has this only for UI, if you use Compose UI. Another pro is the default platform styling, where on Android everything looks like Material Design and on iOS everything looks like the Cupertino widgets. For Compose UI, there’s a library called Compose Look and Feel, but it’s not integrated by default currently.
A “hello world” example in KMP adds less than half a megabyte to an iOS build. With a bunch of libraries and code this could go up to (and above, of course) 1,5 MB. This, again, is made possible by the flexibility of the technology mentioned above: only share the code you want to share. Note that on Android the added size is zero, because Android apps already use Kotlin. To compare: Flutter adds more than 5 MB on Android and even more on iOS, but that also includes its UI framework. Compose Multiplatform’s alpha iOS version has a similar size impact on iOS. See my full comparison here: Native versus Flutter versus Compose Multiplatform.
To make Flutter screens that are integrated into an existing app perform well, it’s recommended to “pre-warm” the Engine(s). This takes 1.5 seconds (of which 330ms blocking the main thread) and uses 42 MB of memory on a low-end device from 2015. On iOS it’s 860ms (260 blocking) and 22 MB. This performance penalty does not exist with KMP.
Being developed by JetBrains, creator of IntelliJ, Kotlin has great tooling support. There are plugins available to make debugging Kotlin code possible in XCode. Note that IntelliJ can also be used to write Flutter apps/Dart code, but since Jetbrains is the creator of both the IDE and the language, I list this USP there. Kotlin is by default supported by code analysis tools like SonarQube, but for Flutter there’s third-party support available.
Conclusion and final thoughts
I dedicated a big part of this to comparing the two technologies, but keep in mind that because of Kotlin Multiplatform’s flexibility, it can even be used alongside other cross-platform solutions. For example, Shopify has a React Native app that suffered from slow performance in a synchronisation job. They introduced KMP to solve this specific issue. This versatility alone is why I think Kotlin Multiplatform is great.
For new apps, Flutter offers an impressive and powerful cross-platform framework, keeping the abovementioned limitations in mind. For existing apps, consider how much code and knowledge (Android + back-end devs) you already have and could reuse with Kotlin Multiplatform. Kotlin syntax is easy to learn for iOS developers too, because it follows concepts similar to Swift. It’s already used for years in production by big apps and your codebase, too, is ready to start being efficiently shared amongst multiple platforms.
In September 2020, Kotlin Multiplatform graduated to Alpha. Two years later, in September 2022, it was ready to be called Beta. At this point several companies (some shown in the picture below) were already successfully using it in production.
This year, Q4, it will be marked stable. There’s no question about whether KMP is ready for production.
Update November 1st, 2023: KMP is now stable!