This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
mobilecritical PriorityID: cmp-skiko-rendering-thread-decoupling

Compose Multiplatform Skiko Rendering Thread Decoupling Standard

Enforces strict isolation between Compose snapshot state mutations, heavy data transformations, and Skiko's hardware vsync render dispatch loop (CADisplayLink on iOS and Choreographer on Android). Prevents hitching, dropped frames, and Skia draw command bottlenecks by deferring heavy calculations off the main rendering path and restricting drawing blocks to pure Skiko operations.

Prohibited Anti-Pattern: Executing Non-Visual State Computation, Blocking Layout Logic, or Heavy Math Inside Compose Draw Phases and Direct Skiko Render Passes

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: Compose Multiplatform Skiko Rendering Thread Decoupling Standard - Enforces strict isolation between Compose snapshot state mutations, heavy data transformations, and Skiko's hardware vsync render dispatch loop (CADisplayLink on iOS and Choreographer on Android). Prevents hitching, dropped frames, and Skia draw command bottlenecks by deferring heavy calculations off the main rendering path and restricting drawing blocks to pure Skiko operations.
globs: **/commonMain/**/*.kt, **/iosMain/**/*.kt, **/androidMain/**/*.kt
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/cmp-skiko-rendering-thread-decoupling"
---

# Compose Multiplatform Skiko Rendering Thread Decoupling Standard

> **Severity**: CRITICAL | **Category**: mobile
> **Anti-Pattern Warning**: Executing Non-Visual State Computation, Blocking Layout Logic, or Heavy Math Inside Compose Draw Phases and Direct Skiko Render Passes

## System Constraints
You are a Principal Mobile Architect specializing in Compose Multiplatform (CMP) and Skiko graphics engine internals. Your objective is to enforce strict decoupling of state calculation, snapshot updates, and background I/O from the Skiko hardware vsync presentation loop across iOS and Android. Prevent any operations that block CADisplayLink or Choreographer ticks, ensure derived state memoization, and isolate canvas draw pipelines.

## Strict Guidelines
- Engineers MUST ALWAYS offload heavy computations, filtering, sorting, and serialization to Dispatchers.Default, pushing only ready-to-render immutable state models to the UI layer.
- Engineers MUST NOT invoke state transformations, dynamic allocations, or snapshot writes inside DrawScope, Canvas, or onDrawModifier lambdas.
- Engineers MUST wrap fine-grained frequent state reads inside derivedStateOf or snapshotFlow to prevent redundant Skiko draw passes during fast-changing inputs (e.g., scroll offsets, sensor inputs).
- Services MUST ensure that platform-specific Skiko rendering contexts (such as SkikoUIView or Metal render targets) are never blocked by synchronous locks or blocking runBlocking calls.
- Components NEVER execute file I/O, network reads, or heavy image decodes synchronously on the Main/Rendering thread before feeding Skia textures.

## Bad vs Good Implementations
### Decoupling Heavy Data Mapping and Canvas Path Computation from the Draw Pass

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Sorting and allocating UI paths inside or immediately upstream of the Canvas scope triggers garbage collection pressure and CPU contention on the rendering thread, blocking Skiko's draw loop and missing hardware vsync deadlines.
```kotlin
import androidx.compose.foundation.Canvas
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Path

@Composable
fun AnalyticsGraph(rawPoints: List<Double>, modifier: Modifier = Modifier) {
    // ANTI-PATTERN: Heavy transformation and allocation executed during recomposition/draw phase,
    // blocking the Skiko CADisplayLink rendering tick.
    Canvas(modifier = modifier) {
        val sortedPoints = rawPoints.sorted().takeLast(100)
        val path = Path().apply {
            sortedPoints.forEachIndexed { index, value ->
                val x = index * (size.width / 100f)
                val y = size.height - (value.toFloat() * size.height)
                if (index == 0) moveTo(x, y) else lineTo(x, y)
            }
        }
        drawPath(path, color = androidx.compose.ui.graphics.Color.Blue)
    }
}
```

