Mavericks mvi
npx -y skills add ujffdi/mavericks-mvi-skills --skill mavericks-mviAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 3 stars3 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
Use when creating or modifying Mavericks 3.x State, MavericksState, MavericksViewModel, AssistedViewModelFactory, hiltMavericksViewModelFactory, ViewModelModule binding, initial args, Compose mavericksViewModel, collectAsStateWithLifecycle, Fragment MavericksView subscriptions, Async execute, setState, withState, DeliveryMode, uniqueOnly, or one-shot effects
SKILL.md
4.2 KB, as published. Nobody here has run it
Mavericks MVI Guide
Mavericks screens are rendered from immutable state. Keep state data-only, reducers pure, and side effects in ViewModel methods or UI consumers.
Quick Reference
| Task | Use |
|---|---|
| Define screen state | data class XxxState(...) : MavericksState |
| Create Hilt VM | @AssistedInject + @Assisted initialState + Factory + hiltMavericksViewModelFactory() |
| Register VM | @Binds @IntoMap @ViewModelKey in the owning ViewModelModule |
| One-shot request | suspend { repo.call() }.execute { copy(request = it) } |
| Long-lived Flow to normal state | flow.setOnEach { value -> copy(value = value) } |
| Refresh without UI flicker | .execute(retainValue = State::request) { ... } |
| Compose VM | mavericksViewModel() or mavericksViewModel(argsFactory = { args }) |
| Compose state | vm.collectAsStateWithLifecycle(State::prop) |
| Fragment VM | by fragmentViewModel() / activityViewModel() / parentFragmentViewModel() |
| Fragment state | vm.onEach(State::prop) { ... } |
| Fragment one-shot | vm.onEach(State::effect, deliveryMode = uniqueOnly()) { ... } |
| Read current state in VM | withState { state -> ... } or suspend awaitState() |
Core Rules
- State must be immutable, public, data-only, and reducer-safe.
- Hilt Mavericks VMs must use
@AssistedInject,@Assisted initialState,@AssistedFactory, andhiltMavericksViewModelFactory(). - Every Hilt Mavericks VM must be bound with
@Binds @IntoMap @ViewModelKey. - Use
executefor finite async work represented byAsync<T>. - Use
setOnEachfor long-lived Flows that map directly to ordinary State fields. - Use Mavericks lifecycle-aware Compose collection:
com.airbnb.mvrx.compose.collectAsStateWithLifecycle. DeliveryModeis only forMavericksViewsubscriptions, not ViewModelonEachand not Compose.- Effects are a project pattern on top of State; nullable single effects are not queues.
Read Only What You Need
- State fields, immutability, args, and
@PersistState: references/state.md - ViewModel template,
execute,setOnEach,setState,withState: references/viewmodel-execute.md - Hilt component and map binding: references/hilt.md
- Compose, Fragment,
MavericksView,DeliveryMode, scopes: references/observing-ui.md - Nullable effects, effect queues, consumption rules: references/effects.md
Async<T>states and rendering patterns: references/async.md- Mavericks ViewModel testing: references/testing.md
Common Pitfalls
| Pitfall | Fix |
|---|---|
| Missing State defaults with no args path | Add defaults or initialize through args/initialState() |
| Mutable State field | Use immutable/read-only types and copy on update |
| Storing derived values | Use computed properties |
Reading immediately after setState | Use reducer state, withState, or awaitState() |
| Heavy work inside reducer | Move work before setState or into execute(dispatcher) |
Long action inside VM onEach gets cancelled | onEach uses collectLatest; move long work elsewhere |
Flow wrapped in execute when no Async is needed | Use setOnEach |
| UI flickers during refresh | Use retainValue |
Rendering state with uniqueOnly() | Use default delivery mode |
Compose using legacy collectAsState | Use Mavericks collectAsStateWithLifecycle |
| Required Compose args omitted | Use mavericksViewModel(argsFactory = { args }) |
| Effect fires twice after Fragment restart | Use uniqueOnly() and clear after handling |
| Multiple effects lost | Use a list/queue or redesign event semantics |
| Hilt VM creation crashes | Check @AssistedFactory, companion factory, and ViewModelModule binding |