Lesson 2

Reading Compose source as evidence

Use declarations, producers, consumers, tests, and history to bound an internals claim.

4 min readUpdated Jul 11, 2026

Status: The reading method is Durable . Conclusions about the pinned files are Version-specific . A test proves its inputs, source set, target, and assertions. It does not prove every private detail forever.

Outcome

When you investigate one Compose mechanism, you should be able to say:

  • where the protocol is declared;
  • which compiler code produces it;
  • which runtime code consumes it;
  • which test observes it; and
  • what history says about its scope.

This prevents a plausible explanation from becoming an unearned guarantee.

Start with a claim, not a class name

Searches for startRestartGroup often produce this sentence:

Compose creates a restart group around every composable.

That sentence hides several questions. Is the name a public contract? Who emits the call? Do all consumers implement it the same way? Which test covers it? Is the behavior current or transitional?

Use a source walk to answer them in order.

Build an evidence graph

Diagram
flowchart TD
    Interface[Protocol declaration] --> Producer[Compiler producer]
    Producer --> Consumer[Runtime consumer]
    Consumer --> Tests[Runtime tests]
    Interface --> History[Pinned history]
    Tests --> Conclusion[Bounded conclusion]
    History --> Conclusion

Read the arrows as questions: what does the runtime ask for, who emits it, how do consumers interpret it, what do tests observe, what changed, and what bounded conclusion follows?

Know what each source set can prove

Source setStrong useBoundary
commonMainShared protocol and implementationNot every platform integration or public API status
nonEmulatorCommonTestRuntime behavior and edge casesNot every workload or platform
androidInstrumentedTestAndroid/device integrationNot common-runtime behavior everywhere
Compiler lowerHow source becomes runtime callsNot runtime behavior by itself
Compiler test dataGolden output and compiler checksNot a universal rule beyond its inputs
runtime/designIntent and historical vocabularyNot current behavior when code differs
BenchmarksMaintainer-selected measurementsNot application-wide causality

The pinned runtime source tree and Compose compiler tree are maps, not conclusions.

A four-stop source walk

Use startRestartGroup as a small exercise.

1. Read the protocol

Open Composer.kt. startRestartGroup(key) is a compiler-facing protocol method. Its KDoc describes a source-keyed group that can be recomposed on demand. This establishes the contract and intended role.

It does not prove that every composable gets one, that keys are globally unique, or that every compiler version emits the same shape.

2. Find the producer

Open the pinned ComposableFunctionBodyTransformer.kt. Search for the generated start and end group calls. This ties the runtime protocol to compiler lowering.

It does not prove an exact dirty-mask layout or that every body is restartable. Those need transformer conditions and compiler test data.

3. Compare consumers

The pinned runtime has separate implementations in GapComposer.kt and LinkComposer.kt. The protocol can stay common while storage differs. The link-buffer flag is disabled by default at this revision, so teach that path as Experimental , not as the universal implementation.

4. Narrow with tests and history

Read runtime restart tests for the behavior they actually assert. Then inspect pinned file history to learn whether a method or implementation is new, renamed, or transitional. History explains evolution; current code and tests decide the current claim.

A repeatable command set

From clean, pinned checkouts:

ANDROIDX=5e647f344a6a600b7342f43f2203d22bb82ca48a
KOTLIN=a1ab72da08c7cc2acca226db6193ea38d988e253

git -C /tmp/support grep -n "startRestartGroup" -- \
  compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime
git -C /tmp/kotlin grep -n "startRestartGroup" -- \
  plugins/compose/compiler-hosted
git -C /tmp/support grep -n "skip" -- \
  compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/RestartTests.kt

The commands establish provenance; read the surrounding code and test assertions too.

Check yourself

Rewrite this claim so it matches the evidence:

Compose creates a restart group around every composable.

A good answer names the protocol, pins the compiler/runtime observation, and avoids universal language.

Source notes

ClaimDirect evidenceStatus
Composer exposes a restart-group protocolComposer.ktDurable Version-specific
The compiler plugin emits the protocol at the pinned revisionComposableFunctionBodyTransformer.ktVersion-specific
Gap and link composers are distinct consumersGapComposer.kt and LinkComposer.ktVersion-specific Experimental
Tests bound restart and skip claimsRestartTests.ktVersion-specific
History is context, not a replacement for current codePinned Gitiles Composer historyDurable

Freshness

Refresh this lesson when lowering moves, the Composer protocol changes, a consumer is added or removed, the link-buffer flag changes default, or restart tests are renamed. Re-pin both repositories before updating a conclusion.

Finished this lesson?

Your progress stays only in this browser.