Configuring R8 For Compose
Use 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-aware optimizations (lambda grouping, `sourceInformation()` stripping, composable arg constant-folding, `ComposerImpl` devirtualization), legitimate keep needs (`@Serializable`, Hilt entry points, reflective `Saver`s), and the AGP 8.x missing-rule reporter / R8 retrace. Cited gain is roughly 75 percent startup and 60 percent frame-render improvement debug-to-release. Use when setting up a new Compose app, when a PR adds an over-broad keep like `-keep class androidx.compose.** { *; }`, when a release build crashes after enabling minification, when APK size needs reduction, or when first enabling minification.
MCP get_skill({ skillId: "configuring-r8-for-compose-5c5d0d85" })Use this skill with your agent
Create a free account and connect via MCP
# Configuring R8 for Compose — Trust Consumer Rules, Avoid Blanket Keeps
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.
## When to use this skill
- Setting up a new Compose app's release variant for the first time.
- A PR adds `-keep class androidx.compose.** { *; }` or any other Compose-wide keep — push back and apply this skill.
- A release build crashes after enabling minification — the cause is almost always a missing keep on a reflective consumer, not on Compose itself.
- APK size review surfaces a large `classes.dex` and the developer wants to know why.
- The first time `isMinifyEnabled = true` is being flipped on, before any release benchmark is run.
- Cross-link from `../../measurement/testing-compose-in-release-mode/SKILL.md` whenever release measurement is being set up.
## When NOT to use this skill
- The app is not yet ready to ship a release variant — wait until perf and crash budgets are in scope.
- 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.
- The release variant has been measured and is fine — do not pre-emptively add keep rules.
- The perf concern is recomposition, layout phase, or stability — see the relevant `stability/` or `recomposition/` skills.
## Prerequisites
- 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`.
- A buildable release variant (debug-signed is fine while iterating — see `../../measurement/testing-compose-in-release-mode/SKILL.md` for measurement signing).
- Kotlin 2.0+ with the `org.jetbrains.kotlin.plugin.compose` plugin so Compose's bundled consumer rules are wired correctly through dependency resolution.
- Familiarity with the difference between `proguard-android.txt` (no R8 optimizations) and `proguard-android-optimize.txt` (R8 optimizations on).
## What R8 actually does for Compose (since AGP 8.0)
Surface these to the developer when they ask "why bother" or push back against minification:
1. **Lambda grouping.** R8 merges many of Compose's generated lambda classes, reducing dex size and method count.
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.
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.
4. **`ComposerImpl` devirtualization.** R8 devirtualizes hot calls into Compose's runtime, which is a major contributor to the cited frame-render improvement.
5. **Resource shrinking.** Paired with `isShrinkResources = true`, R8 strips unreachable drawables, strings, and layout XML.
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).
## Workflow
- [ ] **1. Configure the release buildType.** This is the entire happy-path config — no Compose-specific keeps needed:
```kotlin
// app/build.gradle.kts
android {
buildTypes {
release {
isMinifyEnabled = true
isShrinkResources = true