Android viewmodel
Skill ShinKev/kmp-skill-library/architecture/android-viewmodel
19 Claude AI skills for Kotlin Multiplatform (KMP) & Compose Multiplatform (CMP): architecture, networking, UI, testing, migration & build tooling for Android and iOS.
npx -y skills add ShinKev/kmp-skill-library --skill android-viewmodelAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Best practices for implementing ViewModels in KMP/CMP. ViewModel is now KMP-compatible via org.jetbrains.androidx.lifecycle. Covers StateFlow for UI state, SharedFlow for events, and platform differences in lifecycle-aware collection.
SKILL.md
2.9 KB, as published. Nobody here has run it
ViewModel & State Management (KMP + Android)
KMP Note: As of
lifecycle-viewmodel2.8+,ViewModelis KMP-compatible and lives incommonMainusingorg.jetbrains.androidx.lifecycle:lifecycle-viewmodel. No@HiltViewModelannotation — use Koin constructor injection instead. UsekoinViewModel()in composables.
Instructions
Use ViewModel to hold state and business logic. It must outlive configuration changes.
1. UI State (StateFlow)
- What: Represents the persistent state of the UI (e.g.,
Loading,Success(data),Error). - Type:
StateFlow<UiState>. - Initialization: Must have an initial value.
- Exposure: Expose as a read-only
StateFlowbacking a privateMutableStateFlow.private val _uiState = MutableStateFlow<UiState>(UiState.Loading) val uiState: StateFlow<UiState> = _uiState.asStateFlow() - Updates: Update state using
.update { oldState -> ... }for thread safety.
2. One-Off Events (SharedFlow)
- What: Transient events like "Show Toast", "Navigate to Screen", "Show Snackbar".
- Type:
SharedFlow<UiEvent>. - Configuration: Must use
replay = 0to prevent events from re-triggering on screen rotation.private val _uiEvent = MutableSharedFlow<UiEvent>(replay = 0) val uiEvent: SharedFlow<UiEvent> = _uiEvent.asSharedFlow() - Sending: Use
.emit(event)(suspend) or.tryEmit(event).
3. Collecting in UI
In commonMain CMP composables — use collectAsState():
val state by viewModel.uiState.collectAsState()
In Android-only composables (androidMain / androidApp) — use collectAsStateWithLifecycle() for lifecycle-aware collection that pauses when the app is backgrounded:
val state by viewModel.uiState.collectAsStateWithLifecycle()
For SharedFlow on Android, use LaunchedEffect with LocalLifecycleOwner.
In XML Views (Android-only) — use repeatOnLifecycle(Lifecycle.State.STARTED):
viewLifecycleOwner.lifecycleScope.launch {
viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.uiState.collect { /* update UI */ }
}
}
collectAsStateWithLifecycle(),lifecycleScope, andrepeatOnLifecycleare Android-only APIs. Never use them incommonMain.
4. Scope
- Use
viewModelScopefor all coroutines started by the ViewModel. It is available incommonMainvia the KMP-compatible ViewModel. lifecycleScopeis Android-only — never use it incommonMain.- Delegate specific operations to UseCases or Repositories; keep ViewModels thin.