Kotlin Multiplatform¶
KMP checks: source-set complexity, target bloat, expect/actual consistency, and cross-module version drift.
13 checks.
kmp-common-code-fragmented¶
Severity: Low
Fragmenting common code across many intermediate source sets makes it hard to locate logic and raises the cost of every cross-platform change.
How to fix: Collapse redundant intermediate source sets; prefer the default hierarchy template for common→platform sharing.
kmp-deep-source-set-nesting¶
Severity: Low
Deeply nested intermediate source sets make it hard to know where code belongs and complicate adding/removing a target.
How to fix: Flatten the hierarchy using the Kotlin default hierarchy template instead of hand-rolled intermediate source sets.
kmp-empty-target-source-set¶
Severity: Low
Empty source-set blocks are dead configuration: they enlarge the source-set graph and confuse readers without holding any platform code.
How to fix: Remove the empty source-set block, or move shared code into it. Default target source sets do not need an explicit empty block.
kmp-excessive-targets¶
Severity: Low
Every extra target compiles and tests separately — build/CI time and the source-set matrix grow with the target count. Unused targets are pure overhead.
How to fix: Declare only the targets you actually ship. Drop unused platforms (or gate them behind a flag) to shrink the build matrix.
kmp-ios-targets-without-integration¶
Severity: Low
Apple targets that nothing integrates still cost build/CI time and signal an abandoned or externally-consumed iOS surface that may be unintentional.
How to fix: Add the iOS app/integration (Xcode project, SwiftPM, or CocoaPods consuming the framework), or remove the Apple targets if they are not shipped from this repo.
kmp-kotlin-plugin-version-drift¶
Severity: Low
Mixed Kotlin compiler versions across modules produce incompatible klib/metadata and fail the multiplatform build or cause subtle ABI mismatches.
How to fix: Pin one Kotlin version (e.g. via a version catalog or the root plugins block) and reference it from every module.
kmp-large-source-set-matrix¶
Severity: Low
A sprawling source-set matrix increases cognitive load, build graph size, and the chance of misplaced platform code.
How to fix: Consolidate intermediate source sets and rely on the default hierarchy template where possible.
kmp-legacy-native-memory-api¶
Severity: Low
The new Kotlin/Native memory manager is the default since 1.7.20 and the only one since 1.9.20. freeze()/isFrozen/@SharedImmutable/ensureNeverFrozen are no-ops or removed — the code still compiles but the freezing guarantees are gone. It is dead weight that misleads anyone reasoning about cross-thread sharing.
How to fix: Remove freeze()/isFrozen/ensureNeverFrozen calls and the @SharedImmutable annotation; share state directly under the new memory manager. If you are still on the legacy manager, migrate (kotlin.native.binary.memoryModel=experimental is no longer needed).
kmp-library-version-drift¶
Severity: Low
Different versions of the same library across modules invite classpath conflicts, duplicated transitive graphs, and runtime errors that depend on resolution order.
How to fix: Declare shared dependency versions once (version catalog / platform BOM) and reference them from all modules.
kmp-missing-actual¶
Severity: Medium
Every expect needs a matching actual per target. With none, the build fails to compile — or, if hidden by a missing target, ships a broken platform.
How to fix: Provide an actual for each expect in the relevant platform source sets (e.g. androidMain, iosMain).
kmp-orphan-actual¶
Severity: Low
An actual with no corresponding expect is dead or mismatched code — usually a leftover from a removed expectation.
How to fix: Remove the orphan actual, or restore the expect declaration it implements in commonMain.
kmp-partial-actual-coverage¶
Severity: Low
A platform source set with expectations upstream but no actuals can fail to compile for that target while others build fine.
How to fix: Confirm each platform implements its expectations (directly or via a shared intermediate source set); add the missing actuals.
kmp-toolchain-version-drift¶
Severity: Low
Mismatched JVM targets across modules can produce class-version errors at runtime and inconsistent desugaring/behavior.
How to fix: Configure a single jvmToolchain version in a convention plugin or the root build and apply it everywhere.