kmp-coroutines-flow-patterns

Implements structured concurrency, Flow type selection, and coroutine testing patterns for Kotlin Multiplatform.

2|Updated Jun 6, 2026
One-click install
npx skills add https://github.com/ronjunevaldoz/kmp-agent-skills --skill kmp-coroutines-flow-patterns-ronjunevaldoz
Or copy as Structured Prompt for Agent▼
Please help me install this Agent Skill.
Skill: kmp-coroutines-flow-patterns
Source: https://github.com/ronjunevaldoz/kmp-agent-skills/tree/main/skills/kmp-coroutines-flow-patterns
Command: npx skills add https://github.com/ronjunevaldoz/kmp-agent-skills --skill kmp-coroutines-flow-patterns-ronjunevaldoz

SYSTEM DOCUMENTATION & REQUIREMENTS

What problem does it solve? Kotlin Multiplatform developers frequently misuse coroutines and Flow: launching work on GlobalScope that outlives its lifecycle, wrapping collect calls in try/catch that masks collector bugs, choosing the wrong Flow type and silently dropping events, or writing flaky coroutine tests. This Skill provides the shared foundation of correct coroutine and Flow patterns that screen-level state management and repository layers build on. ## Core Features & Use Cases - Structured Concurrency & Scope Hierarchy: Enforces parent scopes tied to real lifecycles (viewModelScope, TestScope) instead of GlobalScope, with parallel decomposition via coroutineScope and async/awaitAll. - Flow Type Selection & Exception Transparency: Guides selection between cold Flow, StateFlow, SharedFlow, and Channel, and enforces the catch operator over try/catch around collect, plus retryWhen backoff and flatMapLatest/flatMapMerge/flatMapConcat selection. - Cancellation-Safe Cleanup & Testing: Covers NonCancellable cleanup in finally blocks, Mutex over blocking locks, and testing with runTest and Turbine. - Use Case: When building a search-as-you-type feature in a KMP app, use this Skill to debounce the query flow, cancel in-flight requests with flatMapLatest, expose results as StateFlow, and verify the emission sequence with Turbine in runTest. ## Quick Start Ask the agent to review or write coroutine and Flow code for your Kotlin Multiplatform module, for example to convert a GlobalScope-based sync routine into structured concurrency with StateFlow status and a Turbine test.

Frequently Asked Questions about kmp-coroutines-flow-patterns

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

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

Use StateFlow for UI state that always has a current value and can conflate intermediate emissions. Use SharedFlow when broadcasting events to multiple collectors or replaying recent values to late subscribers, and Channel for one-shot effects like navigation.

How do I run suspend functions in parallel with coroutines?▼

Wrap the calls in coroutineScope and launch each with async, then await the results. coroutineScope propagates any child failure to siblings and waits for all children, unlike sequential calls which block each subsequent call from starting.

Why is try/catch around flow.collect() an anti-pattern?▼

Wrapping collect in try/catch also catches exceptions thrown inside the collector body, masking bugs unrelated to the upstream Flow. The catch operator intercepts only upstream exceptions placed above it in the chain, which is the intended exception-transparency contract.

How do I test Kotlin Flow emissions with Turbine?▼

Call flow.test {} inside a runTest block and assert each emission with awaitItem(), finishing with cancelAndIgnoreRemainingEvents(). runTest uses virtual time so delay calls skip instantly, and awaitItem fails loudly if an expected emission never arrives.

When should I use flatMapLatest vs flatMapMerge?▼

Use flatMapLatest when a new upstream value should cancel the previous inner Flow, such as search-as-you-type. Use flatMapMerge when inner Flows are independent and can run concurrently, and flatMapConcat when they must execute strictly in order.

Why does cleanup code not run after coroutine cancellation?▼

A suspending call inside a finally block throws immediately once the coroutine is cancelled. Wrap cleanup that must suspend in withContext(NonCancellable) so it completes even after cancellation, or use onCompletion for Flows.