Moving from React Native to Kotlin Multiplatform

Malvin Sutanto
Oct 5 · 6 min read
Image for post
Image for post
Photo by bantersnaps on Unsplash

This article was originally written in Japanese by my colleague 久保出雅俊 . You can find the original article at https://www.wantedly.com/companies/wantedly/post_articles/282562

In this article, we are going to talk about the reasoning behind our decision to adopt, and move away from React Native, and why we decided to adopt Kotlin Multiplatform in our mobile apps.

Why we adopted React Native in the first place

In parallel with the iOS app rewrite, we also wanted to introduce a new feature called “Discover”, where users can find various interesting contents inside our platform. However, since most of the mobile engineers were focusing on rewriting the application, we decided to introduce React Native to allow web engineers to work on this feature separately. “Discover” feature was initially introduced in the old version of our iOS app and our data showed that it performed admirably, hence we decided to bring it into the new iOS app as well.

Subsequently, we introduced “Discover” to our Android app, and our apps’ architecture roughly looked like this:

Image for post
Image for post
iOS and Android app architecture with shared React Native component.

Our issues with React Native

Lack of active maintainers

Updating Xcode or other build tools became an issue because most of the time we need to update React Native toolings first. These updates sometimes were not straightforward and ended up costing us a lot more effort than necessary. This process of updating the build tools quickly became a major pain point for mobile engineers.

Differences in technology

Also with the subsequent introduction of React Native component into our Android app, it’s hard to work with React Native without the knowledge of both iOS and Android platform, as each OS works differently.

Discrepancies in the UI/UX

There were also some minor differences between native UI elements and React Native UI elements. Hence, UI elements that exist in both native and React Native might look similar but have some disparity (e.g., touch feedback on touchable elements in Android app).

Productivity issues

Removing React Native

Kotlin Multiplatform

Kotlin Multiplatform (Kotlin MPP), is a Kotlin language feature that allows you to share code that is written in Kotlin between multiple platforms.

Image for post
Image for post
How Kotlin Multiplatform works. https://kotlinlang.org/docs/reference/multiplatform.html
  • Code that is written using Common Kotlin will be recompiled to native code on each target platform.
  • Allows you to write native code of each platform in Kotlin.
  • Access platform-specific APIs using the expected/actual declarations.

Kotlin Multiplatform Mobile (KMM) is an official site that showcases usages of MPP for mobile applications, and in it, there’s an example on how we can make use of MPP to share business logic between different platforms but still makes use of the native UI elements. We decided to follow this example and implement our MPP architecture as such.

MPP architecture

To achieve that we make use of the following libraries:

  • Kotlinx Coroutines.
  • Ktor Client.
  • Kotlinx Serialization.
  • SQLDelight for application’s single source of truth.

… and a few other libraries. It has a remarkably similar architecture to KaMPKit implementation that is showcased inside KMM.

Mobile app architecture

Image for post
Image for post
Current iOS and Android app architecture.

With the implementation of MPP and native UI element, we saw a tremendous PV improvement of 46% on one of our screen that was originally implemented with a WebView. Furthermore, it has a 50% smaller app download size.

iOS adoption of MPP is currently underway, and in the future, we hope to broaden the application of MPP to improve the overall productivity of all mobile engineers in the company.

Image for post
Image for post
Future iOS and Android app architecture.

Pros and cons of MPP

Pros

  • When the interface of an MPP component has been decided, implementing UI in Android and business logic in MPP can be done in parallel by 2 different engineers.
  • Since there is no “UI” element in MPP, you are forced to write unit tests to validate your code. This naturally yields a high code coverage.

Cons

  • Different memory management model in iOS (Kotlin/Native). In Kotlin/Native code, there’s a concept of immutability that does not apply to Kotlin/JVM code. When working with coroutines, you’ll often encounter InvalidMutabilityException if you’re not careful. There are plans to change this model, but in the meantime, you have to be careful of which thread your code is invoked in.
  • From the point of view of an iOS app, MPP doesn’t look very different from React Native implementation. However, UI components, which usually requires a deep knowledge of each platform to implement, will not be shared and you won’t expect differences as drastic as React Native. There’s also an official guide on how to prepare your team for MPP, as long as you follow this guide, you should be able to create a component that is easy to maintain for all engineers.

Summary

Wantedly Engineering

All about engineering & design at Wantedly

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store