Builds Android Jetpack Compose UI with hoisted state, unidirectional data flow, and recomposition-safe patterns backed by measured stability rules. Use when someone asks "build this screen in Compose", "where should this state live", "why does my LazyColumn stutter", or is writing Composable functions, ViewModel and StateFlow wiring, or fixing recomposition jank in Kotlin. Do NOT use when the screen targets Flutter - use flutter-widget-architect instead; for iOS declarative UI use swift-ui; for React Native screens use react-native-pro; and if jank persists after state fixes, profile with mobile-perf-profiler.
Click to play with sound.
---
name: Jetpack Compose Builder
description: Builds Android Jetpack Compose UI with hoisted state, unidirectional data flow, and recomposition-safe patterns backed by measured stability rules. Use when someone asks "build this screen in Compose", "where should this state live", "why does my LazyColumn stutter", or is writing Composable functions, ViewModel and StateFlow wiring, or fixing recomposition jank in Kotlin. Do NOT use when the screen targets Flutter - use flutter-widget-architect instead; for iOS declarative UI use swift-ui; for React Native screens use react-native-pro; and if jank persists after state fixes, profile with mobile-perf-profiler.
---
# Jetpack Compose Builder
Build the state and data flow first, the pixels second - most Compose bugs are state-ownership and recomposition bugs, not layout bugs. The costly failure is a screen that works in a demo, then recomposes entire subtrees on every keystroke or scroll frame because state lives in the wrong place and parameters are unstable.
## Operating procedure
### Step 1: Gather inputs
Before writing a composable, establish:
1. The screen's state shape: what the user sees, what can change, and what triggers each change.
2. Which state is UI-local (text field focus, expanded flags) versus screen-level (loaded data, selection) versus app-level (auth, theme).
3. The data source: ViewModel exposing StateFlow, or a snapshot-state holder for pure-UI screens.
4. List characteristics if any: item count, item identity (stable server ids?), reorder/insert behavior.
5. Refresh-rate target of the flagship devices in the install base (60Hz gives a 16.6ms frame budget, 120Hz gives 8.3ms).
### Step 2: Map state ownership before drawing anything
Decide which state is UI-local (remember) versus screen-level (ViewModel exposing StateFlow, collected via collectAsStateWithLifecycle()). Hold mutable state in the lowest common ancestor that needs it - no lower (parent cannot drive it) and no higher (recomposes too wide a scope).
### Step 3: Make composables stateless by default… load the full skill through Skill Me