Kotlin Multiplatform + Kotlin/Native: an alternative to Xamarin?
Can Kotlin Multiplatform and Kotlin/Native replace Xamarin? A demo architecture for Android and iOS, Gradle configuration, common modules, expect/actual, the data layer, and the advantages and limitations of this approach.
Mateusz Kopta
Introduction
Kotlin 1.2 introduced experimental Kotlin Multiplatform Projects, enabling code sharing across JVM platforms (Android, desktop, web). At the same time, Kotlin/Native compiles Kotlin without a VM into native binaries for iOS, macOS, or embedded systems.
Let us combine these technologies and build a simple mobile app for Android and iOS: a photo browser for NASA Astronomy Picture of the Day.
Build system and IDE
Multiplatform is based exclusively on Gradle.
Templates are available in IntelliJ 2017.3, along with a Kotlin/Native plugin for AppCode 2018.1.1. In practice, it is convenient to use Android Studio for Android and common modules, and Xcode for the iOS part.
Project structure
- Android: a classic application depending on the platform-android module.
- iOS: an Xcode project that includes platform-ios as a general-purpose obj-c framework.
- Common: a shared module with pure Kotlin, without platform dependencies. It declares API requiring platform-specific implementations using the expect keyword. The platform-android and platform-ios modules provide actual implementations.
- Platform-android and platform-ios: platform-specific implementations and additional native code. Each platform module implements a single common module.
Only the common version of the standard library, kotlin-stdlib-common, is available in the common module, which limits the available API.
Creation and configuration
- Common: dependency only on kotlin-stdlib-common. Coroutines optionally enabled as an experimental feature.
- Platform-android: an Android library module (com.android.library) using the actual mechanism and an expectedBy dependency on common.
- Platform-iOS: using the Kotlin/Native (Konan) plugin in Gradle to build a framework for iphone and iphone_sim, with optimisations and debugging enabled. Also expectedBy on common.
- Android application: dependency on platform-android.
- iOS application: built in Xcode, embedding the generated AstronomyPictureOfTheDay.framework.
Asynchronicity and coroutines
At the time the project was created, Kotlin/Native did not yet support coroutines. To preserve a programming style similar to async/await, a common interface was defined in common and platform-specific implementations were provided through expect/actual. This enables a consistent asynchronous API while still leveraging native primitives on each platform.
Data access layer
- Endpoint: https://api.nasa.gov/planetary/apod?date=[date]&hd=true&api_key=[api_key]
- The response includes, among others, date, explanation, hdurl, media_type, service_version, title, url.
- The shared data model is located in the common module.
- Queries and parsing are handled natively on the platforms: on Android with Retrofit + Gson, on iOS with Alamofire + SwiftyJSON.
This approach keeps networking and parsing close to the platform while still allowing models and control logic to be shared.
Date representation in common
Using String for a date is inconvenient when navigating one day backwards/forwards. Due to the limitations of kotlin-stdlib-common, a custom date abstraction was prepared in the common module with actual implementations:
- Android: JodaTime
- iOS: NSDate (Foundation)
Thanks to Kotlin/Native interoperability with Objective-C/Swift, Foundation or UIKit API can be called directly from Kotlin code, even though the entire module is written in Kotlin.
MVP: Presenter and View
A simple set of Presenter and View (MVP) interfaces was defined in the common module. Platform-specific screens implement View, while the Presenter and navigation logic remain shared.
Integration in applications
Android and iOS include the common module, inject platform-specific implementations of repositories, time utilities, and asynchronicity mechanisms, and then bind the Presenter to the native UI. As a result, a large part of the logic remains identical across both platforms.
Summary
Kotlin Multiplatform + Kotlin/Native already make it possible today to share key logic between Android and iOS while preserving native interfaces and libraries.
Advantages:
- Shared language and data models
- Native access to API (Retrofit, UIKit, Foundation)
- No VM on the iOS side, clean binaries
Limitations:
- Experimental status and a more limited kotlin-stdlib-common
- Split tooling (Gradle + Xcode)
- At that stage, no full coroutine support in Kotlin/Native, making expect/actual bridging necessary
For teams working in Kotlin, this is a genuine alternative to Xamarin, especially when the goals include native UI and shared logic. It is worth following its development — subsequent releases simplify configuration and broaden library support.
Need technology support?
Let us discuss your project — from discovery to deployment.
Book a consultationWould you like to know more?
Explore other articles or let’s discuss your project
All articles Let’s design your AI application