$npx -y skills add skydoves/compose-performance-skills --skill configuring-r8-for-composeUse this skill to configure R8 correctly for a Jetpack Compose application — full mode by default, proguard-android-optimize.txt, resource shrinking on, and minimal keep rules because Compose ships consumer ProGuard rules. Covers AGP 8.0+ R8 full mode default, R8's Compose-awar
| 1 | # Configuring R8 for Compose — Trust Consumer Rules, Avoid Blanket Keeps |
| 2 | |
| 3 | R8 is the only supported shrinker — ProGuard is deprecated. Compose ships consumer ProGuard rules, so most apps need **no** Compose-specific keep rules. The big modern wins come from R8 full mode (default since AGP 8.0): lambda grouping, `sourceInformation()` stripping, constant-folding of composable args, and `ComposerImpl` devirtualization. This skill teaches Claude to set R8 up minimally and refuse over-broad keeps that defeat those wins. |
| 4 | |
| 5 | ## When to use this skill |
| 6 | |
| 7 | - Setting up a new Compose app's release variant for the first time. |
| 8 | - A PR adds `-keep class androidx.compose.** { *; }` or any other Compose-wide keep — push back and apply this skill. |
| 9 | - A release build crashes after enabling minification — the cause is almost always a missing keep on a reflective consumer, not on Compose itself. |
| 10 | - APK size review surfaces a large `classes.dex` and the developer wants to know why. |
| 11 | - The first time `isMinifyEnabled = true` is being flipped on, before any release benchmark is run. |
| 12 | - Cross-link from `../../measurement/testing-compose-in-release-mode/SKILL.md` whenever release measurement is being set up. |
| 13 | |
| 14 | ## When NOT to use this skill |
| 15 | |
| 16 | - The app is not yet ready to ship a release variant — wait until perf and crash budgets are in scope. |
| 17 | - The developer is debugging a code-level bug (logic error, race, wrong state). R8 issues manifest as `ClassNotFoundException`, `NoSuchMethodError`, or empty reflection results — not behavioral bugs. |
| 18 | - The release variant has been measured and is fine — do not pre-emptively add keep rules. |
| 19 | - The perf concern is recomposition, layout phase, or stability — see the relevant `stability/` or `recomposition/` skills. |
| 20 | |
| 21 | ## Prerequisites |
| 22 | |
| 23 | - AGP 8.0+ for R8 full mode default. If on older AGP, full mode must be explicitly enabled in `gradle.properties` with `android.enableR8.fullMode=true`. |
| 24 | - A buildable release variant (debug-signed is fine while iterating — see `../../measurement/testing-compose-in-release-mode/SKILL.md` for measurement signing). |
| 25 | - Kotlin 2.0+ with the `org.jetbrains.kotlin.plugin.compose` plugin so Compose's bundled consumer rules are wired correctly through dependency resolution. |
| 26 | - Familiarity with the difference between `proguard-android.txt` (no R8 optimizations) and `proguard-android-optimize.txt` (R8 optimizations on). |
| 27 | |
| 28 | ## What R8 actually does for Compose (since AGP 8.0) |
| 29 | |
| 30 | Surface these to the developer when they ask "why bother" or push back against minification: |
| 31 | |
| 32 | 1. **Lambda grouping.** R8 merges many of Compose's generated lambda classes, reducing dex size and method count. |
| 33 | 2. **`sourceInformation()` stripping.** Each composable emits a string of source-position metadata. R8 removes it from release builds — smaller APK and less work per recomposition. |
| 34 | 3. **Composable arg constant-folding.** Constants that would have been wrapped by Live Literals in debug are now folded back into `if (changed and 1 == 0)` style checks the recomposer can short-circuit. |
| 35 | 4. **`ComposerImpl` devirtualization.** R8 devirtualizes hot calls into Compose's runtime, which is a major contributor to the cited frame-render improvement. |
| 36 | 5. **Resource shrinking.** Paired with `isShrinkResources = true`, R8 strips unreachable drawables, strings, and layout XML. |
| 37 | |
| 38 | Cited measurement: roughly **75 percent startup gain** and **60 percent frame-render gain** debug to release. Source: Ben Trengrove, "Why should you always test Compose performance in release" (Android Developers Medium). |
| 39 | |
| 40 | ## Workflow |
| 41 | |
| 42 | - [ ] **1. Configure the release buildType.** This is the entire happy-path config — no Compose-specific keeps needed: |
| 43 | |
| 44 | ```kotlin |
| 45 | // app/build.gradle.kts |
| 46 | android { |
| 47 | buildTypes { |
| 48 | release { |
| 49 | isMinifyEnabled = true |
| 50 | isSh |