Image for post
Image for post

Kotlin Multiplatform Android/iOS: Project Structure Strategies

How should you structure your multiplatform project?

Alistair Sykes
Dec 9, 2019 · 4 min read

Kotlin Multiplatform

Kotlin Multiplatform (KMP) is a way of writing cross-platform code in Kotlin. It is not about compiling all code for all platforms, and it doesn’t limit you to a subset of common APIs. KMP provides mechanisms for writing platform-specific implementations for a common API.


One of the common use-cases, and indeed my main use-case, for KMP is to share code between an Android and iOS project.


With KMP you have a few different options when it comes to deciding how to structure your projects.

You can combine your Android and iOS project into one project. They would live within the same directory and both be able to access and build the KMP shared code.

One of Kotlin’s example projects has this structure:

They also have a great codelab which walks you through setting up a project like this:


The main benefit of this approach is how easy the shared code is to access. No matter which platform you are working on, you can access, update and build the shared code. This makes development fast, particularly for solo development teams.


This setup can be overwhelming for new team members joining a project. There is a lot of code to digest and understand.

For teams with separate Android and iOS developers, working this way can be difficult. Changes can get made in the shared code, which requires changes on both platforms. Meaning you have to work more in tandem, which can be difficult for resource scheduling.

You could completely separate out your shared and platform projects. This involves writing build (Gradle) logic to distribute your shared code between projects.

Android Lib

KMP provides a gradle task for building a JVM JAR file for the Android code.

./gradlew [targetName]Jar

iOS Framework

To create the framework needed for iOS you can write a custom gradle task, for example:

task releaseFatFramework(type: FatFrameworkTask) { 
group = LifecycleBasePlugin.BUILD_GROUP
baseName = frameworkName
destinationDir = file("$buildDir/fat-framework/release")

This can vary based on your exact target configuration.


The code has good separation of concerns and is great for bigger teams. You can distribute the shared code in a more structured manner. Deciding exactly when to release to the two platforms.

For bigger teams, who have separate Kotlin engineers, this might be a helpful approach.


This approach could result in lots of CI configuration and boilerplate. It will probably take longer to setup.

Having to have multiple projects open will cause frequent context switching during development. It will also take more cognitive load to understand the entire picture.

The middle ground approach would mean having the shared code within one of the platform projects.

This naturally (and arguably obviously) would fall within the Android project. This isn’t necessary, but given it shares a language with Android, this would be my recommendation. It will reduce cognitive load and feel familiar to Android developers.

This will, however, shift the responsibility for the shared code onto your Android team. It is worth considering this point and making sure it’s right for your team.

Within the Android project you setup the shared code as a KMP module. IntelliJ has some helpful wizards for this.

This approach makes depending on the shared code, within Android, easy:

dependencies {
// ...
implementation project(':shared')
// ...

You can then add a framework generation task for iOS, like the one detailed above.

I then integrated this framework generation into our CI strategy. Every evening, if the shared code has changed, we submit a pull request into the iOS project. This pull request updates the shared framework. This means your iOS team will be aware of the update and be able to merge the change quickly. It also fits into the iOS CI process, giving you warning of any test failures and therefore changes that are needed.

We use CircleCI (version 2.1), and this is the job configuration:



Environment Variables:

FRAMEWORK_GIT_URL: The url to the git project you would like to commit the updated framework into. e.g. FRAMEWORK_PATH: The path to the destination framework directory. No leading or trailing separator. e.g. Project GITHUB_TOKEN: OAuth token for accessing github through hub command line


This approach reduces cognitive load and minimises the setup and boilerplate. It keeps the Kotlin code in one project, so not introducing more overhead to your iOS team.


Shifting the shared code responsibility to your Android team might not be the right approach for you. It means scheduling your resources differently.

Our Approach

We currently use KMP to share the M (Model from MVVM) between Android and iOS. Meaning we share business logic, API integration and local data storage. These concepts don’t often require platform-specific variations and shares well between platforms.

We use Kotlin on our Android projects, and we generally have separate teams for each platform. So using the middle-ground approach fits our teams well. We try to schedule our Android work slightly ahead of iOS, to give time for the shared code to be started. This eases the iOS development and reduces the number of blockages.

Previous Post

Originally published at

The Startup

Medium's largest active publication, followed by +771K people. Follow to join our community.

Alistair Sykes

Written by

Mobile app developer, focusing on Android. Working at Brightec ( Links:

The Startup

Medium's largest active publication, followed by +771K people. Follow to join our community.

Alistair Sykes

Written by

Mobile app developer, focusing on Android. Working at Brightec ( Links:

The Startup

Medium's largest active publication, followed by +771K people. Follow to join our community.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store