Compose -- RIPDPI
SkillDev toolsJetpack Compose guidance and audit for RIPDPI — state, recomposition, modifiers, navigation, theming, performance, and scored quality reports.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Compose -- RIPDPI skill
What this skill tells your AI
The instructions your AI receives, as published by po4yka/ripdpi in .agents/skills/compose/SKILL.md and read by ahel’s review.
Two modes in one skill:
- Expert Guidance (default) — practical, evidence-backed answers for Compose questions
- Audit — scored quality report across performance, state, side effects, and API quality
Expert Guidance
Non-opinionated, practical guidance for writing correct, performant Compose code —
across Android, Desktop, iOS, and Web. Covers Jetpack Compose and Compose Multiplatform.
Backed by analysis of actual source code from androidx/androidx and
JetBrains/compose-multiplatform-core.
Workflow
When helping with Compose code, follow this checklist:
1. Understand the request
- What Compose layer is involved? (Runtime, UI, Foundation, Material3, Navigation)
- Is this a state problem, layout problem, performance problem, or architecture question?
- Is this Android-only or Compose Multiplatform (CMP)?
2. Analyze the design (if visual reference provided)
- If the user shares a Figma frame, screenshot, or design spec, consult
references/design-to-compose.md - Decompose the design into a composable tree using the 5-step methodology
- Map design tokens to MaterialTheme, spacing to CompositionLocals
- Identify animation needs and consult
references/animation.mdfor recipes
3. Consult the right reference
Read the relevant reference file(s) from references/ before answering:
| Topic | Reference File |
|---|---|
@State, remember, mutableStateOf, derivedStateOf, snapshotFlow | references/state-management.md |
| State hoisting decisions (local / hoisted / plain-holder / ViewModel) | references/state-hoisting.md |
| Screen state-holder vs plain UI composable split for previewability/testing | references/state-holder-vs-viewmodel.md |
StateFlow / SharedFlow / Channel modeling, update { }, stateIn placement | references/state-event-flow.md |
| Deferred state reads (provider lambdas, block-form modifiers) for scroll/animation perf | references/deferred-reads.md |
| Structuring composables, slots, extraction, preview | references/view-composition.md |
Slot API design for reusable components (xxxContent: @Composable () -> Unit) | references/slot-api.md |
Modifier ordering, custom modifiers, Modifier.Node | references/modifiers.md |
LaunchedEffect, DisposableEffect, SideEffect, rememberCoroutineScope | references/side-effects.md |
CompositionLocal, LocalContext, LocalDensity, custom locals | references/composition-locals.md |
LazyColumn, LazyRow, LazyGrid, Pager, keys, content types | references/lists-scrolling.md |
NavHost, type-safe routes, deep links, shared element transitions | references/navigation.md |
animate*AsState, AnimatedVisibility, Crossfade, transitions | references/animation.md |
MaterialTheme, ColorScheme, dynamic color, Typography, shapes | references/theming-material3.md |
| Recomposition skipping, stability, baseline profiles, benchmarking | references/performance.md |
| Semantics, content descriptions, traversal order, testing | references/accessibility.md |
| Removed/replaced APIs, migration paths from older Compose versions | references/deprecated-patterns.md |
Styles API (experimental): Style {}, MutableStyleState, Modifier.styleable() | references/styles-experimental.md |
| Figma/screenshot decomposition, design tokens, spacing, modifier ordering | references/design-to-compose.md |
| Production crash patterns, defensive coding, state/performance rules | references/production-crash-playbook.md |
Compose Multiplatform, expect/actual, resources (Res.*), migration | references/multiplatform.md |
| Desktop (Window, Tray, MenuBar), iOS (UIKitView), Web (ComposeViewport) | references/platform-specifics.md |
4. Apply and verify
- Write code that follows the patterns in the reference
- Flag any anti-patterns you see in the user's existing code
- Suggest the minimal correct solution — don't over-engineer
5. Cite the source
When referencing Compose internals, point to the exact source file:
// See: compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Composer.kt
Key Principles
-
Compose thinks in three phases: Composition → Layout → Drawing. State reads in each phase only trigger work for that phase and later ones.
-
Recomposition is frequent and cheap — but only if you help the compiler skip unchanged scopes. Use stable types, avoid allocations in composable bodies.
-
Modifier order matters.
Modifier.padding(16.dp).background(Color.Red)is visually different fromModifier.background(Color.Red).padding(16.dp). -
State should live as low as possible and be hoisted only as high as needed. Don't put everything in a ViewModel just because you can.
-
Side effects exist to bridge Compose's declarative world with imperative APIs. Use the right one for the job — misusing them causes bugs that are hard to trace.
-
Compose Multiplatform shares the runtime but not the platform. UI code in
commonMainis portable. Platform-specific APIs (LocalContext,BackHandler,Window) requireexpect/actualor conditional source sets.
Source Code Receipts
When you need to verify how something works internally, read references/source-code/index.md. It maps each Compose runtime/UI/Foundation/Material3/Navigation/CMP source file to its upstream URL on androidx/androidx@androidx-main or JetBrains/compose-multiplatform-core@jb-main. Fetch the file directly with WebFetch or gh api.
Two-layer approach:
- Start with guidance — read the topic-specific reference (e.g.,
references/state-management.md) - Go deeper with source — if the user wants receipts or you need to verify, follow
references/source-code/index.mdto the upstream file
Audit Mode
Invoke when the user asks to audit the Jetpack Compose codebase, review Compose architecture or quality, rate the codebase with scores, or establish a pre-release quality baseline.
Rubric version: v1. Read the active Kotlin and Compose BOM versions from gradle/libs.versions.toml; never reuse versions embedded in an older audit. Determine Strong Skipping behavior from that active Kotlin version and the project compiler configuration.
Four scored categories: Performance, State Management, Side Effects, Composable API Quality.
Out of scope in v1: Material 3 compliance (defer to material-3 skill), accessibility scoring, UI test coverage, CMP-specific rules, Wear OS / TV / Auto / Glance, build performance.
Expected Output
Always return a short chat summary with the overall score, category scores, worst issues, and top fixes. Write a repository report only when the user explicitly requests a persistent artifact; use the path they name, or default to the ignored build/reports/compose/compose-audit-<YYYY-MM-DD>.md.
Audit Principles
- Be strict, but evidence-based. Do not score from search hits alone. Read representative files before judging a category.
- Cite concrete file paths in the report for every important deduction.
- Cite an official documentation URL for every deduction. The rubric maps every rule to a canonical source in
references/canonical-sources.md. The report template requires aReferences:line per finding. - Reserve
0-3scores for repeated or systemic problems, not isolated mistakes. - Do not award
9-10unless the repo is consistently strong across the category.
Step 0: RIPDPI Project Orientation
Before starting the audit:
-
Read
.agents/skills/compose-performance/SKILL.mdto absorb the known quick-wins list, existingTrackRecompositioninstrumentation, and annotation conventions. Issues already tracked there should appear in "Known Open Items", not as new findings, unless they remain unfixed. -
Compiler reports: use
./gradlew :app:compileGithubFullDebugKotlin -Pripdpi.composeReports=true(NOT the init.gradle script). This non-signing compile task writesapp/build/compose-reports/andapp/build/compose-metrics/throughripdpi.android.compose.gradle.kts. -
Module scope:
:appis the only Compose module. Do not search:core:data,:core:diagnostics,:core:engine,:core:service, or:core:detectionfor@Composabledefinitions. -
Design system:
RipDpiThemeTokensis the project's custom wrapper overMaterialTheme.RipDpiThemecallsMaterialThemeinternally — this is correct, not a deviation. -
Existing stability setup: The project has
app/compose-stability.confmarking external types stable, and@Immutable/@Stableon all UI model classes. Run compiler reports to get the actualskippable%before applying measured ceilings.
Step 1: Confirm Scope
- If the user passed an explicit path or module, use it.
- If no path was passed, default to
:app(app/src/main/kotlin/com/poyka/ripdpi/). - If the user requests a specific category, audit only that category.
Fast-fail check: grep for androidx.compose in build.gradle* or libs.versions.toml, and for setContent { or @Composable under src/.
Step 2: Map The Repository
Identify: Gradle modules, Compose source roots, shared UI/component packages, theme/design-system packages, screen packages, state holder/ViewModel areas, test and preview locations, baseline-profile modules.
Step 3: Build A Compose Surface Map
Look for: @Composable functions, reusable UI components, screens and routes, ViewModel usage, remember/rememberSaveable/mutableStateOf, collectAsStateWithLifecycle, LaunchedEffect/DisposableEffect/SideEffect, LazyColumn/LazyRow/items.
If subagents are available, parallelize category scans and merge findings.
Step 4: Generate Compose Compiler Reports
Primary path:
REPO_ROOT=$(git rev-parse --show-toplevel)
cd "$REPO_ROOT" && ./gradlew :app:compileGithubFullDebugKotlin -Pripdpi.composeReports=true --no-daemon
Use a 600-second timeout.
Collect the reports:
find app/build/compose-reports/ app/build/compose-metrics/ \
\( -name '*-classes.txt' -o -name '*-composables.txt' -o -name '*-composables.csv' -o -name '*-module.json' \)
Extract: unstable classes, non-skippable named composables, module-wide skippability counts. Compute named-only skippability from *-composables.csv (filter isLambda == "0").
Fallback if convention plugin fails:
./gradlew :app:compileGithubFullDebugKotlin \
--init-script .agents/skills/compose/scripts/compose-reports.init.gradle \
--no-daemon --quiet
Output goes to app/build/compose_audit/.
If both fail: proceed with source-inferred findings, set Compiler diagnostics used: no in the report, reduce confidence by one level, and label all stability claims as inferred.
Step 5: Audit The Four Categories
Use the rubric in references/scoring.md and heuristics in references/search-playbook.md.
Performance: expensive work in composition, avoidable recomposition, lazy list keys, bad state-read timing, unstable or overly broad reads, backwards writes.
State Management: hoisting correctness, single source of truth, reusable stateless seams, correct remember vs rememberSaveable, lifecycle-aware observable collection.
Side Effects: side effects incorrectly done in composition, correct effect API choice, effect keys, stale lambda capture, cleanup correctness, lifecycle-aware effect behavior.
Composable API Quality (focus on ui/components/, not every leaf screen): modifier presence and placement, parameter order, explicit over implicit configuration, meaningful defaults, avoiding MutableState<T> parameters in reusable APIs.
Step 6: Verify Findings
Before deducting points: read the file where the smell appears; confirm it's not a false positive; check for compensating patterns elsewhere; distinguish one-off mistakes from systemic patterns; for stability findings, cite the compiler report line as evidence.
Step 7: Score
| Score | Status |
|---|---|
| 0-3 | fail |
| 4-6 | needs work |
| 7-8 | solid |
| 9-10 | excellent |
Use weights in references/scoring.md to compute the overall score.
Measured ceilings are mandatory. When compiler reports are available, apply the Performance ceiling from references/scoring.md and show the math:
Performance ceiling check:
skippable% = 186/273 = 68.1% -> falls in 50-70% band -> cap at 4
qualitative score: 7
applied score: 4 (ceiling lowered from 7)
Step 8: Write The Report
Use references/report-template.md. The report must include: overall score, category score table, top critical findings, category-by-category reasoning, evidence file paths, prioritized remediation list, Known Open Items cross-referencing the quick-wins checklist from .agents/skills/compose-performance/SKILL.md, and an optional note to run material-3 if design issues are suspected.
Only write the report when the user requested persistence. Use their explicit destination, or create build/reports/compose/compose-audit-<YYYY-MM-DD>.md; do not add a root-level report by default.
Step 9: Return A Short Summary
Include: overall score (and delta vs. prior reports), one-line judgment per category with applied ceiling, compiler-report highlights (Strong Skipping on/off, skippable%, unstable shared types), top three actionable fixes (concrete change, file path + line numbers, official doc URL, expected impact), and whether a material-3 audit is worth running next.
When a persistent report was requested, the top-three fixes in chat MUST be the same items as the report's Prioritized Fixes list.
What To Avoid
- Do not produce a generic checklist with no repository evidence.
- Do not inflate the performance score just because the app uses Compose.
- Do not flag
LaunchedEffect(Unit)on its own — the "run once" pattern is idiomatic. Only flag it when the body captures a value that may change withoutrememberUpdatedState. - Do not deduct for
RipDpiThemeTokensusage — it is the correct design system access pattern. - Do not double-count the same root cause across categories. Pick the dominant category and cross-reference.
- Do not score design in v1.
References
references/scoring.md— per-rule rubric with inline citationsreferences/search-playbook.md— search patterns and red-flag heuristicsreferences/report-template.md— required structure when a persistent report is requestedreferences/canonical-sources.md— the official URLs every deduction must citereferences/diagnostics.md— Gradle/code snippets for compiler reports, stability config, baseline profiles, R8 checks.agents/skills/compose/scripts/compose-reports.init.gradle— Gradle init script fallback
Signals
- GitHub stars
- 69
- Forks
- 4
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
compose-po4yka- Source
- github.com/po4yka/ripdpi