Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Repair Windows errors before they cause bigger problems3Fix the driver behind crashes, sound loss and screen glitchesFor a solo developer, Kotlin Multiplatform (KMP) pays off most when you share the logic that must behave identically on Android and iOS, such as validation, pricing rules, or sync policy, and keep each platform’s UI native. Sharing UI with Compose Multiplatform is a legitimate choice, but it is a larger commitment than sharing rules, and it should be made on purpose rather than as a default. This guide covers the three main architectures, how to lay out modules, where platform code still lives, and the trade-offs that matter most when one person owns both apps.
Three architectures, and how to choose between them
KMP does not force a single architecture. Kotlin’s official overview says the approach allows gradual sharing and that the boundary may change as requirements change. The table below compares the three common shapes.
As an Amazon Associate I earn from qualifying purchases.
| Approach | What is shared | What stays platform-specific | Questions to ask before choosing |
|---|---|---|---|
| Share selected logic | A focused module such as validation, pricing, or sync policy | UI, app entry points, and platform integrations | How much duplicated rule code does this remove, and how large is the interop surface? |
| Shared logic with native UI | Business logic and data rules | Android UI and SwiftUI presentation, plus platform behaviors | Do you need the native look and feel, and do you have the skills to maintain two UIs? |
| Shared UI with Compose Multiplatform | UI, potentially navigation and state, plus business logic | App entry points and any APIs without multiplatform support | Does a unified design system matter more than platform-native behavior, and do the libraries you need support it? |
Kotlin’s official guidance on when to use KMP puts the principle plainly: “The goal isn’t to maximize code sharing, but to share code as needed to lower cost or risk without constraining product decisions.” (Kotlin Documentation, “How to build Android and iOS apps (and when to use Kotlin Multiplatform),” reviewed 7 October 2026.)
Free tools Windows power users keep installed
One-click scans. No signup required.
Why a solo developer should start narrow
A single person pays for every shared boundary in two places at once: the code and the release process. Starting with logic-only sharing keeps the blast radius small. If the shared module works well, you can widen it later. Moving UI into shared code later is harder than adding it at the start, so treat that step as a separate decision with its own evidence.
#1 Best Overall
Project structure
Kotlin’s recommended project structure keeps platform app entry points in separate modules that depend on shared code. The official page notes that “the optimal module structure can vary depending on your goals and necessary targets.” Three layouts cover most cases.
One shared module
If every app uses the same shared UI and business logic, one shared module is usually enough. It is the simplest layout and the easiest to reason about for a single maintainer.
Separate sharedLogic and sharedUI modules
If one app uses native UI, split the shared code into sharedLogic and sharedUI. The native app can depend on sharedLogic alone, which avoids pulling Compose dependencies into code that never renders a Compose screen.
Rank #2
A core module for client and server
The official guide also describes a core module for code shared between client and server targets. Add it only if your backend is written in Kotlin and genuinely needs the same models or rules.
Entry points must be separate with newer Android tooling
The recommended-structure page states that separating Android entry points from common code is mandatory when using Android Gradle Plugin 9 or newer, and it shows a configuration built on the newer Android KMP library plugin. Confirm your Kotlin and AGP versions against that page before copying any configuration. This article deliberately omits Gradle snippets, because they change between releases.
What lives in common code and what does not
In a basic Android and iOS project, shared Kotlin belongs in commonMain. Android-specific and iOS-specific implementations go in their platform source sets. On the iOS side, the shared code is built as a framework that the Xcode project integrates. On the Android side, the shared code is consumed as an Android library.
Rank #3
expect/actual is a boundary, not a shortcut
The expect/actual mechanism lets common code declare an API while each platform supplies its implementation. It is the standard way to reach platform APIs from shared logic, such as a clock, a file path, or a secure key store. Treat each declaration as a contract: the common declaration defines behavior, and both actual implementations must satisfy it. Test both sides, because a passing Android test says nothing about the iOS actual.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Shared Apple code goes in iosMain
Kotlin’s source-set guide says Apple-specific Kotlin code shared between iOS targets can live in iosMain, rather than being duplicated into architecture-specific source sets.
Platform entry points never disappear
Sharing screens does not remove launch code. With Compose Multiplatform, the Android app shows common composables from an Activity, while the iOS app initializes through its own app entry point. You still own two launch paths, two sets of lifecycle wiring, and any platform navigation glue.
Some platform APIs may not have multiplatform support. Kotlin’s documentation on default UI behavior states: “Certain platform-specific APIs necessary for your app may not have multiplatform support, and you will have to implement calling these APIs in platform-specific source sets.” Before committing to shared UI, list every platform API your app depends on and check each one against current library support.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.iOS targets and testing without losing the simulator
The KMP target model distinguishes between an iOS device target, iosArm64, and simulator targets. The official source-set guide states that a project with only the device target cannot run and debug locally on the simulator. On an Apple-silicon development machine, the simulator target commonly used is iosSimulatorArm64.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Building and running the iOS app requires macOS and Xcode. That is a platform requirement, not a KMP one, and it means a developer without a Mac cannot build the iOS target locally.
Best Value
A green Android build does not establish that the iOS target or simulator path works. Run the iOS build and its tests as separate steps, and confirm the simulator target is present in your Gradle configuration before debugging.
Trade-offs that matter most for one person
- Coordination. Changes to shared logic affect both apps. Kotlin’s overview calls out planning and coordination as real costs, so a shared-module change may need to ship in both apps in the same release window.
- Library maturity. Library and integration maturity varies by use case. When a library causes friction, record its exact name, its version, and a reproducible failure, rather than concluding that KMP as a whole is immature.
- Native integration gaps. Platform APIs without multiplatform support need hand-written actuals on each side, and each one adds a maintained surface.
- Dependency weight. A native-UI app that depends on a combined shared module inherits Compose dependencies it does not use. Splitting logic and UI avoids that.
- Two verification paths. Each platform needs its own build and test run, including the iOS simulator path.
Checklist before you commit to a structure
- List the rules that must match across platforms, and move only those into shared code.
- Decide whether the UI should be native on each platform, or shared with Compose Multiplatform.
- Enumerate every platform API you need and confirm multiplatform support for each one.
- Confirm your Kotlin and Android Gradle Plugin versions against the official structure page.
- Confirm you have a Mac with Xcode and a simulator target configured for iOS work.
- Write a test for each
expect/actualpair that runs on both platforms. - Document which library, version, and behavior caused each friction point, so the next decision rests on evidence.
Official references used in this guide: Kotlin Documentation, “How to build Android and iOS apps (and when to use Kotlin Multiplatform)”; “Recommended Kotlin Multiplatform project structure”; “Default UI behavior on different platforms”; and the Kotlin Multiplatform target and source-set guide, all reviewed 7 October 2026.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.
Recommended Free Tools




