Trending: On-device modelsSearch
iHeartGeek
iTECH

Kotlin Multiplatform can compile modules separately

JetBrains has added an optional separate compilation scheme to Kotlin Multiplatform that makes the compiler agree with IntelliJ IDEA about shared code.

JetBrains Multiplatform graphic reading: separate compilation in 2.5.0-Beta1

JetBrains has quietly made the Kotlin Multiplatform compiler stricter about common code, and the difference shows up the moment your editor and your build stop agreeing. Kotlin 2.5.0-Beta1 introduces an optional separate compilation scheme that resolves shared code the way IntelliJ IDEA already does, and it is switched off until you ask for it.

What separate compilation changes

In the current scheme, compiling a platform source set such as jvmMain also compiles the shared code in commonMain against that platform's artefacts. Shared code can therefore reach a declaration that exists on only one target and still build cleanly, because the platform half of the dependency is sitting right there for the compiler to resolve against.

IntelliJ IDEA takes the opposite view. Its analysis works from the metadata KLIB that ships with a dependency, and that metadata describes common declarations only, so the same call is reported as an unresolved reference in the editor. The result is a project that looks broken in the IDE and compiles anyway, which is exactly the sort of disagreement that wastes an afternoon.

Why the mismatch is worth fixing

It is not only a false alarm in the editor. Code that only works because common source was compiled against platform artefacts can fail later, when a different target is built or a dependency is repackaged. JetBrains is describing the change as a way to make compilation results consistent with IDE analysis and to point more consistently at the library calls that cause the trouble.

How to switch it on

Separate compilation is experimental and disabled by default. Opting in means adding kotlin.kmp.separateCompilation=true to gradle.properties. JetBrains has published a list of known issues alongside the option, so a test run first is sensible.

Stricter resolution will bite some existing code. A shared file that calls a platform-only class compiles today and will not compile under the new scheme. The documented fix is to make the relationship explicit: declare an expect class in common code and mark the platform class as the actual implementation. The same stricter behaviour applies to commonTest source sets, because tests compile against the main code they depend on.

Who should reach for it

Teams already fighting phantom errors in their IDE will get the most from the flag, particularly libraries that publish multiplatform artefacts and need their metadata to describe what common code is genuinely allowed to call. Anyone with a large existing codebase should expect some cleanup, which is precisely why the setting is opt-in rather than the default.

Our opinion

A compiler that agrees with your editor sounds like table stakes, not a feature, and that is the strongest thing you can say about separate compilation. Kotlin Multiplatform has spent years asking developers to hold two mental models of the same source set, and the cost of that has always landed on whoever was newest to the project. Making the strict reading available is the honest fix, because it tells you now rather than during a release build. The disappointment is the default: another experimental flag that every team has to discover, discuss and agree before the tooling stops surprising them. JetBrains has the evidence that the loose behaviour causes real confusion, so the eventual move to strict-by-default cannot come soon enough.