Vlastimil Brecka
06/28/2026, 3:48 PMPierre Ayfri
06/28/2026, 9:17 PMVlastimil Brecka
06/28/2026, 9:34 PMpluginManager.withPlugin("org.jetbrains.kotlin.multiplatform") {
val kotlin = extensions.getByName("kotlin") as KotlinMultiplatformExtension
...
if (enableIosTarget.get() && kotlin.targets.findByName("iosSimulatorArm64") == null) {
kotlin.iosSimulatorArm64()
}
if (enableWasmTarget.get() && kotlin.targets.findByName("wasmJs") == null) {
kotlin.wasmJs {
browser()
}
}
...
}
targets are selectively enabled to not do unnecessary work while local dev-ing
plugins {
alias libs.plugins.kotlin.multiplatform
alias libs.plugins.foo.conventions
alias libs.plugins.kotlin.serialization
alias libs.plugins.android.kmp.library
alias libs.plugins.compose.compiler
alias libs.plugins.compose.multiplatform
alias libs.plugins.detekt
alias libs.plugins.metro
}
metro {
generateContributionProviders = true
}
def enableIosTarget = providers.gradleProperty("foo.enableIosTarget")
.map { it.toBoolean() }
.orElse(false)
.get()
def enableWasmTarget = providers.gradleProperty("foo.enableWasmTarget")
.map { it.toBoolean() }
.orElse(false)
.get()
kotlin {
android {
namespace = "com.foo.sharedui"
androidResources {
enable = true
}
}
if (enableIosTarget) {
iosSimulatorArm64() {
binaries {
framework {
baseName = "SharedUI"
binaryOption("bundleId", "sk.foo.sharedui")
export project(":findoc-detail")
export project(":findoc-detail-2")
export project(":findoc-detail-3")
... up to 100
export project(":findoc-detail-100")
}
}
}
}
if (enableWasmTarget) {
wasmJs()
}
sourceSets {
commonMain.dependencies {
implementation libs.androidx.compose.foundation
implementation libs.androidx.compose.material3
implementation libs.androidx.compose.components.resources
implementation libs.androidx.navigation3.runtime
implementation libs.androidx.navigation3.ui
implementation libs.kotlinx.datetime
implementation libs.coil.compose
api project(":findoc-detail")
api project(":findoc-detail-2")
api project(":findoc-detail-3")
... up to 100
api project(":findoc-detail-100")
api project(":foo:design-system")
api project(":bar:design-system")
}
androidMain.dependencies {
implementation libs.androidx.lifecycle.process
}
}
}
dependencies {
androidRuntimeClasspath libs.androidx.compose.tooling
}
and this is my umbrella module exposed to the ios app
as you can see I have 100 modules as dependencies (its a synthetic project to see how would the experience be if I were to migrate out actual build)
and each of the findoc projects as a build file of
plugins {
alias libs.plugins.kotlin.multiplatform
alias libs.plugins.foo.conventions
alias libs.plugins.kotlin.serialization
alias libs.plugins.android.kmp.library
alias libs.plugins.compose.compiler
alias libs.plugins.compose.multiplatform
alias libs.plugins.detekt
alias libs.plugins.metro
}
metro {
generateContributionProviders = true
}
kotlin {
android {
namespace = "com.foo.findoc"
androidResources {
enable = true
}
}
sourceSets {
commonMain.dependencies {
implementation libs.coroutines.core
implementation libs.androidx.compose.foundation
implementation libs.androidx.compose.material3
implementation libs.androidx.compose.components.resources
implementation libs.kotlinx.serialization.json
implementation project(":foo:design-system")
}
}
}
dependencies {
androidRuntimeClasspath libs.androidx.compose.tooling
}
findoc-detail-X represents a feature module, where the exposed part to ios is a screencomposable, or rather the viewcontroller wrapping it, nothing else is publicVlastimil Brecka
06/28/2026, 9:35 PM