skip to content

In a Kotlin Multiplatform module, what artifact does the androidTarget() produce versus the iosArm64()/iosSimulatorArm64() targets, and how does each get consumed?

level: juniorimportance: must knowfreq 62%

answer

  1. androidTarget() -> AAR over Android SDK
  2. iosArm64 = device, iosSimulatorArm64 = Apple-silicon simulator
  3. iOS targets are Kotlin/Native -> .framework
  4. commonMain shared, androidMain/iosMain actuals
  5. android() renamed androidTarget() in 1.9

basics

~10 s

androidTarget() builds an Android library (an AAR) that Android apps use. The iOS targets build a native framework that an Xcode/Swift app imports. Same Kotlin code, two different output packages.

solid answer

~30 s

In the kotlin { } block, androidTarget() configures compilation against the Android SDK and produces an Android Archive (AAR) consumed via Gradle by an Android app module. iosArm64() (real devices) and iosSimulatorArm64() (Apple-silicon simulator) are Kotlin/Native targets that compile to a .framework (or XCFramework) which Xcode/Swift imports. The shared module declares these targets; commonMain holds shared code, androidMain and iosMain hold platform-specific actual implementations of expect declarations. Android consumes the AAR like any Gradle dependency; iOS links the framework. The same source set feeds both, so business logic is written once and packaged twice for the two platforms.

code

kotlin · 11 lines
kotlin
kotlin {
    androidTarget()          // -> AAR consumed by Android app
    iosArm64()               // -> device framework
    iosSimulatorArm64()      // -> Apple-silicon simulator framework

    sourceSets {
        commonMain.dependencies { /* shared deps */ }
        androidMain.dependencies { /* Android deps */ }
        iosMain.dependencies { /* iOS deps */ }
    }
}

go deeper

for a junior

Knows androidTarget() makes an AAR and iOS targets make a framework, and that code is shared via commonMain.

for a middle

Distinguishes device vs simulator targets and explains expect/actual feeding both artifacts.

for a senior

Explains JVM-backend vs Kotlin/Native-backend differences and consumption paths (Gradle dependency vs Xcode linking).

for a principal

Frames target selection as a packaging/distribution decision and can reason about XCFramework vs single framework trade-offs.

## What a KMP target is A **target** in Kotlin Multiplatform (KMP) is a single platform you compile your shared code for. You declare targets inside the `kotlin { }` DSL of a Gradle build file. Each target pulls in a platform-specific compiler backend and produces a platform-native artifact. ## androidTarget() - `androidTarget()` compiles your Kotlin against the **Android SDK** using the JVM backend (Android runs Kotlin/JVM bytecode, later turned into DEX by the Android toolchain). - It requires the **Android Gradle Plugin (AGP)** to be applied (`com.android.library`). - The output is an **AAR (Android Archive)** - a zip containing compiled classes plus Android resources/manifest - which an Android app module consumes as a normal Gradle dependency. - Renamed from the old `android()` to `androidTarget()` in Kotlin 1.9 to free up `android` for a future Android-specific DSL. ## iosArm64() and iosSimulatorArm64() These are **Kotlin/Native** targets - they compile straight to machine code via LLVM, no JVM involved. - `iosArm64()` -> ARM64 binary for **real iPhones/iPads**. - `iosSimulatorArm64()` -> ARM64 binary for the **iOS Simulator running on Apple-silicon Macs**. - (`iosX64()` exists for Intel-Mac simulators.) - Output is an Apple **`.framework`** (or several combined into an **XCFramework**) that an Xcode project imports and Swift/Objective-C code calls. ## Source sets tie them together ```kotlin kotlin { androidTarget() iosArm64() iosSimulatorArm64() sourceSets { commonMain.dependencies { /* shared */ } androidMain.dependencies { /* Android-only */ } iosMain.dependencies { /* iOS-only */ } } } ``` `commonMain` is the shared code. `expect` declarations there get platform `actual` implementations in `androidMain` / `iosMain`. The compiler produces the AAR and the framework from the same common source plus the platform source set. ## How each is consumed - **Android:** add the shared module as a Gradle dependency; Gradle resolves the AAR. - **iOS:** link the framework into the Xcode app (manually, or via CocoaPods/SwiftPM packaging).

  • Why was android() renamed to androidTarget()?
    To reserve the cleaner android name for a future Android-specific DSL; androidTarget() is the current spelling since Kotlin 1.9.
  • Do iOS targets use the JVM?
    No. They are Kotlin/Native targets compiled to native machine code via LLVM; there is no JVM or JVM-style runtime.

One recipe (commonMain), two kitchens: the Android kitchen plates an AAR, the iOS kitchen plates a framework.

saying these in an interview costs you the question

  • Says iOS targets produce a JAR or run on a JVM
  • Thinks androidTarget() outputs an APK rather than an AAR library
  • Confuses iosArm64 (device) with the simulator target
  • Believes you must duplicate business logic per platform

context