Skip to content
All posts
June 26, 20263 min read

Kotlin StateFlow vs LiveData: The Definitive 2026 Guide

LiveData is deprecated. StateFlow is the answer — but knowing why matters more than knowing which. Here's the practical breakdown after switching 22+ Android apps.

AndroidKotlinArchitectureStateFlow
Share:

LiveData is effectively deprecated. Google hasn't removed it, but they've stopped recommending it for new development. If you're still using it in 2026, here's everything you need to know to switch — and why it matters beyond just following trends.

What LiveData actually is

LiveData is a lifecycle-aware observable data holder built for Android Views. It was designed before Kotlin Coroutines existed and before Jetpack Compose was a thing. It solves the problem of updating UI safely across lifecycle states using Android's Lifecycle system.

It works. It's not broken. But it was designed for a world that no longer exists.

What StateFlow actually is

StateFlow is a Kotlin Coroutines construct — a hot Flow that always has a value, emits to collectors, and is lifecycle-independent. It doesn't know or care about Android. That's the point.

kotlin
// LiveData
private val _uiState = MutableLiveData<LoginUiState>()
val uiState: LiveData<LoginUiState> = _uiState

// StateFlow
private val _uiState = MutableStateFlow<LoginUiState>(LoginUiState.Idle)
val uiState: StateFlow<LoginUiState> = _uiState.asStateFlow()

Structurally similar. Behaviorally very different.

The key differences that matter in practice

Initial value. StateFlow always requires an initial value. LiveData doesn't. This sounds minor but it eliminates an entire class of null-handling bugs — your UI always has something to render.

Lifecycle awareness. LiveData handles this automatically. StateFlow doesn't — you collect it using

code
repeatOnLifecycle
or
code
collectAsStateWithLifecycle
in Compose. This is more explicit, which is actually better.

Coroutine integration. LiveData has

code
liveData {}
builders and
code
switchMap
. StateFlow has the full Coroutines API —
code
map
,
code
filter
,
code
combine
,
code
flatMapLatest
. The StateFlow operators are more powerful and composable.

Testability. Testing StateFlow is cleaner. You don't need

code
InstantTaskExecutorRule
. You just set values and collect. The test code is simpler and less tied to Android infrastructure.

Compose compatibility.

code
collectAsStateWithLifecycle()
works perfectly with StateFlow. LiveData has
code
observeAsState()
which works but carries the lifecycle workarounds with it.

Migration pattern

The migration is mechanical:

kotlin
// Before
class LoginViewModel : ViewModel() {
    private val _state = MutableLiveData<LoginUiState>()
    val state: LiveData<LoginUiState> = _state
}

// After
class LoginViewModel : ViewModel() {
    private val _state = MutableStateFlow<LoginUiState>(LoginUiState.Idle)
    val state: StateFlow<LoginUiState> = _state.asStateFlow()
}

In Compose, replace

code
observeAsState()
with
code
collectAsStateWithLifecycle()
(from
code
lifecycle-runtime-compose
).

In non-Compose Views, replace

code
observe()
with:

kotlin
viewLifecycleOwner.lifecycleScope.launch {
    repeatOnLifecycle(Lifecycle.State.STARTED) {
        viewModel.state.collect { state ->
            // update UI
        }
    }
}

When LiveData is still acceptable

Legacy codebases with no immediate migration plan. Mixed Compose/View codebases where the LiveData + DataBinding wiring would cost more to remove than keep. If it's already working and the app is stable, the migration risk may not be worth it.

For new code: StateFlow, always.

The actual reason to switch

It's not about following Google's recommendations. It's that StateFlow composes better. You can

code
combine
two StateFlows to derive a third. You can
code
filter
and
code
map
them. You can test them without Android infrastructure.

The more complex your state management gets, the more the functional operators on Flow save you. LiveData has no equivalent.

After switching 22+ apps: the migration is low risk, the upside compounds over time, and there's no scenario where I'd choose LiveData for new work.

Share:
S

Sudarshan Chaudhari

AI Systems Builder / Product Engineer

Bangkok, Thailand

Solo Android developer with 13+ years in QA, building Android apps, AI automation systems, and developer tools at SudarshanTechLabs.

Stay updated

Get new posts on Android, Kotlin, and solo dev straight to your inbox.

Newsletter preferences

Related Apps

MyFamilyTracker

Real-time family location sharing — Firebase Realtime DB for sub-second propagation, WorkManager + ForegroundService for OS-compliant background collection, geofencing via Google Maps API.

Building something? Available for Android dev and QA consulting.

Work with me

Comments — powered by Giscus

Apps tagged with this