Originally published at mayankmkh.medium.com/kotlin-multiplatform-a..
For a long time, many have desired to have a single codebase that can run on multiple platforms especially mobile — Android and iOS. Many technologies have been developed to fulfill this dream but a few have been adopted in large-scale applications. In this article, we’ll explore some popular code-sharing solutions, compare those, and arrive at a conclusion as to why we chose one over the others, but first allow me to introduce you to InVideo.
InVideo is a powerful web-based video creation tool that lets you create high-quality professional-looking videos in a matter of minutes. You can either create a blank canvas or select one of the thousand templates including but not limited to brand intros, ads, wishes, promos, collage, and quotes. You can then add, remove or modify it according to your liking, and boom you have a beautiful video ready to be shared with the world.
Foray into Mobile
InVideo has a feature-rich Web client and wants to bring the same power to everyone regardless of the device. We need to build apps for Android and iOS with a similar feature set as the web providing the users with advance video editing capabilities.
It’s a fairly complex project dealing with lots of graphics and business logic and can be broadly divided into 2 parts:
Deals with graphics rendering using OpenGL, Vulkan, or Metal, with the ability to render media elements namely image, video, audio, text, stickers, and fonts with support for effects, filters, animations, and transitions. It needs to handle media encoding and decoding and have a smart resource caching system to provide an optimal user experience with minimal resource consumption.
The user-facing part implementing a beautiful, easy-to-use UI optimized for various screen sizes and device constraints. It deals with everything apart from rendering like networking, local storage, file operations, authentication, notifications, analytics, crash reporting, media pickers, complex video editing UI, user interactions, and interfacing with the Editor.
As you can tell, this is a very different app from a regular CRUD app, especially the Renderer and we had limited time and resources to build an app that’s stable, has high performance, consumes minimal resources, and provide a good user experience regardless of the device specifications. All this with a small team of mobile developers, so we need to come up with a solution that could help us build the apps faster and avoid writing complex code multiple times for different platforms. That’s when we started exploring available multiplatform solutions.
- Single codebase to target multiple platforms
- Consistent design and architecture
- Forces us to design in such a way that most of the software is platform agnostic which means better code that is scalable and easier to maintain
- Complex business logic can be written once and shared among platforms
- Feature parity
- Faster shipping of features
- Interaction among the team increases
- Saves not only development effort but also saves time reviewing, testing, and fixing the code
Upsides: abundant learning resources, a vast set of libraries, a large number of contributors, and a huge community. fast iteration speed, animations
Downsides: Increases startup time, initial render time and the app size, relatively higher memory usage. The code becomes difficult to maintain as more platform bridging code is introduced.
Flutter is a UI Toolkit developed by Google to create beautiful apps using Dart language which compiles natively and is high performant.
Upsides: Rapid iteration using hot reload, high performance, building UI is a breeze, smooth animations, community
Downsides: Still maturing, increases app size, has limited tools and plugins which means you need to create a plugin yourself and that requires knowledge of all platforms, a new language to learn.
C++ can be compiled into a binary that can be used by both Android and iOS.
Upsides: High performance, low memory utilization, no garbage collection, shared business logic, common OpenGL for Android and iOS
Downsides: Manual memory management, lack of multiplatform libraries, and tools for mobile development. Too many overheads to deal with as mentioned by Eyal Guthhman in the blog The (not so) hidden cost of sharing code between iOS and Android.
Kotlin Multiplatform (KMP)
Kotlin Multiplatform is created by Jetbrains and uses Kotlin as the programming language. It is more a set of technologies than a framework.
Upsides: common business logic, high performance, compiles to bytecode for Android and native for iOS, good interop with Java, Swift, and Objective-C, uses modern language, very little to no change for Android developers.
Downsides: reduced code sharing as UI is not shared, is in alpha, the lack of libraries, immature tooling, relatively smaller community as compared to React Native or Flutter, new build system, and language to be learned by iOS developers
As the project required dealing with low-level graphics and it being the huge portion of the app, React Native and Flutter didn’t fit our use case and it’s just too much overhead to build the app with C++ as experienced by folks at DropBox (read more about it in the article by Eyal Guthmann). Now we were left with 2 options:
Create Separate apps for each platform
Use Kotlin Multiplatform to share most of the code
We thought if we choose to create separate apps then we would anyways be creating the Android app using Kotlin, then why not try to share that code with iOS too. Its low risk and has high returns. Kotlin Multiplatform (KMP) was the obvious choice for us.
After some more digging, we believe it can scale well and would be beneficial in the long run even if we had to deal with some of the problems with tooling and language.
Reasons for choosing KMP
- As many Android developers are already familiar with Kotlin and Gradle build system which KMP uses, it's a little to no change for them
- No overhead as it compiles to bytecode for Android and native for iOS
- Shared business logic mostly independent of the platform
- Can share as much or as little as desired
- Not sharing the UI can be a bane or a boon. At the expense of reduced code sharing, we could provide a better user experience as every platform has a certain way of interaction, guidelines, and best practices and these intricacies are hard to achieve with cross-platform solutions and are best left to the platform.
- Interop with the other languages allows us to use Kotlin code in Java, Swift, or Objective-C and vice-versa
- expect/actual mechanism to define the structure in common code and provide the implementation is platform-specific directories
- Ability to use platform-specific libraries in KMP project using Gradle (for Android) or Cocoapods (for iOS) which opens a whole new world of ecosystem
- Has libraries for all major tasks networking, local storage, concurrency, JSON parsing, logging, and testing
- Can target JVM for faster iteration cycle as the whole code can be run and tested on the PC rather than a mobile device
- Hiring engineers familiar with Kotlin is much easier than React Native or Flutter
- Future possibility of using the same code for other platforms like Web and Desktop with minimal changes
- Future possibility of sharing UI code as well, thanks to Jetpack Compose and Compose for Desktop
Kotlin Multiplatform Mobile (KMM)
Kotlin Multiplatform Mobile or KMM is a subset of KMP with the focus on making the tech stable for use on mobile platforms namely Android and iOS and provides improved and better tooling for this use case.
KMM plugin for Android Studio
- Ability to generate new KMM project preconfigured to run on Android and iOS
- Provides functionality to create new KMM modules
- It enables us to run iOS apps directly from Android Studio as you would run any Android app
- Enables debugging the Kotlin code running in iOS
- iOS developers need to learn a new language, build system, IDE, and tooling
- Objective-C interop limitations like inline classes and custom classes implementing standard Kotlin collection interfaces (List, Map, Set)
- Kotlin Native (K/N) memory model is not simple to understand
- Slow compilation for Kotlin Native As of writing this article, the Kotlin version is 1.4.31. Kotlin team is working on a new memory model for K/N and have improved compilation time in Kotlin 1.4.30 and more work in this direction is ongoing.
Kotlin is an awesome language and Kotlin Multiplatform brings that to other platforms to help us create scalable and maintainable apps using a single codebase. Although the code-sharing is slightly less than that with other cross-platform solutions as UI cannot be shared, that gives us the advantage of creating a user experience that is in line with the platform’s guidelines and best practices.
KMP combined with reactive programming and unidirectional data flow can help create a solution that is agnostic to the UI framework and can be reused on any platform. Using KMP we hope to share 70–80% of code across mobile platforms and adding one more platform will just be a matter of implementing the UI.
Though KMM is in alpha as of Kotlin 1.4.31, the technologies powering i.e. Kotlin JVM is stable and Kotlin Native is beta since 1.3 so it is pretty safe to be used in production.
If you want to work at the forefront of technology, join us by applying at
Don’t forget to fill in Referrer Name as Mayank Kharbanda and I hope to work with you on many cool things to come.
- Join #multiplatform channel in Kotlin Slack (get an invite)
- If you already have an app then you can explore KMP by building new functionality which can be as small as a single file and expand from there
- If you are an Android developer, then don’t force KMP on iOS devs, instead, try to explain how it works, what are the benefits. Start by creating some modules yourselves, share them with iOS. If everyone thinks it’s a good idea to share code this way then involve the interested devs to start reviewing the code, implementing a function or a class. Start with something small. Read Introduce your team to KMM.
- Jetbrains for creating the language and technology
- InVideo for always working with leading-edge technology
- iOS devs at InVideo for being open to using Kotlin
- Kotlin community
- People who inspired me to share my knowledge. There are so many that naming them is impossible. If I follow you on Twitter and you like helping others, you are one of them. Thanks for inspiring me and many others.
- Sahil Bajaj for proofreading and helping me structure the article.