kotlin-flows

Installation
SKILL.md

Kotlin Flows

This reference covers the Flow traps and semantic edge cases — Channel vs SharedFlow, callback bridging, retry/error handling, side effects in transforms, and KMP boundaries — not the basics of cold/hot streams, the operator table, or lifecycle-safe collection.

Channel vs SharedFlow — the semantics that bite

Found Action
BroadcastChannel Migrate → SharedFlow (deprecated)
ConflatedBroadcastChannel Migrate → StateFlow (deprecated)
Channel for single-consumer fire-once events (nav, snackbars, one-shot effects) Keep — correct. Channel(BUFFERED).receiveAsFlow()
Channel broadcast to multiple collectors Migrate → SharedFlow (see below)
Channel as producer-consumer queue Keep — correct

Channel.receiveAsFlow() is fan-out, NOT broadcast. With multiple collectors, each event reaches one collector (the framework picks which), not all of them. If every collector must see every event, you need SharedFlow. This is the trap that's easy to fall into when reaching for Channel to multicast.

For single-consumer one-shot events, Channel(BUFFERED).receiveAsFlow() is the default because send suspends until consumed (the event is queued, never dropped), whereas SharedFlow(replay = 0) drops the emission if no collector is active at the instant of emission. Expose the Flow, never the Channel, and collect with collect inside LaunchedEffectnot collectAsStateWithLifecycle, which retains the last event as state and re-fires it on every recomposition / config change.

Installs
104
GitHub Stars
136
First Seen
Mar 9, 2026
kotlin-flows — rcosteira79/android-skills