This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
mobilecritical PriorityID: jetpack-compose-strong-skipping-layout-stabilization-standard

Jetpack Compose Strong Skipping Mode Layout Stabilization Standard

Enforces compiler-grade stability contracts, structural equality invariants, and capture hygiene under Compose Strong Skipping Mode. Eradicates recomposition cascades in high-frequency rendering trees by eliminating unstable parameter passing, non-memoized lambda capture leaks, and broken equals/hashCode contracts.

Prohibited Anti-Pattern: Instantiating Unstable Models and Breaking Value Equality Across Strong-Skipping Composable Boundaries

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: Jetpack Compose Strong Skipping Mode Layout Stabilization Standard - Enforces compiler-grade stability contracts, structural equality invariants, and capture hygiene under Compose Strong Skipping Mode. Eradicates recomposition cascades in high-frequency rendering trees by eliminating unstable parameter passing, non-memoized lambda capture leaks, and broken equals/hashCode contracts.
globs: **/*.kt, **/*.kts
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/jetpack-compose-strong-skipping-layout-stabilization-standard"
---

# Jetpack Compose Strong Skipping Mode Layout Stabilization Standard

> **Severity**: CRITICAL | **Category**: mobile
> **Anti-Pattern Warning**: Instantiating Unstable Models and Breaking Value Equality Across Strong-Skipping Composable Boundaries

## System Constraints
You are a Principal Software Architect enforcing the Jetpack Compose Strong Skipping Mode Layout Stabilization Standard. Under Strong Skipping, composables with unstable parameters are skipped only if instance equality or structural equals() returns true, and all lambdas are auto-remembered unless they capture unstable values. You must mandate strict adherence to value equality contracts, immutable collection primitives, deterministic modifier chains, and decoupled high-frequency state reads.

## Strict Guidelines
- Engineers MUST ALWAYS implement structural equals() and hashCode() on all state holder classes and UI model representations passed across @Composable boundaries.
- Engineers MUST NOT rely on standard kotlin.collections.List, Set, or Map for composable parameters; use kotlinx.collections.immutable.ImmutableList/ImmutableSet or annotate wrapping models with @Immutable or @Stable.
- Engineers MUST ALWAYS expose a 'modifier: Modifier = Modifier' parameter as the first optional parameter of any custom Composable and chain callers' modifiers directly to the root layout node.
- Engineers MUST NOT perform state reads of high-frequency inputs (such as scroll offsets, sensor inputs, or animation deltas) inside the composition phase; wrap them in derivedStateOf or defer reads to the layout/draw phase via lambda-based Modifier extensions (e.g., Modifier.offset { ... }, Modifier.drawWithContent { ... }).
- Engineers MUST NOT pass lambdas capturing unstable local scope references without explicitly isolating mutable state reads inside the lambda or hoisting stable lambda instances.
- Code SHOULD verify Composable metrics outputs via composeCompilerReports to guarantee all node boundaries evaluate as 'skippable' and parameter types resolve to 'stable'.

## Bad vs Good Implementations
### Stabilizing Unstable Model Parameters and Lambda Capture Under Strong Skipping

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: UserProfile is a standard class missing value equality contracts (equals/hashCode), and List<String> is treated as unstable by the Compose compiler. Even with Strong Skipping Mode, the equality check falls back to reference equality on UserProfile and deep collection recalculations. A new Modifier instance is constructed inside the layout, breaking structural composition invariants.
```kotlin
import androidx.compose.runtime.Composable
import androidx.compose.material3.Text
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Row

// ANTI-PATTERN: Standard List is unstable, Regular class lacks equals/hashCode,
// and direct state reads trigger cascading recompositions across the entire list.
class UserProfile(
    val id: String,
    val tags: List<String>
)

@Composable
fun UserProfileCard(
    profile: UserProfile,
    onTagClick: (String) -> Unit
) {
    // Creating a fresh Modifier breaks layout memoization across skipping phases
    Row {
        Text(text = profile.id)
        // Recreated lambda capturing unstable outer variables forces recomposition
        profile.tags.forEach { tag ->
            Text(
                text = tag,
                modifier = androidx.compose.ui.Modifier.clickable { onTagClick(tag) }
            )
        }
    }
}
```

