Building Kittysplit's Mobile Apps in Compose Multiplatform

18.09.2025

After 13 years as a web only application, Kittysplit has finally made the leap to mobile. We initially planned to build separate Android and iOS apps using Kotlin Multiplatform for shared business logic, but Compose Multiplatform’s recent stability changed everything. Here’s how we went from web only to native mobile apps.

From Web only to Mobile: A 13 Year Journey

Kittysplit started as a web application back in 2012. For over a decade, we maintained it exclusively as a webapp. The web platform allowed us to provide universal accessibility. Anyone could create or join a Kitty simply by opening a link in their browser, regardless of their device type. This cross platform compatibility is crucial for group expense sharing, where participants often use different devices and operating systems.

Growing Demand for Native Apps

However, user requests for dedicated mobile apps grew year after year. We felt that we needed to address this demand, so we looked at the available options for the implementation. We evaluated React Native, Flutter, Kotlin Multiplatform, and Compose Multiplatform to determine the best approach for our small development team.

Because we already had experience with Android development, we chose Kotlin Multiplatform as our foundation. Our initial plan was straightforward: develop the Android app first using Android Compose, while implementing all business logic in a shared module in Kotlin Multiplatform. This would allow us to share the core functionality across platforms: networking, business logic, calculations and local storage. We planned to build the iOS app using SwiftUI after completing the Android app, leveraging the already written shared business logic.

The Power of Kotlin Multiplatform

Kotlin Multiplatform proved to be an excellent choice for our architecture. We implemented all networking, local storage, and client-side calculations in the shared multiplatform code. Additionally, we moved all our ViewModels into the shared codebase, ensuring consistent business logic and state management across both platforms.

The implementation was straightforward: Kotlin provided almost everything we needed out of the box. For local data storage, we used SQLDelight, which allowed us to write type-safe SQL queries. We integrated the RevenueCat Purchases multiplatform SDK for handling Super Kitty upgrades. To enhance the Swift interoperability for our planned iOS development, we used SKIE from TouchLab. For dependency injection, we chose Koin, which worked seamlessly across our multiplatform setup. This foundation gave us confidence that we could maintain a single source of truth for our core functionality while building native experiences on each platform.

Compose Multiplatform Goes Stable

As it’s often the case in software development, the SwiftUI frontend turned out to be more work than we initially anticipated 🙈. We had been following Compose Multiplatform’s development for some time. Given the challenges we were facing with SwiftUI, we decided to experiment with it for a few days. Compose Multiplatform for iOS had recently reached stable status in May 2025.

We managed to migrate our app to Compose Multiplatform within just a few days, which was much faster than we expected. The resulting app ran smoothly on our iOS devices and felt really well.

This led us to ditch the native SwiftUI frontend entirely and go with Compose Multiplatform instead. It would save us months of work, both now and in the future. With only one codebase to maintain, we can spend our time improving the app and adding new features rather than implementing everything twice.

Kittysplit first time on iOS Kittysplit add entry on iOS

Kittysplit on iOS

The Migration Process: From Android Compose to Compose Multiplatform

The actual migration process was surprisingly straightforward. We started by importing the new Compose Multiplatform dependencies and migrating to multiplatform resources, which was mostly just copying a few files to the new structure. The main code changes involved removing usages of the Android Context throughout our codebase.

Fortunately, we had already been using multiplatform libraries from Sentry and RevenueCat, so those integrations continued to work without any changes. For Firebase Analytics, we used the expect/actual mechanism to provide platform-specific implementations. We also needed to make our deep links work on both platforms, but the patterns were similar enough that it didn’t require major restructuring.

Most of our existing Compose UI code worked with minimal adjustments, and the shared ViewModels we had already implemented in Kotlin Multiplatform integrated seamlessly. Within just a few days, we had a fully functional iOS app that felt genuinely good.

Looking Forward

We’re excited about the future of Kittysplit’s mobile apps with this technology stack. Kotlin Multiplatform and Compose Multiplatform have given us the perfect balance of development efficiency and native performance. With a single codebase to maintain, we can focus on what matters most: building features that make splitting expenses even easier for our users. We’re already working on several improvements and new features that would have taken us much longer to implement across separate platforms. The mobile app journey has finally found its ideal technical foundation, and we couldn’t be more excited about where it’s headed.