Industry: Software development
JetBrains products used: Kotlin Multiplatform Mobile
Yandex is a technology company that builds intelligent products and services powered by machine learning. Its goal is to help consumers and businesses better navigate the online and offline world. Since 1997, Yandex has delivered world-class, locally relevant search and information services. Additionally, it has developed market-leading on-demand transportation services, navigation products, and other mobile applications for millions of consumers across the globe. Yandex has 30 offices worldwide and has been listed on NASDAQ since 2011.
Could you say a few words about your team?
Yandex.Disk is built by a team with members operating in Moscow and St. Petersburg and is one of the most popular cloud services in Russia for storing files in the cloud. Launched on April 5, 2012, Yandex.Disk provides unlimited space in the cloud to keep photos from mobile devices – you can enable auto-upload of images from your mobile device in the app. It includes a smart photo gallery that shows collections of your most beautiful photos and best memories. Yandex.Disk is available as a web version, as a client for Windows and macOS, and as an app for iOS and Android.
How is Kotlin Multiplatform Mobile used in your product?
We have several features in production that are written with Kotlin Multiplatform Mobile. We first started experimenting with KMM by implementing a networking layer for our iOS and Android apps. We were originally thinking about using Ktor, but it didn’t fit our requirements, so we wrote our own lightweight networking library, which uses the expect/actual mechanism under the hood and can make simple REST requests.
We considered this a successful experiment, and the next feature we implemented with KMM was in-app purchases. We implemented the multiplatform library which wraps platform-specific APIs (Google Play and Apple Store) using expect/actual, hides all the complex payment processing, and provides a universal interface to work with the purchase logic in both iOS and Android apps.
That was also a success, so we expanded our multiplatform team, and now we have three engineers working on KMM. The last significant feature we did with KMM was data synchronization for Photo Albums. Networking, data storage, and data synchronization are all implemented in pure Kotlin for both platforms. We often need to perform many operations in the background, and as coroutines are currently only supported on the main thread, we have had to implement our own solution for multithreading. For data storage, we used SQLDelight, which has saved us a lot of time by generating typesafe Kotlin APIs for executing SQL queries.
Why did your team decide to use Kotlin Multiplatform, and what alternatives did you consider?
We all agreed on one thing: reusing code is good. In Yandex, we experiment a lot to find ways to avoid developers having to write the same code multiple times for different platforms. Kotlin Multiplatform Mobile is not the only solution available, and every team solves this problem in different ways. I was surprised when I came to the Yandex.Disk team and realized that the folks here had native code for synchronization logic for each platform and didn’t use C++, for example. But they wanted to try KMM, and I had some experience with it, so it worked out really well.
We don’t believe in sharing the UI layer in mobile application development. This approach almost always leads to hacks in the code and a rougher, unrefined, laggy user interface, and neither developers nor users are happy with the end result. We love our users and we want to provide them with the best experience, which includes providing them with the feeling and smoothness of a native UI. But we are very interested in sharing business logic: in Yandex.Disk 20% of our work is on UI and the other 80% is on business logic – how to collect, synchronize, and process all the user’s data without draining their phone battery. So we have not considered UI-sharing solutions like Flutter, React Native, or Xamarin. One of the alternatives was C++, but writing in С++ is difficult and expensive. Our colleagues at Dropbox found this out the hard way, and also our particular team hadn’t had enough experience with it.
Using C++ for cross-platform development also comes with big DX issues for Android developers – JNI is a pain to use and has a lot of restrictions. So for the Android part of our team, using Kotlin for cross-platform development was a huge advantage. Of course, for iOS developers KMM comes with its own set of issues as, after all, it introduces a new language to the codebase and there can be some DX issues with that. But they are not as big a concern as the problems with C++ development for Android. So the choice for us was clear, especially given that there are more Android developers on our team than iOS developers.
What have been your most significant gains and pains?
The most crucial gain for me was the ability to give talks at different conferences. Kotlin Multiplatform Mobile is a pretty new technology, and the number of developers interested in it is snowballing. Talks about your experiences with KMM will be welcome at any conference!
But really, the main gain from using KMM is that you can write your code once, and it will work the same over all the cross-platform solutions. It’s not just about the development speed, at least at the start. When we were integrating KMM for the first time, we spent a lot of time solving different problems and trying to understand how it should work. Now we have more experience, and we can deliver new features faster. But the main gain is that we know that our logic works the same on both iOS and Android applications. It means that we can test our features once and we only need to fix bugs in one place. Also, the single codebase for business logic gives us similar estimates for the new features on both platforms, simplifying the planning process significantly.
Of course, there are also some pains in using KMM. We hope that most of them will soon be solved, as the technology is maturing and growing fast. We started using KMM when it was still in an “experimental” stage, and we knew what to expect.
The most critical problem was the lack of documentation (both for Kotlin and for 3rd-party libraries). We spent a lot of time at the start just trying to understand how to do simple tasks, like configuring a project or adding new dependencies.
Another big pain is working with concurrency in Kotlin/Native. The Kotlin/Native memory model is not simple to understand, and there were no guides on how to work with it. We didn’t know what to do when something went wrong, so we had to dig into the Kotlin/Native sources to understand the problem, and that was a real challenge.
Finally, DX for me as an iOS developer is a real pain. Debugging your business logic by running the iOS application is usually a bad idea – you need to run two IDEs simultaneously and switch between them. Also, Kotlin/Native has a long compile time that slows your development speed right down. So now, if I need to debug something, I run an Android application. Good test coverage of your common code can save you a lot of time debugging because you don’t need to run iOS or Android apps to check if your code works correctly. Using KMM gives you excellent motivation to start writing tests in your project if you haven’t done so already.
Do you have any tips or advice you’d like to share with our readers?
Experiment – it’s an excellent way to understand if the technology suits your needs. You can try it on a single feature in a small project. Doing things in small steps will save you time in the long run and help you get a lot of experience. The active community in Slack compensates for the lack of documentation, you can always find answers to your questions there.
Would you like to share your contact information with our readers?
The main gain is that we know that our logic works the same on both iOS and Android applications. It means that we can test our features once and we only need to fix bugs in one place. Also, the single codebase for business logic gives us similar estimates for the new features on both platforms, simplifying the planning process significantly.
Artem Olkov, Mobile Developer at Yandex.Disk
Artem Olkov, Mobile Developer at Yandex firstname.lastname@example.org
VMware uses Kotlin Multiplatform Mobile in various modules across their Workspace ONE productivity app portfolio.
The UI for each of the Chalk.com apps is native to the platform, but other than that, almost everything else for their apps can be shared with Kotlin Multiplatform Mobile.