Koin for Compose
Koin provides full support for Jetpack Compose and Compose Multiplatform applications with dedicated packages for dependency injection.
Packages Overview
| Package | Use Case |
|---|---|
koin-compose | Base Compose API (multiplatform) |
koin-compose-viewmodel | ViewModel injection (multiplatform) |
koin-compose-viewmodel-navigation | ViewModel + Navigation 2.x |
koin-compose-navigation3 | Navigation 3 integration (multiplatform) |
koin-androidx-compose | Android convenience (includes koin-compose + koin-compose-viewmodel) |
All Compose APIs are defined in koin-compose and koin-compose-viewmodel. The koin-androidx-compose package is a convenience wrapper that includes both for Android projects.
Which Package Should I Use?
For Android-only projects:
// Option 1: Android convenience package (includes koin-compose + koin-compose-viewmodel)
implementation("io.insert-koin:koin-androidx-compose:$koin_version")
// Option 2: Use multiplatform packages directly
implementation("io.insert-koin:koin-compose:$koin_version")
implementation("io.insert-koin:koin-compose-viewmodel:$koin_version")
// Optional: Navigation integration
implementation("io.insert-koin:koin-androidx-compose-navigation:$koin_version")
For Compose Multiplatform projects:
commonMain.dependencies {
implementation("io.insert-koin:koin-compose:$koin_version")
implementation("io.insert-koin:koin-compose-viewmodel:$koin_version")
// Optional: Navigation integration
implementation("io.insert-koin:koin-compose-viewmodel-navigation:$koin_version")
}
Platform Support
| Platform | Compose Type | Status |
|---|---|---|
| Android | Jetpack Compose | Full support |
| iOS | Compose Multiplatform | Full support |
| Desktop | Compose Desktop | Full support |
| Web | Compose for Web | Experimental |
Starting Koin
Option 1: startKoin (Android only or External Setup)
Initialize Koin outside Compose for full control:
// Android Application class
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
startKoin {
androidContext(this@MyApplication)
androidLogger()
modules(appModule)
}
}
}
// Compose UI uses Koin automatically
@Composable
fun App() {
val viewModel = koinViewModel<MyViewModel>()
}
Use when: You need full control over Koin lifecycle, custom configuration, or integration with other frameworks.
Option 2: KoinApplication (Compose-Managed)
Let Compose handle Koin setup automatically:
@Composable
fun App() {
KoinApplication(configuration = koinConfiguration {
modules(appModule)
}) {
MyScreen()
}
}
Advantages:
- No external setup required (no Application class needed)
- Android Context injected automatically
- Handles start/stop based on composition lifecycle
- Manages configuration changes on Android
Use when: You want the simplest setup with less control.
Automatically injects androidContext and androidLogger on Android.
KoinMultiplatformApplication is deprecated. Use KoinApplication with koinConfiguration instead.
Basic Injection
koinInject() - Get Dependencies
Inject any Koin-managed dependency:
@Composable
fun UserScreen() {
val repository = koinInject<UserRepository>()
// Use repository...
}
Best practice - inject as default parameter:
@Composable
fun UserScreen(
repository: UserRepository = koinInject()
) {
// Testable without Koin
}
koinViewModel() - Get ViewModels
Inject ViewModels with proper lifecycle management:
@Composable
fun UserScreen() {
val viewModel = koinViewModel<UserViewModel>()
val state by viewModel.state.collectAsState()
}
See ViewModel in Compose for all ViewModel APIs.
With Parameters
Pass runtime parameters:
@Composable
fun DetailScreen(itemId: String) {
val viewModel = koinViewModel<DetailViewModel> {
parametersOf(itemId)
}
}
For better performance with frequent recomposition:
@Composable
fun DetailScreen(itemId: String) {
val viewModel = koinViewModel<DetailViewModel>(
parameters = parametersOf(itemId)
)
}
Defining Modules
Compiler Plugin DSL
val appModule = module {
single<UserRepository>()
viewModel<UserViewModel>()
}
Annotations
@Singleton
class UserRepository
@KoinViewModel
class UserViewModel(
private val repository: UserRepository
) : ViewModel()
Classic DSL
val appModule = module {
singleOf(::UserRepository)
viewModelOf(::UserViewModel)
}
Quick Reference
| Function | Purpose |
|---|---|
koinInject<T>() | Inject any dependency |
koinViewModel<T>() | Inject ViewModel |
koinNavViewModel<T>() | ViewModel with Navigation args |
koinActivityViewModel<T>() | Activity-scoped ViewModel (Android) |
rememberKoinModules() | Load modules with composition |
KoinScope {} | Create scoped context |
Documentation
| Topic | Description |
|---|---|
| ViewModel | All ViewModel injection APIs |
| Lifecycle & State | Recomposition, state, side effects |
| Dynamic Modules | rememberKoinModules, lazy loading |
| Scopes | KoinScope, KoinNavigationScope, UnboundKoinScope |
| Testing | Previews, unit tests |
| Isolated Context | SDK isolation |
| Navigation 3 | Type-safe navigation (multiplatform) |
Related
- Core ViewModel - ViewModel declaration DSL
- Android ViewModel - Android-specific features
- KMP Setup - Multiplatform configuration