using-efficient-effects

Installation
SKILL.md

Using Efficient Effects — pick the cheapest correct effect API

Compose ships three effect APIs by default: LaunchedEffect (coroutine, restarts on key change), DisposableEffect (setup/teardown with a cleanup block), and SideEffect (runs on every successful composition). The skydoves/compose-effects library adds RememberedEffect — a non-coroutine analog of LaunchedEffect. Picking the wrong API wastes a coroutine scope, leaks a listener, or silently drops the latest version of a callback. This skill is the decision tree.

When to use this skill

  • The user asks which effect API to choose, or why a LaunchedEffect restarts unexpectedly.
  • A long-lived LaunchedEffect calls a stale version of a callback that the parent has updated.
  • A non-Compose subscriber (listener, observer, broadcast receiver, GL surface) needs setup at composition entry and teardown on key change or exit.
  • A composable just needs to react to a key change synchronously and a coroutine scope is overkill.
  • A LazyColumn row needs its own ViewModel instance (e.g. one VM per chat row, one VM per feed card) and the parent VM store would leak state across rows.
  • The user is debugging unexpected effect restarts, leaked listeners, or per-frame allocations from SideEffect.

When NOT to use this skill

  • Pure derivation of one State<T> from another — use derivedStateOf. See ../../recomposition/choosing-derivedstateof/SKILL.md.
  • Collecting a flow that originates outside the composition — use collectAsStateWithLifecycle. See ../collecting-flows-safely/SKILL.md.
  • One-shot computation that must survive recomposition without re-running — use remember { ... }, not LaunchedEffect(Unit).
Related skills

More from skydoves/compose-performance-skills

Installs
8
GitHub Stars
377
First Seen
Apr 29, 2026