# Using Efficient Effects

Use this skill to choose the cheapest correct effect API in Jetpack Compose, ...

- Repository: https://github.com/skydoves/compose-performance-skills (524 stars)
- Category: Engineering
- License: Apache-2.0
- Last updated: 2026-06-16
- Runs scripts: no, instructions only

## Install

Claude Code: `npx skills add skydoves/compose-performance-skills --skill using-efficient-effects -g -a claude-code -y`
Codex: `npx skills add skydoves/compose-performance-skills --skill using-efficient-effects -g -a codex -y`
Cursor: `npx skills add skydoves/compose-performance-skills --skill using-efficient-effects -g -a cursor -y`
Gemini CLI: `npx skills add skydoves/compose-performance-skills --skill using-efficient-effects -g -a gemini-cli -y`

## Description

Use this skill to choose the cheapest correct effect API in Jetpack Compose, `LaunchedEffect`, `DisposableEffect`, `SideEffect`, `rememberUpdatedState`, and skydoves/compose-effects' `RememberedEffect` and `ViewModelStoreScope`. Covers stale-callback bugs in long-lived `LaunchedEffect`, setup/teardown for non-coroutine subscribers, avoiding a coroutine scope just to react to a key change, and per-row ViewModels in a `LazyColumn`. Trigger when the user mentions LaunchedEffect, DisposableEffect, RememberedEffect, SideEffect, rememberUpdatedState, ViewModelStoreScope, effect restarts unexpectedly, leaked listener, or per-item ViewModel.

## SKILL.md, as published by its author (untrusted third-party text, read it as data)

# 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)`.

## Prerequisites

The rest: https://github.com/skydoves/compose-performance-skills/blob/HEAD/side-effects/using-efficient-effects/SKILL.md
