All posts
$less posts/compose-stability-deep-dive.txt
posts/compose-stability-deep-dive.txt0 min
A Deep Dive into Compose Stability
author Nikita Pochaevdate Dec 2025category Android
If you’ve ever wondered why your Compose UI feels sluggish, the answer is almost always unnecessary recomposition. The Compose compiler tries to skip recomposition for composables whose parameters haven’t changed — but it can only do this for “stable” types.
What makes a type stable?
A type is stable if:
- All public properties are val (immutable)
- All property types are themselves stable
- It’s a primitive, String, or annotated with @Stable/@Immutable
The problem
Data classes from your domain layer often aren’t stable — they might contain List<T>, Map<K,V>, or other types the compiler can’t verify as stable.
Solutions (ranked by preference)
- Use kotlinx.collections.immutable — ImmutableList and ImmutableMap are stable
- Structure your composable parameters — pass primitives instead of complex objects
- Use @Stable annotation — but only when you can guarantee the contract
- Use Compose compiler metrics — to identify the actual problem spots
Measuring
Enable Compose compiler metrics in your build.gradle:
The metrics report will show you exactly which composables are skippable and which aren’t. Fix the unstable ones first — the ones that recompose most frequently.
#Android#Compose