As someone that does Kotlin Multiplatform mobile as my day job and Flutter on the side I feel uniquely qualified to weigh in on this.
The first thing that must be made clear in any discussion on cross-platform mobile development is that XCode, iOS storyboards, and Swift REALLY, REALLY SUCK!! They are absolute torture to use. And I mean torture in the sense that they should be outlawed by the Geneva Conventions kind of torture. If given a choice between XCode/Swift development and water boarding I would suggest water boarding. And note that 10 years ago I used to do iOS development in Objective-C but that was not cross-platform. Realize that anything Apple does is not to make your life better, but to lock you into their ecosystem.
On the other hand you have Kotlin which is a pleasure to develop in. You have excellent tools in Idea/AndroidStudio, though I understand people who wish for VSCode support.
So where does Dart/Flutter fall here. Dart as a language I would put in between Java and Kotlin. It is better than Java and while it has recently moved closer to Kotlin with things like null-safety and extensions there will probably always be a gulf between it and Kotlin. Some of the notable things separating it:
- semicolons: Seriously sucks to have to terminate every line
- Inferior lambdas: Syntax is closer to Java syntax. No implicit
it, no lambdas with receivers, no putting a lambda outside the parentheses
- No function receivers. While they do now have extensions it is not as powerful without this
- Primitive enums, they are just names for integer constants
- No reflection at all
- No data classes
Some of these are worked around by builders that can generate code for you, which works but is sometimes cumbersome and I would choose Kotlin over that any day.
So with KMM you end up writing your common business logic in Kotlin. You have to write your UIs separately. For Android that is not too bad as you are still in Kotlin. For iOS that means submitting to the torture of XCode, Swift and Storyboards. Storyboards are a nightmare on a team as they are the source of indecipherable merge conflicts. There are also difficulties here because the way Kotlin is exposed to Swift in often less than ideal. You can use SwiftUI (if you don’t want to support older devices) which improves things a bit, but I am less familiar with it, though we are moving to it on my project. If you need platform-specific code you can also do that in Kotlin.
So by lines of code probably 60% of your code is the common business logic, 15% Android UI, and 25% iOS UI. That is by lines of code, by development time the iOS side is probably 50%.
There are 3 major pieces I see that differentiats Flutter in this discussion:
- A cross-platform, declarative UI framework that is built on top of Skia that allows building the UI once and still achieving a native look and feel. This is Flutter’s killer feature
- A mechanism to make calls to platform specific code. The is done through channels where data can be sent back and forth, which is sort of like API calls to a server. You have to provide serialization/deserialization on either end and the two ends do not share common memory. But to write that Platform specific code you are using platform-specific tools and languages (Java/Kotlin on Android and Swift/Objective-C on iOS)
- An incredible hot reload functionality that makes changes to the running app without even doing a build. Just save the file and it can show up instantly in the running app.
1 and 3 are the big plusses here for Flutter. Number 2 along with Dart being an inferior language to Kotlin are minuses in comparison to KMM. So can you put up with an inferior language and harder platform-specific code (which is rare) to get the benefits of 1 and 3.
What I want to see is #1 the cross platform UI framework in KMM. I would gladly give up #3, the hot-reload technology in order to get this. Jetpack Compose is very much like Flutter’s UI framework, but is Android (and soon desktop as well) only.
But the thing is there is actually nothing stopping a team from being able to accomplish this. Flutter is open-source and there is nothing stopping anyone from porting that UI to be KMM based. Or alternatively, Jetpack Compose could be extended to include UI for iOS.
If I had that ability to do cross-platform UI in KMM like I can in Flutter and never have to touch Swift or XCode, I would never write another line of Flutter. That would be the best of all worlds. Unfortunately, I know I am too old to take on such a project.