Flows in Kotlin


Flow vs Stateflow vs Sharedflow
First, the Base Type: Flow<T>
A cold asynchronous stream.
Starts emitting only when collected.
Use for standard data streams (e.g., database queries, API paginated responses).
fun getNumbers(): Flow<Int> = flow {
emit(1)
emit(2)
}
Then the Hot Ones: StateFlow
and SharedFlow
:
StateFlow<T>
Hot flow — always active (even if no one is collecting).
Keeps and exposes the latest value.
Perfect for UI state (like screen loading state, user input, etc).
Backed by
MutableStateFlow
(which you update).Think of it like
LiveData
from Android but for coroutines.
val state = MutableStateFlow("Loading...")
state.value = "Done!"
state.collect {
println(it) // Always gets the latest value
}
SharedFlow<T>
Also hot flow, but doesn’t keep a "latest value".
More like an event bus — good for one-time events (like navigation, toasts).
Supports multiple collectors at once.
Tip: Use
SharedFlow
when:You want to broadcast something once.
You don’t care about storing the latest value.
val events = MutableSharedFlow<String>()
launch {
events.emit("Navigate to Home")
}
events.collect {
println("Event received: $it")
}
Type | Cold/Hot | Keeps Latest | Use Case |
Flow | Cold | ❌ | Streams of values from a source |
StateFlow | Hot | ✅ | UI state, real-time values |
SharedFlow | Hot | ❌ (can buffer) | One-time events, notifications |
Conclusion :
Scenario | Use |
Emitting DB/API results | Flow |
UI screen state | StateFlow |
Toasts, navigation events | SharedFlow |
Subscribe to my newsletter
Read articles from Bipin directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
