Kotlin StateFlow & SharedFlow

Kotlin StateFlow & SharedFlow

StateFlow and SharedFlow are hot flows in Kotlin, introduced to handle state and events in a modern, coroutine-friendly way.
They are commonly used in Android (MVVM) and backend reactive systems.


1. Hot Flow vs Cold Flow (Quick Recap)

Feature Flow StateFlow / SharedFlow
Type Cold Hot
Starts emitting On collect Always active
Stores value ❌ No ✅ Yes (StateFlow)
Multiple collectors Yes Yes

2. StateFlow

🔹 What is StateFlow?

  • Holds one latest value

  • Always has an initial value

  • Emits updates to all collectors

  • Ideal for UI state

Think of StateFlow as LiveData replacement


Basic StateFlow Example

import kotlinx.coroutines.flow.*

class CounterViewModel {
private val _count = MutableStateFlow(0)
val count: StateFlow<Int> = _count

fun increment() {
_count.value += 1
}
}

Collecting:

count.collect {
println(it)
}

Key Properties of StateFlow

  • Requires initial value

  • Replays latest value only

  • Never completes

  • Always active


3. SharedFlow

🔹 What is SharedFlow?

  • Used for events

  • Does not require initial value

  • Can emit multiple values

  • Configurable replay & buffer

Think of SharedFlow as EventBus


Basic SharedFlow Example

class EventViewModel {
private val _events = MutableSharedFlow<String>()
val events = _events.asSharedFlow()

suspend fun sendEvent() {
_events.emit("User Logged In")
}
}

Collecting:

events.collect {
println(it)
}

4. StateFlow vs SharedFlow (Important)

Feature StateFlow SharedFlow
Use case State Events
Initial value Required Not required
Replay 1 (latest) Configurable
LiveData alternative ✅ Yes ❌ No
One-time events ❌ Not ideal ✅ Perfect

5. Replay & Buffer in SharedFlow

val flow = MutableSharedFlow<Int>(
replay = 1,
extraBufferCapacity = 2
)
  • replay → re-emit last values to new collectors

  • buffer → handles fast emitters


6. Emit vs TryEmit

_events.emit("Event") // suspend
_events.tryEmit("Event") // non-suspend

7. Collecting Safely

viewModelScope.launch {
stateFlow.collect {
// update UI
}
}

8. Android MVVM Example

class LoginViewModel : ViewModel() {

private val _uiState = MutableStateFlow(false)
val uiState: StateFlow<Boolean> = _uiState

private val _events = MutableSharedFlow<String>()
val events = _events.asSharedFlow()

fun login() {
_uiState.value = true
viewModelScope.launch {
_events.emit("Login Success")
}
}
}


9. StateFlow vs LiveData

Feature StateFlow LiveData
Coroutine support Native Limited
Thread safety Yes Partial
Platform Multiplatform Android only

Summary

  • StateFlow → UI State (latest value)

  • SharedFlow → One-time events

  • Both are hot flows

  • Built on coroutines

  • Better than LiveData & Event wrappers

You may also like...