In Kotlin Multiplatform, dependencies are declared per source set, such as commonMain, androidMain and iosMain, not once per module. A complete inventory therefore has to cover every source set and target. Reading only the Android dependencies, or only the common block, will miss components that ship in other builds.
How the declarations work
The Kotlin documentation explains that each source set has its own dependencies block. Dependencies in commonMain are available to all targets, and only multiplatform libraries can go there because common code must compile for every declared target. Platform source sets hold platform-specific dependencies.
kotlin {
sourceSets {
commonMain.dependencies {
implementation(libs.kotlinx.coroutinesCore)
}
androidMain.dependencies {
// Android-specific dependencies
}
iosMain.dependencies {
implementation(libs.sqldelight.nativeDriver)
}
}
}
In the docs example, the SQLDelight native driver is available in the iOS source set but not in the Android or common source sets.
You declare one name, Gradle resolves many artifacts
You declare a common library name, not a platform-specific one. The Kotlin Multiplatform Gradle plugin resolves the matching platform artifacts for each target. The standard library is added to every source set, with the platform variant in platform source sets. Project dependencies work the same way.
That is convenient for developers and awkward for inventory, because one line in a build file turns into several artifacts, different for each target.
What to check in your inventory
| Question | Why it matters |
|---|---|
| Is every source set represented? | A component only in iosMain still ships in the iOS app |
| Are platform artifacts listed, not just the common name? | Advisories may apply to one platform artifact |
| Are test source sets separated from shipping ones? | Test only components should not drive release decisions |
| Is the version catalog used for all source sets? | One catalog entry can feed several targets |
Gradle version catalogs are the recommended way to manage versions here, and the Kotlin docs recommend them for Multiplatform projects. Remember that catalog versions are requests, not guarantees.
Steps to build a trustworthy inventory
- List the targets the project builds: Android, iOS, desktop, web, server.
- For each target, resolve its runtime classpath or equivalent, not only the declared list.
- Combine the results into one SBOM, tagging which target each component belongs to.
- Scan the combined list, then filter findings by the target that ships.
- Repeat on every release, since resolved versions can change without a build file change.
For the broader picture of a mobile project spanning several package managers, see how many dependency ecosystems are in a React Native or Flutter app, which applies to Kotlin Multiplatform as well.
Try it yourself
Click through it at your own pace, or open it full screen.
Look at how direct and transitive components are listed together, then ask whether your own inventory shows each target the same way.
Safeguard's SBOM and dependency scanning build an inventory from a repository you connect, and the free scan at gold.safeguard.sh/scan is a way to see what it finds.
Quick check
Can I put an Android only library in commonMain?
No. The Kotlin docs say only multiplatform libraries can go in commonMain, because common code must compile for every declared target.
Does one version catalog entry cover all targets?
It supplies the coordinate and version, and the plugin resolves the matching platform artifacts per source set. Confirm the resolved artifacts, not just the catalog line.
Sources
Last reviewed: 19 October 2026.