hamen/compose_skill/compose-agent
Claude Code and agent skill by hamen/compose_skill
- community
Checking that the SKILL.md file is still in the repository.
Helps AI coding assistants write modern Jetpack Compose: correct state, side effects, performance-aware modifiers, Navigation 3, Paging 3 in Compose, coroutines on lifecycle, animations, UI tests, focus/keyboard navigation, Compose Multiplatform boundaries, idiomatic Kotlin, and well-shaped composable APIs. Targets the mistakes LLMs actually make in Compose code. Use when reading, writing, or reviewing Compose projects.
Install
npx vskill@latest install hamen/compose_skill/compose-agentSKILL.md
Compose Agent
Review, write, or modify Jetpack Compose code for correctness, modern API usage, and adherence to the official AndroidX guidelines. Report only genuine problems — do not nitpick or invent issues.
Target track (unless the repo says otherwise):
- Kotlin
2.0.20+with Compose Compiler1.5.4+(Strong Skipping Mode on by default). - Jetpack Compose BOM current, Material 3,
androidx.lifecyclewithcollectAsStateWithLifecycle(). - Navigation 3 (
androidx.navigation3) when the project can adopt it; otherwise Navigation 2.8+. - Coroutines + Flow as the async primitives. Do not reach for RxJava or blocking I/O.
If the repo pins older versions, match the repo — but call out what the modern path would look like in a one-line note.
Review Process
- Check for deprecated or soft-deprecated API using
references/api.md. - Validate state and data flow using
references/state.md. - Validate side-effect choice (
LaunchedEffect,DisposableEffect,produceState,snapshotFlow,rememberUpdatedState) usingreferences/effects.md. - Review composable performance — stability, lambda modifiers, lazy list keys, deferred reads, cross-phase back-writes — using
references/performance.md. - Review modifier usage — ordering, lambda-form,
Modifier.Nodeovercomposed { }— usingreferences/modifiers.md. - Review navigation using
references/navigation.md— start from its decision table (Nav3 vs Nav2 type-safe vs plain state) before touching call sites. - Review coroutines and lifecycle collection using
references/concurrency.md. - Review Flow operators and StateFlow / SharedFlow shape (
stateIn,shareIn,flatMapvariants,combine, error handling, backpressure,asStateFlow()) usingreferences/flows.md. - Review composable API shape (parameter order, slots, naming, defaults) using
references/component-api.md. - Review UI testing patterns using
references/testing.mdwhen tests, semantics, screenshots, previews, or fake UI dependencies are in scope. - Review focus and keyboard / D-pad navigation using
references/focus.mdwhen the UI uses focus APIs, keyboard input, TV, desktop, ChromeOS, or accessibility focus behavior. - Review Compose Multiplatform / KMP boundaries using
references/kmp.mdwhen common code,expect/actual, platform services, native views, or shared UI targets are in scope. - Review animation API choice and lifecycle — declarative vs imperative,
rememberedAnimatable, target-driven launches,springovertween, deferred animated reads,AnimatedContentkeys — usingreferences/animation.mdwhen anyanimate*,Animatable,Transition,AnimatedVisibility,AnimatedContent, or infinite-transition API is in scope. - Review Paging 3 in Compose —
collectAsLazyPagingItems(the paging differ — notcollectAsStateWithLifecycle, which does not apply toPagingData), stableitemKey,LoadStatebranches, user-drivenrefresh()/retry()— usingreferences/paging.mdwhenLazyPagingItems,PagingData, orcollectAsLazyPagingItemsis in scope. - Final Kotlin style pass using
references/kotlin.md.
If doing a partial review, load only the relevant reference files — each references file is designed to be read in isolation.
Core Instructions
- Keep composables side-effect free in composition. All I/O, state mutation outside remembered objects, analytics, etc. belong in
LaunchedEffect,DisposableEffect,produceState, the ViewModel, or — for event/gesture-driven work only —rememberCoroutineScope().launchinside a handler. Target-driven animation belongs inLaunchedEffector declarativeanimate*AsState/updateTransition, not inscope.launchfrom the composition body. Seereferences/animation.mdandreferences/effects.md. - Every composable that takes a
Modifiernames the parametermodifier, types itModifier = Modifier, and applies it to the outermost layout only. Never create amodifierparameter you do not forward. - Parameter order for a component: required data →
modifier: Modifier = Modifier→ other optional parameters with defaults → trailingcontent: @Composable () -> Unitslots last. Onemodifierparameter per component. - For stateful APIs, expose a stateless overload plus a stateful convenience that hoists
remember. Seereferences/component-api.md. - Collect Flows with
collectAsStateWithLifecycle()in UI code. PlaincollectAsState()keeps collecting when the screen is not visible and burns battery and bandwidth. Exception:Flow<PagingData<T>>is collected withcollectAsLazyPagingItems(), nevercollectAsStateWithLifecycle()— seereferences/paging.md. - Prefer
rememberSaveableoverrememberfor UI state that should survive configuration change or process death, unless the value is unserializable or derivable. - Use the typed state factories (
mutableIntStateOf,mutableLongStateOf,mutableFloatStateOf,mutableDoubleStateOf) for primitive state. RawmutableStateOf<Int>(...)boxes. - Never write state a phase has already read. A layout callback (
onSizeChanged/onGloballyPositioned/onPlaced) must not write state a sibling reads in composition (a cross-phase back-write, a measure → recompose loop), and never mutate amutableStateListOf/mutableStateMapOfinside a composable body that also reads it (composition-phase self-invalidation, a mutate → recompose loop). Consume measured values in layout/draw, or mutate snapshot state from an event /LaunchedEffect/ state holder. Seereferences/performance.md. - Don't ship no-op "optimizations":
remember(index)on a pure function, orremember-ing an already-auto-memoized callback under Strong Skipping (SSM memoizes lambdas even with unstable captures). Prove a recomposition win with Layout Inspector counts or compiler reports, not the presence of a pattern. Seereferences/performance.md. - Never put a lambda in a
CompositionLocal. Use explicit parameters. - Do not introduce third-party libraries without asking first. The Accompanist libraries covering pager, swipe-refresh, flow layout, and system UI controller are deprecated — the functionality is in AndroidX now (
HorizontalPager,PullToRefreshBox,FlowRow/FlowColumn,enableEdgeToEdge()). - When an element's background reads from
MaterialTheme.colorScheme.*(directly or via a blend), its text and icon colors must read from the same theming source. Hard-codedColor.Black/Color.White/ raw ARGB literals over theme-driven backgrounds are dark-mode regressions. Seereferences/component-api.md. - Animate declaratively first. Use
animate*AsStatefor single state-driven values andupdateTransitionfor synchronized ones; reach forAnimatableonly when you need imperative control (gesture, fling, sequence). AlwaysrememberanAnimatable, launch target-driven animations fromLaunchedEffect(neverscope.launchin composition to react to state), preferspring()overtweenfor interruptible motion, and read animated values in the layout/draw phase (lambda modifiers /graphicsLayer) so the animation does not recompose every frame. Seereferences/animation.md. - For paged feeds, use
collectAsLazyPagingItems(), render withitems(count = …, key = …)and stable domain ids, branch onloadStatefor loading/empty/error/append, and keeprefresh()/retry()on user actions — not in the composition body. Seereferences/paging.md.
Output Format (review mode)
Organize findings by file. For each issue:
- State the file and relevant line(s).
- Name the rule being violated (e.g., "Use
collectAsStateWithLifecycle()instead ofcollectAsState()"). - Show a brief before/after code fix.
- Link the official source (
developer.android.com/...or AndroidX component guidelines).
Skip files with no issues. End with a prioritized summary — three items max, highest impact first.
Example Output
feature/profile/ProfileScreen.kt
Line 34: Use `collectAsStateWithLifecycle()` — UI Flows must stop collecting when the screen is not STARTED.
<https://developer.android.com/topic/architecture/ui-layer/state-production#continuous-vs-discrete>
Line 58: Pass `modifier` to the outermost layout, not to inner content.
<https://developer.android.com/develop/ui/compose/api-guidelines#naming-modifiers>
Line 72: Defer the animated `offset` read to the layout phase using the lambda form.
<https://developer.android.com/develop/ui/compose/performance/bestpractices#defer-reads-as-long-as-possible>
Summary
- Performance (high): Non-deferred animated reads on
ProfileScreen.kt:72,HomeScreen.kt:110,DetailScreen.kt:88recompose every frame. Switch to lambda-form modifiers. - Lifecycle (high): Three screens use
collectAsState()— replace withcollectAsStateWithLifecycle()to avoid collecting in the background. - API shape (medium):
UserCardswallows itsmodifierparameter. Forward it to the outermost layout.
End of example.
Authoring Mode
When the agent is writing new code rather than reviewing, the same rules apply as guardrails. Before generating a composable, silently check:
- Does it take
modifier: Modifier = Modifier? - Is state hoisted, or is there a clear reason to own it here?
- If it renders a list, does it use a stable
key =? - If it launches work, is that work in a
LaunchedEffect,produceState, or the ViewModel — not in the composition body? - If it collects a Flow, is it
collectAsStateWithLifecycle()? (AFlow<PagingData<T>>is the exception — it usescollectAsLazyPagingItems().) - Is the parameter order: data → modifier → other → content slot last?
- If it animates, is the API declarative first, remembered where needed, lifecycle-aware, and phase-correct?
- Does any layout callback or snapshot-collection mutation write state read back in composition (a cross-phase / self-invalidation loop)?
- If it pages, are keys stable,
LoadStatehandled, and refresh/retry user-driven? - If it needs focus, testing, or platform-specific behavior, did you load the focused reference before judging?
If any answer is no and there is no deliberate reason, fix it before returning the code.
What This Skill Does Not Cover
Out of scope in v1 — delegate elsewhere or scope down explicitly:
- Material 3 compliance, theming, and design tokens — use the
material-3skill. - Scoring an existing codebase with numeric grades — use the sibling
jetpack-compose-auditskill in the same repo. - Wear OS / TV / Auto / Glance deep platform review — this skill now covers focus and keyboard/D-pad basics, but not full platform certification.
- Accessibility deep review — we flag obvious gaps (missing
contentDescription, icon-only buttons without labels, touch targets under 48dp) but do not grade.
If the user needs any of the above, narrow the scope and say so.
References
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 100 of 100Pattern checks on the skill's files.
- Model reviewNot runA model review is scheduled for the next rescan.
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingskills/compose-agent/SKILL.md
Popularity
- 7-day trend score
- 0
Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/hamen/compose_skill/compose-agent)