#### Production Standard (Correct)
> **Standard**: Calculations are moved off the main rendering loop using coroutines (Dispatchers.Default) and memoized with derivedStateOf/remember. Canvas execution only performs hardware-accelerated drawing with pre-computed structures.
```kotlin
import androidx.compose.foundation.Canvas
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Path
import kotlinx.collections.immutable.ImmutableList
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext

@Immutable
data class NormalizedPoint(val xRatio: Float, val yRatio: Float)

@Composable
fun AnalyticsGraph(normalizedPoints: ImmutableList<NormalizedPoint>, modifier: Modifier = Modifier) {
    // GUARDRAIL: Path is pre-calculated or memoized; allocations inside draw loop are eliminated.
    val cachedPath by remember(normalizedPoints) {
        derivedStateOf {
            Path().apply {
                normalizedPoints.forEachIndexed { index, point ->
                    if (index == 0) moveTo(point.xRatio, point.yRatio) else lineTo(point.xRatio, point.yRatio)
                }
            }
        }
    }

    Canvas(modifier = modifier) {
        // Skiko draw pass executes strictly precomputed vector commands scaled to canvas bounds
        drawPath(path = cachedPath, color = Color.Blue)
    }
}

// Compute pipeline decoupled to background dispatcher
suspend fun processGraphPoints(raw: List<Double>): ImmutableList<NormalizedPoint> =
    withContext(Dispatchers.Default) {
        // Heavy sorting and calculations decoupled from UI/Render thread
        buildNormalizedPoints(raw)
    }
```

Recommended MCP Servers (mcp-serverlist.com)

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

Architectural Specification & Invariant Rationale

Architectural Invariant Design: Compose Multiplatform Skiko Rendering Thread Decoupling Standard

Compose Multiplatform Skiko Rendering Thread Decoupling Standard defines an industrial-grade behavioral standard for mobile engineering. Enforces strict isolation between Compose snapshot state mutations, heavy data transformations, and Skiko's hardware vsync render dispatch loop (CADisplayLink on iOS and Choreographer on Android). Prevents hitching, dropped frames, and Skia draw command bottlenecks by deferring heavy calculations off the main rendering path and restricting drawing blocks to pure Skiko operations. 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: Executing Non-Visual State Computation, Blocking Layout Logic, or Heavy Math Inside Compose Draw Phases and Direct Skiko Render Passes 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 DriftExecuting Non-Visual State Computation, Blocking Layout Logic, or Heavy Math Inside Compose Draw Phases and Direct Skiko Render PassesCritical
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 offload heavy computations, filtering, sorting, and serialization to Dispatchers.Default, pushing only ready-to-render immutable state models to the UI layer.

Engineers MUST ALWAYS offload heavy computations, filtering, sorting, and serialization to Dispatchers.Default, pushing only ready-to-render immutable state models to the UI layer.

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 invoke state transformations, dynamic allocations, or snapshot writes inside DrawScope, Canvas, or onDrawModifier lambdas.

Engineers MUST NOT invoke state transformations, dynamic allocations, or snapshot writes inside DrawScope, Canvas, or onDrawModifier lambdas.

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 wrap fine-grained frequent state reads inside derivedStateOf or snapshotFlow to prevent redundant Skiko draw passes during fast-changing inputs (e.g., scroll offsets, sensor inputs).

Engineers MUST wrap fine-grained frequent state reads inside derivedStateOf or snapshotFlow to prevent redundant Skiko draw passes during fast-changing inputs (e.g., scroll offsets, sensor inputs).

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

Services MUST ensure that platform-specific Skiko rendering contexts (such as SkikoUIView or Metal render targets) are never blocked by synchronous locks or blocking runBlocking calls.

Services MUST ensure that platform-specific Skiko rendering contexts (such as SkikoUIView or Metal render targets) are never blocked by synchronous locks or blocking runBlocking calls.

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

Components NEVER execute file I/O, network reads, or heavy image decodes synchronously on the Main/Rendering thread before feeding Skia textures.

Components NEVER execute file I/O, network reads, or heavy image decodes synchronously on the Main/Rendering thread before feeding Skia textures.

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 Compose Multiplatform Skiko Rendering Thread Decoupling Standard critical for AI coding assistants?

Enforces strict isolation between Compose snapshot state mutations, heavy data transformations, and Skiko's hardware vsync render dispatch loop (CADisplayLink on iOS and Choreographer on Android). Prevents hitching, dropped frames, and Skia draw command bottlenecks by deferring heavy calculations off the main rendering path and restricting drawing blocks to pure Skiko operations. 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 (Executing Non-Visual State Computation, Blocking Layout Logic, or Heavy Math Inside Compose Draw Phases and Direct Skiko Render Passes) 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

Compose