One Kotlin codebase behind the Android and iOS apps.
- native apps
- 2
- Kotlin codebase
- 1
- engineers
- 2
- months to fully shared native apps
- ~3
Where it started
Maytes (formerly KttiPay) is a consumer payments product. When I joined in September 2024 the Android app was a legacy Java codebase. iOS and web each needed the same payment flows, the same rules about money and the same fixes.
What I did
- Moved the Android app to shared Kotlin in increments. Each piece moved into Kotlin Multiplatform and Compose Multiplatform while the app kept shipping, without a big-bang rewrite.
- Brought iOS onto the same code. Once the shared layer carried the screens and the payment logic, the iOS app ran on it too. Both native apps became fully shared about three months after I joined.
- The web. The web app is built in React, for better compatibility.
Payments on three platforms
Wallet payments are the part that cannot be shared naively: Apple Pay and Google Pay are different systems with different rules. I wrote KPayment to put both behind one Kotlin API while each wallet still runs natively on its own platform. Maytes released it as open source. The current work is split-at-checkout payments.
KPayment on GitHub · Apple Pay and Google Pay for Kotlin Multiplatform · Floating point can’t hold a cent
How two engineers ship three platforms
Two engineers ship all three platforms. On Android and iOS, one codebase means one implementation of each payment flow, one place to fix a bug, and one review per change.
The shipped app
Maytes (formerly KttiPay) is available on the App Store and Google Play.
Stack
- Kotlin Multiplatform
- Compose Multiplatform
- React