Skip to content
All Skills

Using Stability Analyzer Ide Plugin

Use this skill to install and operate the `skydoves/compose-stability-analyzer` IntelliJ / Android Studio plugin so the developer sees Compose stability feedback live in the editor instead of waiting for a Gradle build. Covers installing the plugin from disk, configuring the `Settings → Tools → Compose Stability Analyzer` panel, reading the four gutter colors (green stable, red unstable, yellow runtime, gray no-params), the per-parameter hover documentation, the inline parameter hint badges, and the `UnstableComposable` weak-warning inspection with its `@Suppress("NonSkippableComposable")` and `@Suppress("ParamsComparedByRef")` quick fixes. Use when the user mentions gutter icons, inline hints, the stability inspection, the IDEA plugin, real-time stability feedback while editing, or asks why a composable is flagged as non-skippable in the editor.

Software Engineering|v1|Updated 7/14/2026|GitHub source
MCP get_skill({ skillId: "using-stability-analyzer-ide-plugin-fabf3b7f" })

Use this skill with your agent

Create a free account and connect via MCP

Get Started Free
# Using the Stability Analyzer IDE Plugin — live in-editor stability feedback

The Compose Compiler reports tell the developer about stability after a build completes. The `skydoves/compose-stability-analyzer` IntelliJ plugin tells them while they edit. Gutter icons mark every `@Composable` with a color, hover docs render the per-parameter table with reasons, inline hints render colored badges next to each parameter type, and the `UnstableComposable` weak-warning inspection surfaces actionable problems with quick fixes.

The plugin uses the Kotlin K2 Analysis API to evaluate the same stability rules that drive `../understanding-stability-inference/SKILL.md`, so editor feedback agrees with what `../diagnosing-compose-stability/SKILL.md` would later show in the compiler reports. This shortens the loop from "ship → build → read reports" to "type → see the gutter".

## When to use this skill

- The developer wants real-time stability feedback while editing a Composable file.
- A reviewer is reading a PR locally and wants the inline signal next to each composable.
- A new joiner wants to see at a glance which composables in the file are non-skippable.
- The user asks why the editor flagged a function with a weak warning called `UnstableComposable`.
- The user mentions gutter icons, inline hints, the stability inspection, the IDEA plugin, the K2 Analysis API for Compose, or the `Compose Stability Analyzer` tool window.

## When NOT to use this skill

- CI gating that fails the build on stability regressions. Use `../enforcing-stability-in-ci/SKILL.md`.
- Build-time Compose Compiler reports analysis. Use `../diagnosing-compose-stability/SKILL.md`.
- Active runtime tracing or visual cascade investigation through the plugin's tool window. Use `../visualizing-recomposition-cascades/SKILL.md`.
- Conceptual questions about how the compiler classifies a type. Use `../understanding-stability-inference/SKILL.md`.

## Prerequisites

- Android Studio 2024.2+ or IntelliJ IDEA 2024.2+ (build range 242 through 261, covering 2024.2 through the 2026.1 EAP).
- Kotlin 2.3.0 in the IDE plugin runtime, required by the K2 Analysis API the plugin relies on.
- The Compose Compiler Gradle plugin already wired in the project (`org.jetbrains.kotlin.plugin.compose`). The analyzer evaluates stability against the same compiler model.
- The plugin is currently installed from disk during development; the JetBrains Marketplace listing is pending.

## Workflow

### 1. Build the plugin from source

Clone `skydoves/compose-stability-analyzer` and build the IDEA module.

```bash
git clone https://github.com/skydoves/compose-stability-analyzer
cd compose-stability-analyzer
./gradlew :compose-stability-analyzer-idea:buildPlugin
```

The packaged plugin lands at `compose-stability-analyzer-idea/build/distributions/*.zip`.

### 2. Install from disk

In the IDE, open **Settings → Plugins → ⚙ → Install Plugin from Disk…** and pick the ZIP produced in step 1. Restart the IDE when prompted. **DO NOT** look for the plugin in the JetBrains Marketplace yet; the listing is under review at the time of writing.

### 3. Confirm the settings panel

Open **Settings → Tools → Compose Stability Analyzer**. Verify `isStabilityCheckEnabled` is on. The full set of toggles, all read from `StabilitySettingsState`, is:

