kotlin-flow-state-event-modeling

Guides selection and review of StateFlow, SharedFlow, and Channel primitives for Kotlin state and event modeling.

Updated May 21, 2025
One-click install
npx skills add https://github.com/albertmartorell1975/MeteoMartoCompose --skill kotlin-flow-state-event-modeling-albertmartorell1975
Or copy as Structured Prompt for Agent▼
Please help me install this Agent Skill.
Skill: kotlin-flow-state-event-modeling
Source: https://github.com/albertmartorell1975/MeteoMartoCompose/tree/main/.agents/skills/kotlin-flow-state-event-modeling
Command: npx skills add https://github.com/albertmartorell1975/MeteoMartoCompose --skill kotlin-flow-state-event-modeling-albertmartorell1975

SYSTEM DOCUMENTATION & REQUIREMENTS

What problem does it solve? Kotlin Flow offers several hot and cold primitives with different replay, buffering, and synchronous-read semantics, and choosing the wrong one causes dropped events, stale state, leaked sharing coroutines, or fake sentinel values leaking into domain types. This Skill provides concrete decision rules and code patterns for modeling state and one-shot events correctly. ## Core Features & Use Cases - Primitive selection guidance: Decision table mapping requirements (synchronous .value reads, fan-out, exactly-once delivery) to StateFlow, SharedFlow, Channel.receiveAsFlow, or plain Flow. - Common bug detection: Identifies anti-patterns such as stateIn() called inside functions, WhileSubscribed combined with synchronous .value reads, non-atomic read/modify/write on MutableStateFlow, and sentinel initial values like NoUser. - Code review support: Red-flag tables and before/after Kotlin snippets for reviewing Flow-based ViewModel and repository code. - Use Case: While reviewing an Android ViewModel, you notice navigation events emitted through a default MutableSharedFlow are occasionally lost; the Skill explains why and shows the Channel(BUFFERED).receiveAsFlow() alternative. ## Quick Start Ask the assistant to review your Kotlin ViewModel's StateFlow and SharedFlow usage for correctness using this skill.

Frequently Asked Questions about kotlin-flow-state-event-modeling

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

FAQPage Schema
How do I emit one-shot events like navigation or snackbars in Kotlin Flow?▼

For a single consumer handling exactly-once events, use a Channel(Channel.BUFFERED) exposed via receiveAsFlow() instead of a default MutableSharedFlow. Default SharedFlow has no replay buffer, so events emitted with no active collector are lost.

StateFlow vs SharedFlow: which should I use for UI state?▼

Use StateFlow when state always has a value and is read both by collectors and synchronous .value code. Use SharedFlow for hot streams with multiple subscribers where synchronous reads are not required, and configure replay explicitly.

Why does my StateFlow show stale data with WhileSubscribed?▼

SharingStarted.WhileSubscribed disconnects the upstream when no collectors are active, so .value returns the last cached or initial value. If .value must stay fresh without collectors, use SharingStarted.Eagerly or explicit initialization.

How do I update MutableStateFlow safely from multiple coroutines?▼

Use MutableStateFlow.update { current -> ... } instead of reading .value and writing it back. The update function applies the transform atomically against the latest state, preventing lost updates from concurrent modifications.

Why is calling stateIn() inside a function a problem?▼

Each call to stateIn() launches a new sharing coroutine on the given scope that never completes, so repeated calls leak coroutines and duplicate work. Assign the result to a val property so the shared instance is computed once.

What should I use instead of a sentinel initial value like NoUser in StateFlow?▼

Model absence explicitly with a nullable type, a sealed interface UI state, or Result, or use phase initialization where the StateFlow is only exposed after the real value loads. Sentinels force consumers to treat fake data as real domain values.