using-efficient-effects

Selects the correct Jetpack Compose effect API for coroutines, listeners, and per-row ViewModels.

1|Updated Jul 6, 2026
One-click install
npx skills add https://github.com/citytexi/team-yg-pesonal-agent --skill using-efficient-effects-citytexi
Or copy as Structured Prompt for Agent▼
Please help me install this Agent Skill.
Skill: using-efficient-effects
Source: https://github.com/citytexi/team-yg-pesonal-agent/tree/main/.claude/skills/using-efficient-effects
Command: npx skills add https://github.com/citytexi/team-yg-pesonal-agent --skill using-efficient-effects-citytexi

SYSTEM DOCUMENTATION & REQUIREMENTS

What problem does it solve? Choosing the wrong Compose effect API wastes coroutine scopes, leaks listeners, or silently captures stale callbacks. This Skill provides a decision tree for picking between LaunchedEffect, DisposableEffect, SideEffect, rememberUpdatedState, and skydoves/compose-effects' RememberedEffect and ViewModelStoreScope. ## Core Features & Use Cases - Effect API decision tree: Maps each scenario (coroutine work, setup/teardown subscribers, synchronous key reactions, per-commit publishing) to the cheapest correct API. - Bug pattern fixes: Shows wrong/right code for stale callbacks in long-lived LaunchedEffect, listener leaks, and shared ViewModels across LazyColumn rows. - Use Case: A LazyColumn where every row needs its own ViewModel — wrap each row in ViewModelStoreScope(key = row.id) so hiltViewModel() resolves to a per-row store instead of the parent screen's store. ## Quick Start Ask the AI to review your composable and recommend which Compose effect API to use for a listener that needs cleanup on key change.

Frequently Asked Questions about using-efficient-effects

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

FAQPage Schema
How do I fix a stale callback inside LaunchedEffect?▼

Wrap the callback with rememberUpdatedState and reference the latest value inside the effect. The coroutine keeps running without restarting while always invoking the freshest lambda passed from the parent.

LaunchedEffect vs DisposableEffect: which should I use?▼

Use LaunchedEffect when the work suspends or needs a coroutine, such as network calls or animations. Use DisposableEffect for non-coroutine subscribers like listeners or observers that need explicit setup and onDispose cleanup.

How do I give each LazyColumn row its own ViewModel?▼

Wrap the row content in ViewModelStoreScope(key = row.id) from com.github.skydoves:compose-effects-viewmodel, then call hiltViewModel() inside. Without it, every row resolves against the parent screen's store and shares one ViewModel instance.

Does RememberedEffect replace LaunchedEffect?▼

RememberedEffect from skydoves/compose-effects replaces LaunchedEffect only when the body does not suspend. It reacts to key changes synchronously without allocating a coroutine scope, but it has no onDispose, so pair it with DisposableEffect for teardown.

Why does my LaunchedEffect restart unexpectedly?▼

The effect restarts whenever any key in its key set changes value. Lying about the key set or passing unstable keys causes unexpected restarts; conversely, omitting a value the effect closes over makes it miss updates.

When should I avoid SideEffect in Compose?▼

Avoid SideEffect for per-frame work or anything that allocates, because it runs on every successful composition commit. Reserve it for thin writes that publish Compose state to a non-Compose system you cannot subscribe to via DisposableEffect.