Kotlin Multiplatform Mobile — what’s all the fuss?
KMM’s the latest kid on the block when it comes to building mobile. At Octopus Energy we’ve been experimenting with KMM for the last ~9 months and have built an app from the ground up using the technology. So what’s it all about? And should you be giving it a shot?
This post’s intended as a conceptual overview of KMM, and in the following few posts i’ll go into details of how we’ve found it to work in practice.
Want to work with KMM, Jetpack Compose, SwiftUI; AND make a dent in climate change?
Octopus Energy is always hiring talented, passionate mobile developers, so if you like what you see here please reach out! Or apply directly at: https://jobs.lever.co/octoenergy
Developing mobile apps
When it comes to building mobile you’ve historically had a selection of options that fit into two main categories. Cross Platform UI or Native.
Which options better is a bit of minefield as developers usually specialise on only one of the options, so their jobs often rely on fighting their respective corner…which leads to some strong views either way.
At a high level it can usually be considered that cross platform UI is king when user experience is low priority and time/cost are high priority, native is king in the reverse. But why? And where does KMM fit in?
Cross platform UI — the impossible job
Cross-platform UI is built on the concept of creating a single framework which outputs apps for multiple platforms with a single team working on a single codebase — write once, run anywhere.
Write once, run anywhere sounds like a winning strategy, right? But writing a common framework across two operating systems is incredibly hard.
The Android or iOS systems we build apps with clock in at over 10 million lines of code written over more than a decade. And they’re not finished, yearly both operating systems receive a mountain of updates to their core packages, not to mention the huge ecosystem of libraries surrounding them (e.g. androidx).
And these systems are built by two of the biggest companies in the world — backed by the accompanying resources they have at their disposal.
Inevitably cross platform UI frameworks struggle to keep up, have issues with performance, become plagued by bugs, and as things get more complex, need native developers to build functionality which isn’t supported by the framework.
After a few years, a new framework comes out — without the legacy problems — and developers move on.
No cross platform UI framework has ever truly made it out of the trough of disillusionment.
Trough of Disillusionment
Interest wanes as experiments and implementations fail to deliver. Producers of the technology shake out or fail. Investment continues only if the surviving providers improve their products to the satisfaction of early adopters.
Cross platform UI may struggle to become the go-to, long-term, development choice for the majority of projects, but it does fulfil a purpose. If you want to build an app quickly across multiple platforms and you lack resources, cross platform UI is the way to go. Nacent startups, hobby projects, agencies, prototypes — these are all areas where cross platform UI shines.
Native — expensive duplication
Native development allows you to have complete freedom to use the platform to its full potential, and gives you access to the entire ecosystem — giving you the ability to make the best possible user experience.
But there’s a cost in money and time.
The teams on a native project are fundamentally separate and made up of people with wildly different skillsets and experience. They work on different codebases, written in separate languages, to separate standards for everything from code quality to architecture.
Requirements need planned & communicated to each team which usually each work at different speeds. Problems are solved twice for very similar problems — often the same problem. And after it’s been built, everything needs tested twice, often throwing up two sets of bugs…and the cycle repeats.
Maintaining two separate teams is always more expensive than maintaining a single team and usually slower.
Native may not be ideal but it is a safe bet. There’s always going to be people to hire and the technology will exist for as long as the underlying platform exists.
This is great for long lived projects like those found in enterprises or scaling startups. The added control of the platform also makes native the preferred route for anything using specialist UI, projects which rely on performance, or apps that heavily utilise device capabilities.
Where KMM fits in
Neither cross platform UI or native are ideal solutions. Native development will always lead to separate teams on separate code bases, cross platform UI will always struggle to create a reliable and long-lived common framework— they’re both based on concepts which give no further room for major improvements.
KMM uses a new approach.
Conceptually KMM is based on code sharing and language interoperability — ideas that have been pretty successful in software development. Code sharing has been around for as long as computers have existed and forms the foundation of all modern technology; in Android & iOS we’re also pretty used to the concept of interoperability as for the the better part of 4 years we’ve been well acquainted to having Java/Kotlin or ObjC/Swift in our codebases.
In KMM the choice of what to share is up to the team. It’s a share what you want approach in which you can share anything from small chunks of logic to whole layers of your app. Importantly the base of the project — specifically the UI and device capabilities— remains fully native.
But what projects would KMM benefit and when should you choose it? In terms of the technology hype cycle KMM probably lies somewhere shortly after the technology trigger — it’s still early stage, so it’s hard to say exactly where it will end up being most beneficial.
A potential technology breakthrough kicks things off. Early proof-of-concept stories and media interest trigger significant publicity. Often no usable products exist and commercial viability is unproven.
As KMM offers a comparable user experience to native projects — the UI will after all be fully native — along with the possibility to work as a single team with all the associated cost & speed benefits, there’s every possibility KMM could eventually prove an incredibly popular choice.
Why KMM may succeed
This articles getting a fair bit longer than I intended, so I’ll break down some of the finer points of KMM which give some good signs for it’s uptake.
- Can be incrementally adopted. Most projects are legacy and don’t have the luxury of re-writing an entire codebase. KMM can be adopted piece by piece with small chunks of common code moved into a shared module.
- As a language and compiler solution it’s much more likely to have longevity when compared to cross platform UI.
- No specialist knowledge required. If you know Kotlin and Gradle, you can make KMM apps. Making hiring far easier.
- Mobile is just the beginning. You can already share code with a broad range of other platforms including desktop & web.
- Limited risk in adoption. If everything fails the android app is already written — just move your shared code to the android module — and you could write your own parser to transform Kotlin files to Swift files — fairly quickly having your iOS app back up and running.
Should you try?
Where KMM shines is that it doesn’t try to join the wild goose chase of write once run anywhere. Anyone that’s developed UI for several years has seen their fair share of Flutters & React Natives which promise a lot, underdeliver, and burnout before the next write once anywhere solution comes along promising that this time it’ll be different.
KMM builds on the concept which modern software development has been wildly successful with — shared code. KMM is simply a shared application-specific library.
For us, the developers that use it, its simplicity is its strength. If you know Kotlin and Gradle you’re good to go with sharing a big chunk of your codebase between Android & iOS.
The simplicity is shown in our own project. Our KMM app was built with a host of new technologies — SwiftUI, Compose, and GraphQL. As expected when using new technologies — specifically new UI frameworks like SwiftUI & Compose — they threw up lots of issues. The surprising thing with KMM is that it threw up almost none.
Shared UI is a history of pain and failure. Shared logic is the history of computers.
If you have specific areas of KMM which you’d love to learn more about drop them in the comments and I’ll do my best to describe them in the following posts.