kotlin-flows

Guides correct selection, creation, and lifecycle-safe collection of Kotlin Flow, StateFlow, SharedFlow, and Channel.

1|Updated Jun 1, 2026
One-click install
npx skills add https://github.com/chmonya-inc/dnd-manager --skill kotlin-flows-chmonya-inc
Or copy as Structured Prompt for Agent▼
Please help me install this Agent Skill.
Skill: kotlin-flows
Source: https://github.com/chmonya-inc/dnd-manager/tree/main/.agents/skills/kotlin-flows
Command: npx skills add https://github.com/chmonya-inc/dnd-manager --skill kotlin-flows-chmonya-inc

SYSTEM DOCUMENTATION & REQUIREMENTS

What problem does it solve? Kotlin coroutines offer multiple stream types (Flow, StateFlow, SharedFlow, Channel) with subtle semantic differences, and choosing or combining them incorrectly causes dropped events, leaked callbacks, swallowed cancellations, and race conditions. This Skill audits existing flow code and enforces correct patterns for stream selection, operator usage, error handling, and lifecycle-safe collection in Android and KMP projects. ## Core Features & Use Cases - Type Selection Guidance: Decision tables for choosing between cold Flow, StateFlow, SharedFlow, and Channel based on state retention, collector count, and event delivery guarantees. - Channel Audit & Migration: Detects deprecated BroadcastChannel and ConflatedBroadcastChannel usage and distinguishes legitimate single-consumer Channel use from broadcast misuse. - Pattern Enforcement: Covers callback bridging with callbackFlow and awaitClose, operator selection (flatMapLatest, combine, debounce), StateFlow encapsulation, and lifecycle-safe collection with collectAsStateWithLifecycle and repeatOnLifecycle. - Use Case: While refactoring a ViewModel, the Skill flags a publicly exposed MutableStateFlow, replaces a manual Job cancellation pattern with flatMapLatest, and converts a SharedFlow event stream to Channel(BUFFERED).receiveAsFlow() so navigation events are never dropped. ## Quick Start Review my ViewModel's StateFlow and event handling code and fix any violations of correct Kotlin Flow patterns.

Frequently Asked Questions about kotlin-flows

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I choose between StateFlow, SharedFlow, and Channel in Kotlin?▼

Use StateFlow for UI state that new collectors need immediately, Channel(BUFFERED).receiveAsFlow() for single-consumer fire-once events like navigation, and SharedFlow only for multi-collector broadcasts. Plain cold Flow fits one-off repository data streams.

How do I handle one-shot events like navigation in a ViewModel?▼

Use Channel(Channel.BUFFERED).receiveAsFlow() and collect it once inside a LaunchedEffect. Channel queues events until consumed, so navigation and snackbar events are never silently dropped when the UI is briefly inactive.

Should I expose MutableStateFlow from a ViewModel?▼

No. Keep the MutableStateFlow private and expose an immutable StateFlow publicly. Exposing the mutable type lets external callers mutate state directly, bypassing ViewModel logic and breaking encapsulation.

Why does my SharedFlow event get lost when the app is backgrounded?▼

SharedFlow with replay = 0 drops emissions when no collector is active, and repeatOnLifecycle stops collection below STARTED. For events that must not be missed, use Channel(BUFFERED).receiveAsFlow() which suspends send until a receiver consumes.

What is the difference between flatMapLatest and combine in Kotlin Flow?▼

flatMapLatest cancels the previous inner flow when the upstream emits, ideal for search queries. Combine merges multiple flows and emits whenever any upstream emits, ideal for deriving UI state from several StateFlows.

Why is catching Exception inside a flow collect block dangerous?▼

A broad catch intercepts CancellationException, preventing coroutine cancellation and leaking resources. Catch only specific exception types, rethrow CancellationException explicitly, or use the catch operator which skips it automatically.