Skip to content
AB

MVI Versus MVVM for Complex Health Application State

Use a single state and explicit events when screens combine permissions, synchronization, local data, remote data, and navigation.

Ashish BhakhandPublished

MVVM and MVI are not opposing religions. The useful difference is how explicitly a feature models change.

A health dashboard may combine Health Connect permission, local Room data, server scores, refresh progress, subscription state, and one-time navigation. Several unrelated LiveData or StateFlow properties can produce combinations the UI was never meant to show.

MVI exposes one immutable state:

Code
data class DashboardState(
    val loading: Boolean = true,
    val recovery: Score? = null,
    val sync: SyncState = SyncState.Idle,
    val error: UiError? = null,
)

Intents describe inputs; the ViewModel reduces results into a new state. The screen collects one flow.

Use side effects for events that should not be replayed as state, such as opening a system permission screen or showing a transient message. Durable facts such as an error banner or selected date belong in state.

MVI costs more vocabulary. A simple form can use ordinary ViewModel methods without inventing an elaborate reducer. It earns its place when concurrent sources and lifecycle restoration make implicit transitions risky.

The best architecture is the smallest one that prevents invalid state. For complex health and sync screens, one explicit state often pays for itself.

← Back to all writing