Flows in Kotlin

BipinBipin
2 min read

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")
}
TypeCold/HotKeeps LatestUse Case
FlowColdStreams of values from a source
StateFlowHotUI state, real-time values
SharedFlowHot❌ (can buffer)One-time events, notifications

Conclusion :

ScenarioUse
Emitting DB/API resultsFlow
UI screen stateStateFlow
Toasts, navigation eventsSharedFlow
0
Subscribe to my newsletter

Read articles from Bipin directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Bipin
Bipin