Industry: Language learning
JetBrains products used: Kotlin Multiplatform Mobile
Memrise is a language learning app with over 50 million users. We combine entertaining content with proven scientific techniques to make learning languages fun and effective.
Our courses offer 200 language combinations across 24 languages. It’s more than just remembering words (although our CEO happens to be a Memory Grandmaster). We create an immersive learning experience with video content spoken by locals, build learners’ confidence speaking with voice recognition, and teach practical phrases with plenty of humor.
As an engineering team, we take a mobile-first approach. We have 10 engineers with a mix of iOS and Android expertise developing our mobile apps.
Our mobile app
Memrise’s mobile app was launched over 5 years ago. Developing natively for iOS and Android gave us the flexibility to balance our branding with individual platform UI paradigms. That strategy paid off: we’ve won several Best App and App of the Year awards.
But there’s another side to the story. At the heart of Memrise is a set of algorithms that optimize the learning process, and this logic was completely duplicated on each client. Whenever we had to debug inconsistent behavior between platforms, it was clear we’d essentially been writing the same code but in different programming languages.
Moving the shared logic to our backend systems wasn’t an option. That would present performance challenges and stop us from offering a full offline experience – an important feature of Memrise. Our learners expect to be able to use the app on planes and underground trains. Popular cross-platform frameworks like React Native and Flutter didn’t meet our needs either, because the code we wanted to share is platform-agnostic business logic. We briefly experimented with a Rust library, then quickly settled on Kotlin Multiplatform.
Adopting Kotlin Multiplatform
Our main principle for defining a multiplatform strategy was that we should be able to migrate logic incrementally. Kotlin itself was another factor. Given its ubiquity in the Android world and its similarity to Swift, we’ve been able to avoid a steep learning curve or a fragmented developer experience.
We shipped our first Kotlin Multiplatform code to production in an iOS release 2 years ago. We’re now sharing our core business logic between Android, iOS, and even our web frontend via Kotlin/JS.
Starting this project on iOS was a happy accident. It exposed us to the challenges of the Kotlin/Native memory model early on and highlighted some Cocoapods tooling we’d have to build (although Cocoapods now has official plugin support).
As early adopters, our challenges have centered around tooling and development workflows. The multiplatform library itself has been a big success. We’ve been able to maintain 100% test coverage during our migration, and we now have a single source of truth for some of our most important logic.
Earlier this year, we began a second project to explore sharing networking and persistence code between our mobile apps. The latest features in our Android app interact with our backend systems through a KMM module, using Ktor Client, Kotlinx Serialization, and SQLDelight. This slice of the application is a testbed for how we might eventually share API interactions and database configurations between our iOS and Android apps.
We don’t have any plans to share UI layer code. We’re excited to build next-generation user interfaces with SwiftUI and Jetpack Compose, so we’re glad to have a system for sharing code without the constraints of traditional cross-platform mobile frameworks.
It’s a great time to be working with KMM. JetBrains’ announcement of Alpha status gives us confidence in its future, and the community is growing fast.
Kotlin Multiplatform is a key part of Memrise’s engineering strategy. The more we can share implementation details between our client applications, the more we can focus on the important stuff: building great user experiences.
Jamie McDonald, Engineering Manager, @jdamcd
Andy Uhnak, Senior Software Engineer