wnb-koin-feature-modulelisted
Install: claude install-skill wenubey/claude-android-skills
# Koin — feature-scoped module structure
This skill covers **how to organize Koin modules in a growing Android codebase**. The core rule: as an app scales, a single monolithic `viewModelModule` listing every ViewModel becomes a merge-conflict magnet and a review-friction generator. Split by feature; keep infrastructure by concern.
Pairs with `[[wnb-viewmodel-udf]]` — the VM shape the module binds.
## Non-negotiables
1. **Feature-scoped modules for feature code.** One `Module` per feature package (`customerModule`, `sellerModule`, `authModule`, `adminModule`, …). Each module bundles that feature's ViewModels *and* any bindings only that feature uses.
2. **Concern-scoped modules for cross-cutting infrastructure.** `databaseModule`, `ktorModule` / `firebaseModule`, `dispatcherModule`, `preferencesModule`, `connectivityModule`, `workerModule`. These stay concern-scoped because they are consumed by every feature.
3. **`viewModelOf(::XxxViewModel)` when the constructor is Koin-injectable end-to-end.** Only fall back to `viewModel { XxxViewModel(get(), get(named("foo")), get()) }` when you need qualifiers, `SavedStateHandle`, or manual argument massaging.
4. **`single` vs `factory` vs `viewModel`:**
- `single { }` — one instance per Koin scope. Use for repositories, DAOs, HTTP clients, dispatcher providers.
- `factory { }` — new instance every `get()`. Use for lightweight helpers you don't want to leak state across.
- `viewModel { }` / `viewModelOf(...)` — one instance