Flutter versus Kotlin Multiplatform for existing codebases

Jacob Ras
8 min readJul 26, 2023

--

Left: Flutter logo. Right: Kotlin logo.

Cross-platform technologies for code sharing between Android and iOS have existed for a while, maturing from simply running web pages filled with JavaScript in a web view to compiling to platform-native binaries. In this article, I’d like to compare Kotlin Multiplatform with Flutter for existing apps. How do these technologies fit into your existing Android/iOS codebase and can you reuse existing logic or do you need to start from scratch? Let’s find out!

⏩ 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?

Let’s first briefly look at Kotlin itself. Kotlin is a programming language, created by JetBrains. Known for IntelliJ IDEA, they’re the creator of tools developers use to write software for many languages including Java (+ Android), Python, JavaScript and many more.

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.

Overview of multiplatform code pointing to multiple technologies (server, android, iOS, desktop, JS)

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:

Popular apps using Kotlin Multiplatform (KMP) in 2023 — and what you can learn from them

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

Flutter: New knowledge, New code, Rewriting libraries. KMP: Android + back-end knowledge, Reusing existing code, Migration of existing libraries.

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

Flutter: Interop using Engines and Channels. KMP: Interop by just calling code.

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

Flutter: All-in, No exit plan. KMP: Share what makes sense, exit plan = Kotlin 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.

*there are tools to compile Dart to JavaScript and there are several back-end frameworks for Dart (like shelf and dart_frog), but Flutter being mostly used for mobile development means the biggest (mobile) chunk of the codebase will not be reusable.

✨ Flutter versus KMP — USPs

Flutter: Hot reload, Platform styling. KMP: App size, Performance, Tooling.

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 almost 5 MB on both platforms, but that also includes its UI framework. I plan to make a comparison including the Compose UI framework size.

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.

Roadmap

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.

KMP roadmap: 2020 alpha, 2022 beta, 2023 Q4 stable.

Update November 1st, 2023: KMP is now stable!

--

--