# Migrating a Real Android App to Kotlin Multiplatform: Lessons Learned

A deep dive into moving Android codebases to KMP while managing platform-specific dependencies.

- **Source:** [ProAndroidDev - Medium](https://brifing.si/source/d9553fa9-7b72-4b9b-bc73-c6bf9a40dd5f)
- **Published:** 2026-11-02
- **Topic:** [Software & Engineering](https://brifing.si/c/engineering)
- **Original article:** <https://proandroiddev.com/migrating-a-real-android-app-to-kotlin-multiplatform-2-4-what-moved-for-free-and-what-hurt-7ec973002f01?source=rss----c72404660798---4>
- **On Brifing:** https://brifing.si/s/bd57808f-1682-42a1-9f82-619d1c54e24c

## Migration Strategy and Scope

The migration achieved 84% code coverage in commonMain by prioritizing modularity. Success depended less on library support and more on decoupling the codebase from Android-specific APIs. While some layers migrated mechanically in an afternoon, others required weeks of refactoring to remove deep-seated platform coupling that had accumulated over many years of development.

## Dependency Injection as a Shield

Koin serves as the primary mechanism to keep platform-specific code out of shared modules. By depending on interfaces rather than expect/actual declarations, the architecture avoids complex initialization steps. This approach allows each platform to bind its own implementation, effectively isolating platform-specific dependencies while maintaining a clean, testable shared codebase for the application.

## Networking and Data Layers

Ktor and SQLDelight facilitated a smooth transition because they were chosen with multiplatform goals in mind. Networking configurations moved to commonMain with minimal friction, requiring only engine-specific adjustments. SQLDelight proved highly effective, though developers must note that the WebWorkerDriver on the web platform currently operates as an in-memory solution without persistent storage.

## The Hidden Android Dependency Trap

A major failure mode involves Android-only dependencies like Context leaking into shared code. These issues often remain invisible until a second target is added to the CI pipeline. A green Android build is insufficient; implementing a secondary target from the very first module conversion is essential to catch platform-specific leaks early.

## The Challenge of java.time

Replacing java.time was the most difficult aspect of the migration due to its pervasive use in domain models and UI formatting. Kotlinx-datetime serves as the replacement, but it lacks some locale-aware formatting features found in Java. Developers must build custom abstractions to handle date intervals and formatting across different platform-specific implementations.

## Handling Files and Streams

Android file handling does not translate directly to web or iOS environments. The solution involves a lazy, stream-based API that avoids loading entire files into memory. By using a lambda-based approach, the system supports retries and redirects, allowing each platform to implement its own efficient reading mechanism while keeping the shared interface clean.

## Storage and Local Data

SharedPreferences and localStorage appear similar but behave differently when handling complex data. The migration utilized Multiplatform Settings combined with kotlinx.serialization to manage structured values. This design choice highlights the importance of abstracting the actual business need rather than mimicking the specific API structure of a single platform like Android.

## Key Takeaways for Architects

Successful KMP migration requires auditing internal code coupling rather than just checking library compatibility. Relying on dependency injection to bridge platform differences reduces maintenance overhead significantly. Ultimately, defining interfaces based on application requirements rather than platform-specific implementations ensures the codebase remains flexible and resilient across all targeted platforms during the transition.

## Sources covering this story

- https://proandroiddev.com/migrating-a-real-android-app-to-kotlin-multiplatform-2-4-what-moved-for-free-and-what-hurt-7ec973002f01?source=rss----c72404660798---4 — 

---

_Summary written by Brifing from the original reporting. Copyright in the original article belongs to its publisher; read the full piece at the link above._
