Track Compose Recomposition Causes with an IR-Based Monitoring Plugin
Compose performance debugging becomes a compile-time diagnostic: the plugin identifies the exact state that triggers each recomposition, works on every Compose Multiplatform backend, and is disabled in release builds. That spares developers from hand-instrumenting logs or chasing stack traces that never point at the offending state.
Compose screens lose smoothness when state changes too frequently, triggering excessive recomposition. Pinpointing the problematic state means collecting every state and parameter, diffing values on each recomposition, and logging the changes. Manual instrumentation and tools like Rebugger do this, but they clutter source and require updating monitoring code as signatures evolve.
Two compile-time approaches automate that injection. An ASM-based pipeline for Android injects bytecode that gathers states and diffs them on recomposition, gated behind a feature flag. It relies on fixed bytecode patterns produced by the Compose compiler, so future compiler optimizations can break it, and it only targets Android.
The newer ComposeStateMonitor plugin avoids those limits by hooking into the Kotlin compiler's IR phase. It adds plain @Composable calls before every composable exit, letting the Compose compiler itself process the monitoring code. The plugin adapts to Kotlin 2.0+ versions through compat layers, and it works with JVM, native, wasm, and JS backends. Source and usage are on GitHub.
Moving from ASM bytecode injection to an IR compiler extension shows that Compose Multiplatform tooling now has to hook into the compiler's own pipeline rather than the generated bytecode; the latter is too version-sensitive.
Injecting @Composable calls at the IR level means monitoring code is treated as first-class composable code, getting the same skipping and grouping optimizations, which is a clever way to keep overhead low.
The plugin's need for per-Kotlin-version compat layers underscores how unstable the IR editing API remains even after 2.0, a tax every compiler-plugin author pays.