KMM vs Flutter vs React Native: Choosing a Cross-Platform Mobile Application Framework
Nowadays, there is a big variety of cross-platform frameworks, including Flutter, React Native and, of course, Kotlin Multiplatform Mobile (KMP). What framework should you choose and why? Let’s try to find out!
Every framework has its pros and cons, and none of them is a magic bullet. To put it simply, your choice depends on the task at hand.
JetBrains team have done an incredible job of optimizing development and code reuse costs. And the code can be reused not only within one platform, but also between different ones (Android and iOS). If your development team want to keep the UI native for each platform, Kotlin Multiplatform Mobile is your go-to choice.
This is because Kotlin Multiplatform does not even support user interface. Instead, it enables you to implement business logic into Android and iOS apps. Its special configuration allows you to create a project that will be compiled into an Android library with Android-specific code, and into an iOS framework with iOS-specific code. From a technical standpoint, this means that you can use the same code in iOS and Android at the same time. When you debug your code, you only have to edit it once to see changes on both platforms. However, there are certain elements on the native end of the app that should be left out of the common code:
● the entire UI;
● interface binding to the common ViewModel from the common code library;
● platform-dependent features: camera interaction, NFC, Touch ID, or Bluetooth.
And generally speaking, a common UI on different platforms is not even necessary. For completely uniform UI, you will have to do multiple iterations to make the UI and app behavior more native. Naturally, this requires additional development cycles.
Flutter uses canvas from the native SDK for multiple platforms and draws its UI components using Material Design specifications. React Native uses its own components in JS code. React allows you to update the app logic without rebuilding the project and uploading it to the store (JS code is loaded from servers and starts working on the device immediately, so you don't have to update the entire app).
Another benefit of using Flutter is a unified design for all operating system versions and even between different operating systems. On top of that, this framework lets you easily customize your design. It is probably pointless to compare high development speed and performance of Flutter to other frameworks, since this is definitely its strong side.
Kotlin Multiplatform Mobile has no intermediate layers, which virtually eliminates any interaction bottlenecks. And since Kotlin Multiplatform works with native ecosystems of each platform, developers can use the tools and libraries they have always used, including Swift UI and Jetpack Compose. If you face any limitations, you can always overcome them with Kotlin, Swift, or any other language that is convenient for solving specific problems with minimal risks. However, you have to stick to Dart in case of Flutter and to JS in case of React Native.
Unlike React Native, Kotlin Multiplatform does not require using VM. Even though Flutter does not require VM for development either, you have to use a non-native language for a non-native ecosystem. At the same time, Kotlin Multiplatform makes it easy to write your own code at any level of abstraction and at any layer of architecture.
Unlike Flutter or React Native, where you have to keep working with their infrastructure, KMM can be integrated into any existing project. KMM integration can be done in steps, so you don’t have to put the development on hold. We prepare a roadmap on extending KMM integration with a project, so that we could release an app to the store after each step. Another point to note is that we extend KMM use in line with the current app code, which helps us to avoid introducing new bugs into the project.
A KMM project requires only one engineer to create the shared code and the native part for the respective platform. A specialist working in another platform has to just integrate the user interface into the existing logic. The code is written once, which eliminates the risk of getting two bugs instead of one.
As a result, you can cut costs on developing and maintaining an app, implement functions much faster, and stay completely native both on the developer and the user side at the same time.