| Key | Default | Effect |
|---|---|---|
| `isStabilityCheckEnabled` | `true` | Master switch for all editor features. |
| `isStrongSkippingEnabled` | `true` | Match Compose Compiler 2.0.20+ runtime: classify with strong skipping on. |
| `showGutterIcons` | `true` | Render the colored icon in the gutter beside each `@Composable`. |
| `showGutterIconsOnlyForUnskippable` | `false` | Hide green/gray icons; only show problems. Use on dense files. |
| `showGutterIconsInTests` | `false` | Render gutter icons inside test source roots too. |
| `showWarnings` | `true` | Enable the `UnstableComposable` inspection. |
| `showInlineHints` | `true` | Render colored parameter-type badges inline. |
| `showOnlyUnstableHints` | `false` | Suppress inline badges for stable parameters. |
| `stableGutterColorRGB` | `#5FB865` (95, 184, 101) | Gutter / hint color for stable composables. |
| `unstableGutterColorRGB` | `#E8684A` (232, 104, 74) | Gutter / hint color for unstable composables. |
| `runtimeGutterColorRGB` | `#F0C674` (240, 198, 116) | Gutter / hint color for runtime-stability composables. |
| `stableHintColorRGB` / `unstableHintColorRGB` / `runtimeHintColorRGB` | per defaults above | Inline hint color overrides. |
| `ignoredTypePatterns` | `""` | Newline- or comma-separated glob list of types to treat as stable. |
| `stabilityConfigurationPath` | `""` | Optional path to the same `stability_config.conf` the compiler reads. |
| `isHeatmapEnabled` | `true` | Allow the live recomposition heatmap (see `../visualizing-recomposition-cascades/SKILL.md`). |

Point `stabilityConfigurationPath` at the project's `stability_config.conf` so the in-editor classification matches the compiler's classification.

### 4. Read the gutter colors

Open any Kotlin file containing `@Composable` functions. Confirm a colored icon appears beside each. The four colors and their meanings:

| Color | Hex | Meaning |
|---|---|---|
| Green | `#5FB865` | Skippable; every parameter stable. |
| Red | `#E8684A` | At least one unstable parameter; not skippable. |
| Yellow | `#F0C674` | At least one runtime-stability parameter (resolved across separate compilation units). |
| Gray | `#808080` | No parameters (still restartable but trivially skippable). |

A gray gutter is fine; the function has nothing to compare. A green gutter means the analyzer believes Compose will skip recomposition when arguments are equal. A red or yellow gutter is a diagnostic: the function will recompose more than necessary when the parent recomposes.

### 5. Hover for the parameter table

Hover any composable name. The popup, served by `StabilityDocumentationProvider`, shows the skippability badge, a per-parameter table with the stability classification per parameter, and the suggested fix when the analyzer can name one (e.g. "wrap `List<Item>` in `ImmutableList`"). Use this for triage before opening the full compiler reports.

### 6. Tune inline hints for dense files

`StabilityInlayHintsProvider` renders a colored badge next to each parameter type in the function signature. On a screen with many composables this can become noisy. In **Settings → Tools → Compose Stability Analyzer** enable `showOnlyUnstableHints` so badges disappear for stable parameters and only the actionable ones remain. For an even quieter file, enable `showGutterIconsOnlyForUnskippable` so the gutter only shows red/yellow.

### 7. Read the `UnstableComposable` inspection

`StabilityInspection` (short name `UnstableComposable`, group `Compose`, severity weak warning) flags non-skippable composables with at least one unstable parameter. It runs on the fly and on **Code → Inspect Code…**. The inspection surfaces in two ways:

- A weak-warning underline in the editor.
- A finding in the **Inspection Results** tool window grouped under `Compose / Unstable Composable`.

It is intentionally a weak warning: skippability is a diagnostic, not a build-blocking error. It will not turn the file red, will not block a commit, and will not fail CI on its own. Treat it as a backlog signal.

### 8. Apply quick fixes only when justified

The inspection ships two suppression intentions, surfaced via Alt+Enter on the underlined composable:

- `@Suppress("NonSkippableComposable")` — applied by `AddSuppressAnnotationFix` / `AddSuppressIntentionAction`. Silences the inspection on a function the developer has actively decided is acceptable (e.g. a debug overlay never on a hot path).
- `@Suppress("ParamsComparedByRef")` — same fix path, narrower scope: silences the warning when the parameter is intentionally compared by reference.

