We’ve recently unveiled our plans for Rukkaz: a video platform designed for family creators, responsible advertisers and kids. Rukkaz is built with privacy-by-design and safe community as first principles (we talked about our guiding principles in an earlier post).
While developing Rukkaz natively for iOS and Android we realised we were writing the same functionalities twice, sometimes with different outcomes and inconsistencies across the platforms, resulting in loss of time, as well as headaches for the team.
This platform-specific approach was also having an effect on the team dynamics: we started to see ourselves as platform specialists rather than one team focused on delivering the best Rukkaz experience possible. So we switched to the same principles used elsewhere in our kidtech stack, and focused on cross-platform development.
We chose to develop Rukkaz using Kotlin MultiPlatform
Kotlin MultiPlatform (MLP) is a project that extends the Kotlin language and enables developers to cross-compile to Objective-C on iOS and interoperate natively with all the libraries and frameworks in the iOS ecosystem.
We found Kotlin MLP very lean and noninvasive, as it allows us to reuse all the native code we’ve developed for iOS (either in Obj-C or Swift) with zero effort, enabling us to defer the choice of rewriting valuable pre-existing business logic to the last responsible moment.
With Kotlin MLP we aim to have a completely shared codebase for all the key libraries making up Rukkaz, including eventing, logging, persistence, networking, and – most importantly – all the logic around and protection of the user’s privacy. To date, more than 50% of our codebase is shared across platforms, resulting in a massive saving of development time, and in a fast time to market for Rukkaz.
User interfaces, where platforms differ the most, are still platform specific. We are aware this is just the beginning of our journey, and we’ll reassess if we need to introduce a shared view layer in the future.
Since native Android development pivoted from Java to Kotlin two years ago, our team has decided to embrace this new language. That choice gave us a headstart on Kotlin MultiPlatform as the whole team had developed a deep familiarity with the language, resulting in an extremely short learning curve when compared to other options, even for iOS developers.
Being responsible for delivering a feature end-to-end on both platforms with a good chunk of shared code has changed our mindset, turning platform experts into Rukkaz enthusiasts focused on making the internet safer for kids.
Known shortcomings of Kotlin MLP
There are a good number of libraries out there that handle the basic things you might need, like Ktor or KotlinX Serialization, but the ecosystem of cross-platform libraries available today is not as rich.
Not all Java libraries are supported out of the box, mostly because they depend on the Android SDK. Kotlin MultiPlatform compiles to Objective-C, and some functionalities like generics or suspended functions/coroutines are not 100% ready yet.
We consider both issues minor, as we’ve been able to work around them by creating Kotlin MultiPlatform wrappers around native libraries or functionalities.
We’re aware we’re amongst the early adopters of Kotlin Multiplatform, and we’re confident that our experience will get better as the number of companies embracing it grows, and the Kotlin-Everywhere community gets bigger.
How we evaluated all cross-platform technologies
We limited our study to the technologies with the largest adoption, defined as the number of StackOverflow questions, GitHub repositories, Google trends, and companies endorsing the technology.
We ended up shortlisting six technologies, namely: React Native, Flutter, NativeScript, Ionic, Xamarin and Kotlin Multiplatform (MLP).
Criteria | Kotlin MLP | React Native | Flutter | NativeScript | Ionic | Xamarin |
Search Results | 407k | 150M | 70M | 945k | 93M | 15M |
StackOverflow questions | 165 + 1.1M Kotlin Android | 67k | 33k | 166k | 30k | 36k |
GitHub repositories | 339 + 858k Kotlin Android | 105k | 28k | 5k | 80k | 30k |
Companies backing / Support | JetBrains, Google | Facebook, many others | Progress | Ionic | Microsoft |
Each cross-platform technology was then benchmarked against these four criteria:
- Quality: Does this enable us to produce the same results as with native?
- Learning curve: Does it leverage existing skill sets in the team or company?
- Team cohesion: Does it allow us to move together as a team in the same direction?
- Hiring: Can we tap into a good pool of candidates to expand our development team?
Each technology in our shortlist came with its own trade-offs. In the spirit of failing fast, we focussed on identifying the shortcomings of each option and determining whether those represented a show stopper for our specific case.
Here’s a short summary of the reasons why we discarded each technology.
The main red flag on React Native was the experiences of AirBnB’s and Udacity’s engineering teams, and how they ended up maintaining three codebases as opposed to one – which largely defeats the purpose of embracing a cross-platform technology.
On top of that, we couldn’t tap into our team’s existing knowledge – while at SuperAwesome we use JavaScript extensively, we’re geared towards an Angular ecosystem.
We found NativeScript lacked both mature integration with native codebases as well as a large enough developer pool.
We think a deep integration with native is a must-have feature for any cross-platform technology to achieve the same qualitative results as with native in specific cases. For this same reason we discarded Ionic, which allows for hybrid web-based app development only.
We decided against Flutter and Xamarin because they would introduce a new tech stack to the company (based on Dart or .Net), in which we had no experience. Flutter also came with the con of having a small pool of candidates, which would have caused delays on hiring.
Do you want to help us solve problems like these to make the internet safer for kids? We’re always looking for engineers to join the mission!