There’s strength in having a diversity of languages and tools for software ecosystems. Redundancy enables more resiliency. What seems evident about modern, still evolving but production-active programming languages is they are slowly evolving to converge, sharing more similarities over time. Explicit nullability, type inference, generics, asynchrony at the language-level- this is the “stone soup” we’re making and enjoying. Dart is a part of that, and is evolving by borrowing and growing, because the people involved know there’s value in learning from other languages and ecosystems.
I’d argue the biggest strength of Kotlin is its interoperability with legacy Java code. Companies invested in years or decades of Java code can bring their legacy code (their past investment) along for the ride with Kotlin. I personally also think this one of Kotlin’s biggest weaknesses, because there’s a lot of complexity introduced by the compiler to implement that interoperability.
Kotlin Multiplatform borrows a lot from other languages to provide Compose. The fact that it requires a compiler plugin to build says a lot about just how much effort it takes for Kotlin to function in a declarative and reactive way. Did you know that every Composable is secretly given an extra function parameter. It’s called a context. If that sounds familiar, it’s because it serves a similar purpose as Flutter’s BuildContext. But in Kotlin Multiplatform, the context is hidden from the code. That’s an interesting and different design choice. There’s great value in simply watching to see which approach is more practically effective. Or maybe it doesn’t matter at all. The diversity is the strength here: trying different ways of solving the same problem helps explore the solution space. Where else do fresh ideas come from?
Remember also that technology stacks tend to specialize over the long term. I think Google’s choice of Java and the JVM for mobile devices reflects the lack of other viable options at the time. The impetus for Kotlin, by Google’s own statements, was to offer a more productive choice for Android developers, but without throwing the baby out with the bathwater, so to speak, by abandoning Java altogether. Java’s origins were that it was originally designed to run TV Set Top Boxes. That’s it’s origin story, and you’d be hard-pressed to predict the path Java would take, back in 1996. A lot of Android’s design is based around the limitations of the early hardware. The core zygote process is basically a workaround for slow JVM startup times. Java was a tight fit on Android initially. If the Dart and Flutter of today were around then, I think Android would have a very different shape than it does today.
That’s where I think the OP doesn’t recognize the arc of development that brought both Dart/Flutter and Kotlin to where we are today. Kotlin Multiplatform is playing catch-up to Flutter for interoperability. If you want to write an iOS Kotlin Multiplatform app today, you have a very limited set of third-party libraries which have been retrofitted with the support for iOS. It will take a while for open-source Kotlin libraries to reach parity with the degree to which iOS is already supported in Dart/Flutter, just because Dart/Flutter has had a head-start. And remember, an iOS app in Kotlin Multiplatform cannot import anything from java- it has to be pure Kotlin, with separate code for Android (which could use java) and for iOS (which cannot use any java).
When I started my own app-development journey just 1 year ago, I picked Kotlin Multiplatform, and hoped that Compose Multiplatform would be ready for me. It wasn’t. A year ago, Compose Multiplatform was a 1.0 alpha release where you had to disable the JVM’s garbage collector to have usable performance. That’s since changed, and Compose Multiplatform has come a long way. But it’s still not the case that you can reliably expect any arbitrary third-party open source library to have Kotlin Multiplatform support for iOS. I spent weeks, one year ago trying to map out which third party libraries had Multiplatform support, so I could build an app that would run on iOS or Android… It was painful to find a library that I thought would meet all my needs, only to discover that the supposed Kotlin Multiplatform support for iOS was actually only partial, or so buggy as to be unusable for production. Not a criticism of the open source community, some of whom don’t have the incentive to build and test their libraries for iOS.
I’m not sure there’s a lot of motivation for companies who have invested in writing two separate versions of their apps to immediately decide to drop their Swift/ObjC codebases in order to adopt Kotlin Multiplatform. There’s significant risk in forklifting an entire platform of paying customers with iOS onto a basically entirely different tech stack. Sure, it happens, but it’s not free, either in terms of money or risk. Even though the languages are different, the Sonos mobile app debacle is a perfect case-study in failure to migrate fork-lift style to a new technology stack. The Ars Technica writeup is amazing.
In the end, even if Google decides to bail on Dart/Flutter, there’s enough inertia from non-Google developers that Dart/Flutter won’t die overnight. If it goes moribund, then we move on. It’s not the end of the world, and honestly, having a diverse set of language skills is more valuable than being a one-language-to-rule-them sort of developer. I love my comfort zone as much as the next person, but it’s important to remember that this decade’s comfort zone is often the next decade’s legacy debt. What I hope most for the future of Dart/Flutter is that we develop some of the most amazing apps that push the envelope for beautiful UIs, performant codebases, fast development, fast multi-platform support and app reliability. That’s how we maintain the pressure on Java, Kotlin and Swift. And hopefully have some fun along the way.