Apply suppressions on the specific function only. **DO NOT** push them to file scope.

### 9. Annotate hot paths with `@TraceRecomposition`

`AddTraceRecompositionIntention` is available via Alt+Enter on any `@Composable`. It inserts the `@TraceRecomposition` annotation, which is the runtime instrumentation entry point used by the live heatmap and by `../../measurement/tracing-recompositions-at-runtime/SKILL.md`. Use it on suspected hot composables once the gutter has identified them.

## Patterns

### Pattern: red gutter inside a hot path is actionable, even when the build is green

```text
// WRONG
PriceTicker has a red gutter icon.
Build is green, the team ships, jank reports come in two days later.
```

```text
// WRONG because: the inspection is a weak warning by design and does not block the build.
// The gutter is the only signal until the developer opens the compiler reports.
// Treat red gutters on hot-path composables as actionable; confirm with
// `../diagnosing-compose-stability/SKILL.md`, then fix via `../stabilizing-compose-types/SKILL.md`.
```

```text
// RIGHT
PriceTicker has a red gutter icon.
Hover -> "price: Price unstable (var price)".
Open the compiler reports for confirmation.
Stabilize `Price` (val + immutable fields) per `../stabilizing-compose-types/SKILL.md`.
Gutter turns green; confirm with the live heatmap per `../visualizing-recomposition-cascades/SKILL.md`.
```

### Pattern: suppress on the function, never on the file

```kotlin
// WRONG
@file:Suppress("UnstableComposable")

package com.example.feature.cart
```

```text
// WRONG because: file-level suppression hides every future regression in that file.
// New unstable composables added to the file will never surface in the inspection.
```

```kotlin
// RIGHT — narrow, justified suppression on a single function
@Suppress("NonSkippableComposable")
@Composable
fun DebugOverlay(state: MutableState<DebugInfo>) {
    // dev-only overlay; never on hot path; intentional MutableState parameter.
}
```

### Pattern: do not chase 100% green gutters

```text
// WRONG
"All composables in :feature-search must show green gutters before merge."
```

```text
// WRONG because: skippability is a diagnostic, not a KPI. Some composables legitimately
// take unstable parameters (interop with Java POJOs, third-party data classes the team
// does not own). The goal is "no regression in hot-path composables", not "all green".
// Use `../enforcing-stability-in-ci/SKILL.md` to gate against regressions, not absolutes.
```

```text
// RIGHT
Hot-path composables (list rows, scroll items, animation tickers) are green or yellow.
Cold-path composables (settings screens, debug tools) may be red and that is acceptable.
```

### Pattern: silence noise via settings, not via inspection-disable

```text
// WRONG
Settings -> Editor -> Inspections -> Compose -> Unstable Composable -> off
```

```text
// WRONG because: turning the inspection off globally silences real regressions
// across the whole codebase. The next unstable parameter slipping into a hot
// composable will not surface anywhere in the editor.
```

```text
// RIGHT
Settings -> Tools -> Compose Stability Analyzer:
  showGutterIconsOnlyForUnskippable = true
  showOnlyUnstableHints = true
The inspection stays on; only the visual noise is reduced.
```

### Pattern: align the in-editor classifier with the compiler

```kotlin
// RIGHT — in Settings -> Tools -> Compose Stability Analyzer
isStrongSkippingEnabled = true
stabilityConfigurationPath = "<repo-root>/stability_config.conf"
```

The compiler runs with strong skipping on by default in Kotlin 2.0.20+ and consults the same `stability_config.conf` (see `../stabilizing-compose-types/SKILL.md`). Matching both settings means the gutter color the developer sees agrees with what the compiler emits in `../diagnosing-compose-stability/SKILL.md`.

## Mandatory rules

