JetBrains/kotlin
Compose
Active contributors: Andrei Shikov, Dmitriy Novozhilov, Wojciech Litewka
plugins/compose/ is the compiler plugin behind Jetpack Compose (Android) and Compose Multiplatform. It transforms @Composable functions, inserts the Compose runtime's bookkeeping calls, generates skipping logic for unchanged inputs, and tracks state-read snapshots. Without this plugin, code marked @Composable would fail to compile against Compose runtime expectations.
Purpose
Implement the Compose programming model at the compiler level. Compose's correctness depends on the compiler injecting per-call group identifiers, lifting state reads, and generating "skippable" wrappers for @Composable functions whose parameters didn't change. The plugin makes this happen.
Directory layout
plugins/compose/
├── compiler-hosted/ The plugin entry points (FIR + IR extensions)
├── compose-cli/ CLI integration helpers
├── compose-compiler-cli/ Standalone compose compiler command
├── compose-compiler-tests/ Tests
├── plugins-interactions-testing/ (cross-plugin tests in the parent plugins/ dir)
├── ChangeLog.md Compose plugin release notes
└── README.mdKey abstractions
| Concept | Role |
|---|---|
@Composable |
The annotation that opts a function into Compose. The plugin recognizes it during FIR resolution. |
| Group keys | Stable identifiers the plugin injects into composable bodies so Compose can recompose just the affected part of the tree. |
| Skipping wrappers | Generated wrappers that early-return if all inputs are equal to the previous invocation. |
| State reads | The plugin lifts reads of androidx.compose.runtime.State-derived values so Compose can subscribe a composition to changes. |
@Stable, @Immutable |
Annotations the plugin uses to decide whether a parameter participates in skip logic. |
Composer parameter |
The plugin transforms every @Composable function to take an extra Composer parameter, mirroring how the runtime threads its state. |
How it works
graph LR
FIR["FIR<br/>(post-resolution)"] -->|recognizes @Composable| FirExt["Compose FIR extension"]
FirExt -->|generates contracts| FIR2["FIR with extra<br/>frontend information"]
Fir2Ir["fir2ir"] --> IR["IR"]
IR --> IrTransform["Compose IR generator"]
IrTransform -->|inject Composer<br/>+ group keys + skipping| IR2["Transformed IR"]
IR2 --> Backend["JVM / JS / Wasm / Native"]The plugin runs in two layers: a FIR extension that recognizes Compose constructs and supplies frontend information needed for resolve, and an IR generator (IrGenerationExtension) that does the heavy mechanical transformation.
Multiplatform
Compose is one of Kotlin's flagship Multiplatform stories. The plugin is target-agnostic — it transforms IR before per-target lowering, so the same plugin produces correct output for Android, iOS (Native), desktop (JVM), Wasm, and JS targets.
The runtime that the transformed code calls into (androidx.compose.runtime) lives in separate repositories: AndroidX (Google) for the Android-flavored runtime and JetBrains/compose-multiplatform for the multiplatform runtime. This repository ships only the compiler plugin.
KGP integration
libraries/tools/kotlin-compose-compiler/ is the Gradle DSL counterpart. It applies the plugin and exposes Compose-specific options:
plugins {
kotlin("multiplatform")
id("org.jetbrains.kotlin.plugin.compose")
}Versioning
Compose's compiler plugin is tightly coupled to specific runtime versions because of API contracts. The ChangeLog.md in the plugin's directory tracks compatibility.
Tests
plugins/compose/compose-compiler-tests/ runs golden-file tests against checked-in reference output. The reference output captures the IR after Compose transformation; mismatches indicate the plugin's transformation has changed.
Integration points
- Backend-agnostic: runs as IR generator, so all backends (JVM, JS, Wasm, Native) get correct output.
- Consumed by: any Kotlin Multiplatform / Android project using Compose.
- Co-traveler:
androidx.compose.runtimeand the JetBrains Compose Multiplatform runtime — defined elsewhere, used at runtime.
Where to start
For a transformation-behavior change: plugins/compose/compiler-hosted/ and look for the IR-transformer classes. For Compose-specific frontend behavior (e.g., a new @Composable rule): the FIR extension in the same module.
See plugins/index.md for the broader plugin landscape.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.