Architect your KMM application
This document provides architecture guidelines on how to decide which layers of your application make cross-platform that work both on iOS and Android and which keep native.
On the backend, the business logic is similar for both Android and iOS, so it's a great candidate for making it cross-platform. For platform-specific features such as network requests, local database access, hardware manipulation, and cryptographic storage, use a multiplatform library that does this for you or connect to platform-specific APIs with the
expect declaration, by providing the
actual implementation for each platform.
KMM presumes that the best user experience is when it is native to the platform itself, and therefore we don’t recommend sharing it in KMM. However, you can share the code for the UI behavior that defines what happens with any user interaction and how the frontend communicates with the backend with the help of compatible architectural patterns.
Best practices for the KMM app architecture
To summarize, we recommend making cross-platform the following layers in your application:
|Layer||Recommendation on sharing|
|Platform access||Yes/no. You’ll still need to use platform-specific APIs, but you can share the behavior.|
|Frontend behavior (reaction to inputs & communication with the backend)||Yes/no. Consider these architectural patterns.|
|User interface (including animations & transitions)||No. It needs to be platform-specific.|
Architectural patterns for sharing UI behavior
Make a clear distinction between the UI and presentation layers.
Are completely decoupled from the UI platform.
Are easily testable without a UI environment.
MVP for legacy UI frameworks
Model-View-Presenter (MVP) forces you to create an API for both the Presenter that receives inputs and the View that displays outputs, allowing you to test each independently.
Here is an example of a simple MVP presenter:
lastCommand mechanism, which allows a view to detach and re-attach, for example for configuration changes on Android.
MVI for declarative UI frameworks
Model-View-Intent (MVI) is the natural evolution of MVP when working with declarative UI frameworks (although it also works with legacy UI frameworks). It is therefore recommended to be used with Swift UI or Jetpack Compose.
In MVI, the entire UI structure is described in one tree. Here is an example of a simple MVI presenter:
lastModel mechanism, which allows a view to detach and re-attach, for example for configuration changes on Android.
Thanks to contributors
We'd like to thank the Kodein Koders team for helping us write this article.