Compose -- RIPDPI

SkillDev tools

Jetpack 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.

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.md for recipes
3. Consult the right reference

Read the relevant reference file(s) from references/ before answering:

TopicReference File
@State, remember, mutableStateOf, derivedStateOf, snapshotFlowreferences/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/testingreferences/state-holder-vs-viewmodel.md
StateFlow / SharedFlow / Channel modeling, update { }, stateIn placementreferences/state-event-flow.md
Deferred state reads (provider lambdas, block-form modifiers) for scroll/animation perfreferences/deferred-reads.md
Structuring composables, slots, extraction, previewreferences/view-composition.md
Slot API design for reusable components (xxxContent: @Composable () -> Unit)references/slot-api.md
Modifier ordering, custom modifiers, Modifier.Nodereferences/modifiers.md
LaunchedEffect, DisposableEffect, SideEffect, rememberCoroutineScopereferences/side-effects.md
CompositionLocal, LocalContext, LocalDensity, custom localsreferences/composition-locals.md
LazyColumn, LazyRow, LazyGrid, Pager, keys, content typesreferences/lists-scrolling.md
NavHost, type-safe routes, deep links, shared element transitionsreferences/navigation.md
animate*AsState, AnimatedVisibility, Crossfade, transitionsreferences/animation.md
MaterialTheme, ColorScheme, dynamic color, Typography, shapesreferences/theming-material3.md
Recomposition skipping, stability, baseline profiles, benchmarkingreferences/performance.md
Semantics, content descriptions, traversal order, testingreferences/accessibility.md
Removed/replaced APIs, migration paths from older Compose versionsreferences/deprecated-patterns.md
Styles API (experimental): Style {}, MutableStyleState, Modifier.styleable()references/styles-experimental.md
Figma/screenshot decomposition, design tokens, spacing, modifier orderingreferences/design-to-compose.md
Production crash patterns, defensive coding, state/performance rulesreferences/production-crash-playbook.md
Compose Multiplatform, expect/actual, resources (Res.*), migrationreferences/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

  1. Compose thinks in three phases: Composition → Layout → Drawing. State reads in each phase only trigger work for that phase and later ones.

  2. Recomposition is frequent and cheap — but only if you help the compiler skip unchanged scopes. Use stable types, avoid allocations in composable bodies.

  3. Modifier order matters. Modifier.padding(16.dp).background(Color.Red) is visually different from Modifier.background(Color.Red).padding(16.dp).

  4. 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.

  5. 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.

  6. Compose Multiplatform shares the runtime but not the platform. UI code in commonMain is portable. Platform-specific APIs (LocalContext, BackHandler, Window) require expect/actual or 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:

  1. Start with guidance — read the topic-specific reference (e.g., references/state-management.md)
  2. Go deeper with source — if the user wants receipts or you need to verify, follow references/source-code/index.md to 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 a References: line per finding.
  • Reserve 0-3 scores for repeated or systemic problems, not isolated mistakes.
  • Do not award 9-10 unless the repo is consistently strong across the category.

Step 0: RIPDPI Project Orientation

Before starting the audit:

  1. Read .agents/skills/compose-performance/SKILL.md to absorb the known quick-wins list, existing TrackRecomposition instrumentation, and annotation conventions. Issues already tracked there should appear in "Known Open Items", not as new findings, unless they remain unfixed.

  2. Compiler reports: use ./gradlew :app:compileGithubFullDebugKotlin -Pripdpi.composeReports=true (NOT the init.gradle script). This non-signing compile task writes app/build/compose-reports/ and app/build/compose-metrics/ through ripdpi.android.compose.gradle.kts.

  3. Module scope: :app is the only Compose module. Do not search :core:data, :core:diagnostics, :core:engine, :core:service, or :core:detection for @Composable definitions.

  4. Design system: RipDpiThemeTokens is the project's custom wrapper over MaterialTheme. RipDpiTheme calls MaterialTheme internally — this is correct, not a deviation.

  5. Existing stability setup: The project has app/compose-stability.conf marking external types stable, and @Immutable/@Stable on all UI model classes. Run compiler reports to get the actual skippable% 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

ScoreStatus
0-3fail
4-6needs work
7-8solid
9-10excellent

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 without rememberUpdatedState.
  • Do not deduct for RipDpiThemeTokens usage — 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 citations
  • references/search-playbook.md — search patterns and red-flag heuristics
  • references/report-template.md — required structure when a persistent report is requested
  • references/canonical-sources.md — the official URLs every deduction must cite
  • references/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