#### Production Standard (Correct)
> **Standard**: UserProfile is marked @Immutable with a data class guaranteeing structural equals() and hashCode(). tags uses kotlinx.collections.immutable.ImmutableList, making the parameter explicitly stable. The modifier parameter is defaulted and chained, allowing Strong Skipping Mode to reliably skip recomposition when data equality holds.
```kotlin
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Immutable
import androidx.compose.ui.Modifier
import androidx.compose.material3.Text
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Row
import kotlinx.collections.immutable.ImmutableList

// PRODUCTION FIX: Immutable annotation guarantees compiler stability;
// ImmutableList enforces structural immutability contract across skips.
@Immutable
data class UserProfile(
    val id: String,
    val tags: ImmutableList<String>
)

@Composable
fun UserProfileCard(
    profile: UserProfile,
    onTagClick: (String) -> Unit,
    modifier: Modifier = Modifier
) {
    Row(modifier = modifier) {
        Text(text = profile.id)
        profile.tags.forEach { tag ->
            Text(
                text = tag,
                modifier = Modifier.clickable { onTagClick(tag) }
            )
        }
    }
}
```

### Deferring High-Frequency Scroll State Reads to Phase-Specific Modifiers

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Reading scrollState.firstVisibleItemScrollOffset directly inside the Composable function scope invalidates the entire Composable on every single scroll frame. Strong Skipping cannot bypass this execution because the state read is tied directly to the composition phase.
```kotlin
import androidx.compose.runtime.Composable
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.offset
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp

// ANTI-PATTERN: Reading scroll offset directly in the composition phase causes
// UserHeader to recompose on EVERY frame during scrolling, bypassing Strong Skipping.
@Composable
fun UserHeader(
    scrollState: LazyListState,
    modifier: Modifier = Modifier
) {
    val offsetPx = scrollState.firstVisibleItemScrollOffset
    Box(
        modifier = modifier.offset(y = (offsetPx / 2).dp)
    )
}
```

#### Production Standard (Correct)
> **Standard**: By utilizing the lambda-based Modifier.offset { ... }, state reading is deferred to the Layout/Draw phase. The UserHeader Composable is executed once during initial composition and skipped completely during scrolling, eliminating render-thread jank.
```kotlin
import androidx.compose.runtime.Composable
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.offset
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.IntOffset

// PRODUCTION FIX: Defer state read to the layout/offset phase via lambda modifier.
// Zero recompositions occur during continuous scrolling.
@Composable
fun UserHeader(
    scrollState: LazyListState,
    modifier: Modifier = Modifier
) {
    Box(
        modifier = modifier.offset {
            IntOffset(x = 0, y = scrollState.firstVisibleItemScrollOffset / 2)
        }
    )
}
```

Recommended MCP Servers (mcp-serverlist.com)

Equip agent with system tools to verify code for this stack.

Recommended Agent Skills (askills.dev)

Ready-to-use executable skill functions tailored to this stack.

Architectural Specification & Invariant Rationale

Architectural Invariant Design: Jetpack Compose Strong Skipping Mode Layout Stabilization Standard

Jetpack Compose Strong Skipping Mode Layout Stabilization Standard defines an industrial-grade behavioral standard for mobile engineering. Enforces compiler-grade stability contracts, structural equality invariants, and capture hygiene under Compose Strong Skipping Mode. Eradicates recomposition cascades in high-frequency rendering trees by eliminating unstable parameter passing, non-memoized lambda capture leaks, and broken equals/hashCode contracts. Modern software architectures require strict adherence to deterministic patterns to guarantee high availability, maintainability, and zero security vulnerabilities.

Framework Paradigm Shift & Drift MechanicsLLMs are trained on millions of open-source repositories containing outdated code, legacy idioms, and unpatched antipatterns. When coding assistants generate implementations for this stack, they default to common statistical tokens: Instantiating Unstable Models and Breaking Value Equality Across Strong-Skipping Composable Boundaries Without an explicit system instruction file, developers spend hours debugging silent failures.
Failure Modes & Production Blast Radius

Hazard Analysis: What Breaks Without This Rule

The following failure modes have been cataloged from hundreds of hours of production code reviews where AI assistants produced non-compliant implementations:

Failure ModeAI Symptom (The Anti-Pattern)SeverityProduction Impact & Remedy
AI Hallucination & Deprecation DriftInstantiating Unstable Models and Breaking Value Equality Across Strong-Skipping Composable BoundariesCritical
Violating this industrial standard introduces regression bugs, security risks, and unexpected runtime failures in production.
Enforce explicit behavioral system directives across all AI coding assistants in your repository.
Silent Architecture InconsistencyAI assistants produce mixed paradigms across files, creating fragmented codebase conventions.Medium
Increases cognitive load during code reviews and leads to maintenance debt across engineering teams.
Pin project conventions in .cursor/rules, CLAUDE.md, and AGENTS.md so all team agents follow identical guardrails.
Architectural Directives in Detail