- **MUST** treat a red or yellow gutter on any composable inside a hot path as actionable. Confirm with the compiler reports per `../diagnosing-compose-stability/SKILL.md`, then fix via `../stabilizing-compose-types/SKILL.md`.
- **MUST** point `stabilityConfigurationPath` at the same `stability_config.conf` the Compose compiler reads, so the editor and the compiler agree on classifications.
- **MUST NOT** apply file-level `@file:Suppress("UnstableComposable")`. Suppress on the specific function with `@Suppress("NonSkippableComposable")` or `@Suppress("ParamsComparedByRef")`, and document why in a comment.
- **MUST NOT** disable the inspection globally to silence noise. Tune `showGutterIconsOnlyForUnskippable = true` and `showOnlyUnstableHints = true` in **Settings → Tools → Compose Stability Analyzer** first.
- **MUST NOT** chase 100% green gutters. Skippability is a diagnostic, not a KPI. Stability config is a contract, not a magic spell — marking a mutable type stable means the compiler trusts the developer; break the contract and recompositions silently go missing.
- **PREFERRED:** keep `isStrongSkippingEnabled = true` so the analyzer's classification matches the compiler's actual runtime behavior on Kotlin 2.0.20+.
- **PREFERRED:** apply `@TraceRecomposition` via the **Add @TraceRecomposition** intention on suspected hot composables, then follow `../../measurement/tracing-recompositions-at-runtime/SKILL.md` to wire the runtime side.
- **PREFERRED:** install from disk during development; the JetBrains Marketplace listing is pending and **MUST NOT** be assumed available yet.

## Verification

- [ ] Plugin installed from disk via **Settings → Plugins → ⚙ → Install Plugin from Disk…**; the IDE has been restarted.
- [ ] **Settings → Tools → Compose Stability Analyzer** is present and `isStabilityCheckEnabled` is on.
- [ ] Opening a Kotlin file with `@Composable` declarations shows a colored gutter icon beside every one of them.
- [ ] Hovering a composable name shows the parameter-stability table popup served by `StabilityDocumentationProvider`.
- [ ] Inline parameter-type hints render next to each parameter in the function signature; toggling `showOnlyUnstableHints` hides hints for stable parameters.
- [ ] The `UnstableComposable` inspection (group `Compose`, weak warning) flags at least one known-unstable composable when one exists in the open file.
- [ ] Pressing Alt+Enter on a flagged composable offers `@Suppress("NonSkippableComposable")` and `@Suppress("ParamsComparedByRef")` quick fixes.
- [ ] Pressing Alt+Enter on any `@Composable` offers the **Add @TraceRecomposition** intention.
- [ ] `stabilityConfigurationPath` points at the same `stability_config.conf` used by the Compose Compiler in the project's Gradle config.

## References

- skydoves/compose-stability-analyzer — https://github.com/skydoves/compose-stability-analyzer
- The `compose-stability-analyzer-idea` module within that repo — https://github.com/skydoves/compose-stability-analyzer/tree/main/compose-stability-analyzer-idea
- skydoves, "Optimize App Performance by Mastering Stability" — https://medium.com/proandroiddev/optimize-app-performance-by-mastering-stability-in-jetpack-compose-69f40a8c785d
- Compose stability overview — https://developer.android.com/develop/ui/compose/performance/stability
- Strong Skipping — https://developer.android.com/develop/ui/compose/performance/stability/strongskipping
- IntelliJ Platform K2 Analysis API — https://plugins.jetbrains.com/docs/intellij/analysis-api.html

For CI-side gating that turns red gutters into a build failure, see `../enforcing-stability-in-ci/SKILL.md`. For the build-time Compose Compiler reports the gutter colors agree with, see `../diagnosing-compose-stability/SKILL.md`. For the upstream type fixes that turn red gutters green, see `../stabilizing-compose-types/SKILL.md`. For the active investigation tools (cascade visualizer, live heatmap) inside the same plugin, see `../visualizing-recomposition-cascades/SKILL.md`. For the runtime instrumentation that the **Add @TraceRecomposition** intention sets up, see `../../measurement/tracing-recompositions-at-runtime/SKILL.md`.
#android#jetpack-compose#performance#kotlin#code#qualityandroid-studiogradlejetpack-composegitcompose-stability-analyzer

Related Skills

More skills in Software Engineering

Accessibility Standards

Comprehensive web accessibility standards based on WCAG 2.2 AA, with 38+ anti-patterns, legal enforcement context (EAA, ADA Title II), WAI-ARIA patterns, and framework-specific fixes for modern web frameworks and libraries.

#github-copilot#accessibilityMIT

Accord

