Dependency Injection (Koin) in Android/KMM App
Koin—DI framework on Kotlin DSL without code generation. Suitable where Dagger/Hilt is overkill: small-to-medium apps, KMM projects needing shared DI for Android and iOS, teams that don't need kapt or KSP in build.
Basic Setup
// build.gradle.kts
implementation("io.insert-koin:koin-android:3.5.0")
implementation("io.insert-koin:koin-androidx-viewmodel:3.5.0")
Dependency module:
val appModule = module {
single<UserRepository> { UserRepositoryImpl(get()) }
single { ApiService(get()) }
factory { AuthUseCase(get()) }
viewModel { LoginViewModel(get()) }
}
single—singleton for lifetime of Koin container. factory—new instance on each request. viewModel—creates ViewModel and registers in ViewModelStore.
Initialization in Application:
class App : Application() {
override fun onCreate() {
super.onCreate()
startKoin {
androidContext(this@App)
modules(appModule)
}
}
}
In Fragment or Activity:
val viewModel: LoginViewModel by viewModel()
val repository: UserRepository by inject()
Koin in KMM
In Kotlin Multiplatform, Koin allows you to declare shared dependencies in commonMain and platform-specific ones in androidMain / iosMain:
// commonMain
val commonModule = module {
single { UserSyncService(get()) }
factory { SyncUseCase(get()) }
}
// androidMain
val androidModule = module {
single<DatabaseDriver> { AndroidSqliteDriver(Database.Schema, androidContext(), "app.db") }
}
// iosMain
val iosModule = module {
single<DatabaseDriver> { NativeSqliteDriver(Database.Schema, "app.db") }
}
On iOS Koin is initialized via KoinApplication:
// Swift
KoinKt.doInitKoin(appDeclaration: { _ in })
This is the key advantage over Hilt: Hilt is Android-only, Koin works in shared code.
Typical Mistake
NoBeanDefFoundException at runtime—Koin didn't find binding for requested type. Reason: forgot to add module in startKoin, or type in inject<T>() doesn't match registered one (interface vs implementation). Unlike Dagger, error surfaces not at compile time but at first dependency access. For early detection—checkModules() in tests:
@Test
fun verifyKoinApp() {
koinApplication {
modules(appModule)
}.checkModules()
}
Setting up Koin for Android project—0.5–1 day. For KMM with multiple platform modules—2–3 days. Cost is calculated individually.







