Cross-platform development significantly reduces overhead for both developers and organizations. While React Native leveraged web expertise and Flutter introduced a unified UI for multi-platform delivery, Kotlin Multiplatform (KMP) represents the next evolution. KMP offers the flexibility of Compose for shared UI, while uniquely allowing developers to implement native interfaces where maximum performance and stability are required—all while maintaining a single shared logic base in Kotlin.
Finding comprehensive resources for Kotlin Multiplatform (KMP) using Native UI can be challenging, so this series aims to bridge that gap.
We will build a production-ready foundation using a modular Clean Architecture—the industry standard for scalable apps. Our roadmap covers the essential pillars of modern development:
- Dependency Injection,
- Networking,
- and Architecture.
In this first installment, we’ll kick things off by implementing Dependency Injection with Koin.
Creating a new Project
The recommended IDEs are IntelliJ IDEA and Android Studio. I'll use Android Studio
Install the KMP plugin: in the sidebar of Android Studio, select plugins

Look for "Kotlin Multiplatform" and install it
Complete the wizard process by choosing the project name, and do not share the UI
That is it, simple and easy
Koin Implementation Guide for Native UI
We start with:
Koin Build libs
Basically, it is this article from Koin documentation, in short:
- in
gradle/libs.versions.toml:
[versions]
koin = "4.2.0"
koin-plugin = "0.4.1"
[libraries]
koin-core = { module = "io.insert-koin:koin-core", version.ref = "koin" }
koin-annotations = { module = "io.insert-koin:koin-annotations", version.ref = "koin" }
koin-compose = { module = "io.insert-koin:koin-compose", version.ref = "koin" }
koin-compose-viewmodel = { module = "io.insert-koin:koin-compose-viewmodel", version.ref = "koin" }
koin-ktor = { module = "io.insert-koin:koin-ktor", version.ref = "koin" }
koin-test = { module = "io.insert-koin:koin-test", version.ref = "koin" }
[plugins]
koin-compiler = { id = "io.insert-koin.compiler.plugin", version.ref = "koin-plugin" }
- In the shared module's
shared/build.gradle.kts:
plugins {
alias(libs.plugins.koin.compiler)
}
kotlin {
...
sourceSets {
commonMain.dependencies {
implementation(libs.koin.core)
implementation(libs.koin.annotations)
implementation(libs.koin.compose.viewmodel)
implementation(libs.koin.ktor) // for Ktor web client DI
}
commonTest.dependencies {
implementation(libs.koin.test)
}
}
}
- In the Android module's
composeApp/build.gradle.kts
kotlin {
...
sourceSets {
...
commonMain.dependencies {
...
implementation(libs.koin.compose) // contains android
}
...
}
}
Compose contains the Android Koin dependency; it can be used as a common or Android dependency.
Koin Project setup
After installing all libraries, it is time to set up the code. You can follow this also to set it up
- create KoinModules in the shared module
// shared/commonMain/kotlin/di/KoinModules.kt
import org.koin.core.module.Module
import org.koin.dsl.module
val sharedModule = module {
}
expect val platformModule: Module
- create the platform modules, Android
// shared/androidMain/kotlin/di/PlatformModule.android.kt
import org.koin.dsl.module
actual val platformModule = module {
}
iOS:
// shared/iosMain/kotlin/di/PlatformModule.ios.kt
import org.koin.dsl.module
actual val platformModule = module {
}
- Koin initialization: we start with the shared module
// shared/commonMain/kotlin/di/KoinInit.kt
import org.koin.core.context.startKoin
import org.koin.core.KoinApplication
import org.koin.dsl.KoinAppDeclaration
import org.koin.dsl.includes
fun initKoin(config: KoinAppDeclaration? = null): KoinApplication {
return startKoin {
includes(config)
modules(
sharedModule,
platformModule
)
}
}
Now, with the Android module, the simplest way is to add initKoin() in the MainActivity
// composeApp/kotlin/MainActivity.kt
...
import com.irsc.kotlinnativedemo.di.initKoin
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
initKoin()
...
}
}
But for the iOS module, we will follow the instructions this time. Let's start by creating KoinInitIos in the shared module.
// shared/src/iosMain/kotlin/di/KoinInitIos.kt
fun initKoinIos() {
initKoin()
}
Now to call it in the iOS native code
import SwiftUI
import Shared
@main
struct iOSApp: App {
init() {
KoinInitIosKt.doInitKoinIos()
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
Please notice that we are importing Shared (capital S), the Kotlin file KoinInitIos.kt is used with Kt postfix, and the function is used with do prefix
I have submitted a fix for the documentation code; hopefully, it will be fixed by the time you read this article
That is it, we have added Koin to our project successfully. The next step is to test it with view model injection
Stay tuned for the next article



Top comments (0)