Step-by-Step Production Directives

Each rule constraint below is injected into the AI agent's system prompt to establish deterministic boundaries:

1

Engineers MUST ALWAYS implement structural equals() and hashCode() on all state holder classes and UI model representations passed across @Composable boundaries.

Engineers MUST ALWAYS implement structural equals() and hashCode() on all state holder classes and UI model representations passed across @Composable boundaries.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
2

Engineers MUST NOT rely on standard kotlin.collections.List, Set, or Map for composable parameters

Engineers MUST NOT rely on standard kotlin.collections.List, Set, or Map for composable parameters; use kotlinx.collections.immutable.ImmutableList/ImmutableSet or annotate wrapping models with @Immutable or @Stable.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
3

Engineers MUST ALWAYS expose a 'modifier

Engineers MUST ALWAYS expose a 'modifier: Modifier = Modifier' parameter as the first optional parameter of any custom Composable and chain callers' modifiers directly to the root layout node.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
4

Engineers MUST NOT perform state reads of high-frequency inputs (such as scroll offsets, sensor inputs, or animation deltas) inside the composition phase

Engineers MUST NOT perform state reads of high-frequency inputs (such as scroll offsets, sensor inputs, or animation deltas) inside the composition phase; wrap them in derivedStateOf or defer reads to the layout/draw phase via lambda-based Modifier extensions (e.g., Modifier.offset { ... }, Modifier.drawWithContent { ... }).

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
5

Engineers MUST NOT pass lambdas capturing unstable local scope references without explicitly isolating mutable state reads inside the lambda or hoisting stable lambda instances.

Engineers MUST NOT pass lambdas capturing unstable local scope references without explicitly isolating mutable state reads inside the lambda or hoisting stable lambda instances.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
6

Code SHOULD verify Composable metrics outputs via composeCompilerReports to guarantee all node boundaries evaluate as 'skippable' and parameter types resolve to 'stable'.

Code SHOULD verify Composable metrics outputs via composeCompilerReports to guarantee all node boundaries evaluate as 'skippable' and parameter types resolve to 'stable'.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
Technical Questions & Answers

Frequently Asked Technical Questions

Common questions developers face when configuring AI coding assistants for this stack:

Q:Why is Jetpack Compose Strong Skipping Mode Layout Stabilization Standard critical for AI coding assistants?

Enforces compiler-grade stability contracts, structural equality invariants, and capture hygiene under Compose Strong Skipping Mode. Eradicates recomposition cascades in high-frequency rendering trees by eliminating unstable parameter passing, non-memoized lambda capture leaks, and broken equals/hashCode contracts. Without explicit behavioral boundaries, AI coding assistants (Cursor, Claude Code, Windsurf, Codex) rely on training data averages, which frequently produce deprecated, inefficient, or vulnerable code patterns.

Q:How does adopting this rule prevent AI hallucinations?

This rule explicitly declares what the AI must avoid (Instantiating Unstable Models and Breaking Value Equality Across Strong-Skipping Composable Boundaries) and prescribes verified positive examples. Grounding the LLM with negative and positive pairs eliminates guesswork.

Q:Which AI coding environments are supported?

This specification is multi-platform compatible: Cursor (.cursor/rules/*.mdc & .cursorrules), Anthropic Claude Code (CLAUDE.md), Windsurf (.windsurfrules), Codex / Cline (AGENTS.md), and GitHub Copilot (.github/copilot-instructions.md).

Q:Can I combine this rule with other technology stacks?

Yes. Use the Interactive Stack Builder or download an Agent Pack to merge this rule with other frontend, backend, database, security, and DevOps rules without syntax collision.

Open Specification · CC BY 4.0·Free for Personal, Team & Commercial In-Repo Use

Citation & Open Source Attribution Guidelines

This specification is licensed under Creative Commons Attribution 4.0 International (CC BY 4.0). You are completely free to adapt and share this rule in your workspace. If citing, including in public AI benchmark datasets, or redistributing, attribution to AgentRules.org is required.

Related MOBILE Rules

View all rules →
1 Rule in Stack

Jetpack