Authoring unified specification packages across Business/Development/Design teams via staged elaboration (L0 Vision → L1 Requirements → L2 Team Detail → L3 Acceptance Criteria). No code. Use when authoring cross-team specs, building L0-L3 packages, or aligning Biz/Dev/Design on a single source of truth.

#broad-capability#developmentMIT

Acquire Codebase Knowledge

Use this skill when the user explicitly asks to map, document, or onboard into an existing codebase. Trigger for prompts like "map this codebase", "document this architecture", "onboard me to this repo", or "create codebase docs". Do not trigger for routine feature implementation, bug fixes, or narrow code edits unless the user asks for repository-level discovery.

#github-copilot#documentationMIT

Acreadiness Assess

Run the AgentRC readiness assessment on the current repository and produce a static HTML dashboard at reports/index.html. Wraps `npx github:microsoft/agentrc readiness` and hands off rendering to the @ai-readiness-reporter custom agent. Supports policies (--policy) for org-specific scoring. Use when asked to assess, audit, or score the AI readiness of a repo.

#github-copilot#planningMIT

Acreadiness Generate Instructions

Generate tailored AI agent instruction files via AgentRC instructions command. Produces .github/copilot-instructions.md (default, recommended for Copilot in VS Code) plus optional per-area .instructions.md files with applyTo globs for monorepos. Use after running /acreadiness-assess to close gaps in the AI Tooling pillar.

#github-copilot#skillMIT

Acreadiness Policy

Help the user pick, write, or apply an AgentRC policy. Policies customise readiness scoring by disabling irrelevant checks, overriding impact/level, setting pass-rate thresholds, or chaining org baselines with team overrides. Use when the user asks about strict mode, AI-only scoring, custom weights, CI gating, or wants org-wide standardisation.

#github-copilot#planningMIT

Explore Other Categories

Skills from other categories with shared topics

Avoiding Subcomposition Pitfalls

Use this skill when a Compose tree uses SubcomposeLayout, BoxWithConstraints, or Scaffold and the developer reports extra measure passes, slow first frame, or layout passes running content composition repeatedly. Covers why SubcomposeLayout composes its slots during the measure phase, why BoxWithConstraints forces a subcomposition for every new Constraints value, why nesting Scaffold or BoxWithConstraints multiplies the cost, when a custom Layout or Modifier.layout { } replaces SubcomposeLayout, and how to use SubcomposeLayoutState's slot reuse policy and precompose APIs when SubcomposeLayout is genuinely required. Use when the developer mentions BoxWithConstraints, SubcomposeLayout, Scaffold, "extra measure pass", "double measurement", "first frame slow", "subcompose", or notices that wrapping content in BoxWithConstraints regresses scroll perf inside a LazyColumn.

Mobile App Development#android#jetpack-compose

Choosing Derivedstateof

Use this skill to decide when Jetpack Compose derivedStateOf is the right tool and when it is pure overhead. Covers the "input frequency must exceed output frequency" rule, the mandatory remember { derivedStateOf { } } wrapper, the canonical pitfall of capturing non-state variables by initial value (and the remember(key) fix), and the snapshotFlow alternative for fire-and-forget side effects on derived values. Use when the developer mentions derivedStateOf, scroll-position-driven booleans, threshold checks, firstVisibleItemIndex, "show FAB on scroll", recomposition counts that don't drop after wrapping a value, or asks whether a computed string concatenation should use derivedStateOf.

Mobile App Development#android#jetpack-compose

Collecting Flows Safely

Use this skill to migrate Compose UI from `collectAsState()` to `collectAsStateWithLifecycle()`, hoist `Flow<T>` parameters out of composables, and apply `.conflate()` / `.distinctUntilChanged()` / `snapshotFlow` so background CPU and battery stop draining and chatty flows stop invalidating the UI per emission. Covers ViewModel `StateFlow`/`SharedFlow` consumers, sensor and location streams, and the "Flow as composable parameter" antipattern. Trigger when the user mentions `collectAsState`, `collectAsStateWithLifecycle`, lifecycle-aware flow collection, `Lifecycle.State.STARTED`, background battery drain from a Compose screen, `snapshotFlow`, `Flow` parameter on a composable, conflate, or distinctUntilChanged.

Mobile App Development#android#jetpack-compose