Layout inspector

The Compose layout / component hierarchy with bounds, constraints, modifiers, and source refs — plus a sibling compose/semantics projection for testTag / role / mergeMode questions.

At a glance

   
Kinds layout/inspector, compose/semantics
Schema version 1
Modules :data-layoutinspector-core (published) · :data-layoutinspector-connector
Render mode default
Cost low
Token usage Inline JSON, not yet benchmarked (scales with hierarchy depth). See token usage.
Transport inline
Platforms Android · Desktop · shared

What it answers

  • layout/inspector — what’s the parent / child shape of this composable? Measured size? Constraints? Z-order? Which inspectable modifiers are attached, with what values? Which source file / line declared the node?
  • compose/semantics — for each SemanticsNode, what is its testTag, role, mergeMode, bounds?

It is intentionally separate from a11y/hierarchy — the question there is “what does an assistive technology see”; the question here is layout structure or stable test selectors.

What it does NOT answer

  • It does not run accessibility checks — that is a11y/atf.
  • It does not measure recomposition — that is compose/recomposition.
  • The Desktop / shared backend reaches the layout tree through RootForTest; non-Compose Android views (interop) are not modelled.

Use cases

  • Pinpoint which composable owns a misaligned region from history/diff/regions.
  • Confirm a refactor preserved testTags so existing UI tests keep finding their targets.
  • Inspect resolved Modifier.padding(...) values when a screenshot says one thing and the source says another.
  • Drive the VS Code extension’s tree view of a preview.

Payload shape

LayoutInspectorPayload, LayoutInspectorNode, ComposeSemanticsPayload, ComposeSemanticsNode in :data-layoutinspector-core.

// layout/inspector
{
  "nodes": [
    { "nodeId": "1", "component": "Column",
      "bounds": { "left": 0, "top": 0, "right": 1080, "bottom": 1920 },
      "measuredSize": "1080x1920",
      "constraints": "minW=0, maxW=1080, minH=0, maxH=1920",
      "modifiers": [{ "name": "padding", "args": "16dp" }],
      "sourceRef": "HomeScreen.kt:42" }
  ]
}

// compose/semantics
{
  "nodes": [
    { "nodeId": "2", "testTag": "submit-button", "role": "Button",
      "mergeMode": "mergeDescendants", "boundsInRoot": "48,200,144,232" }
  ]
}

Enabling

Producer runs whenever its owning extension is publicly enabled. Backed on Android by the daemon’s RootForTest carried on PreviewContext.inspection. CLI / Gradle output: build/compose-previews/data/<id>/layout-inspector.json and compose-semantics.json.

The compose-preview serve viewer projects the same tree into three inspection layers over the rendered frame — Overlays → Inspect → Typography (per text node: resolved size / line height / face / weight, from ComposeSemanticsNode.typography), Theme attributes (per container: resolved fill or gradient, border, corner radius, shape, shadow elevation, effective alpha and clip, from ComposeSemanticsNode.tokens, anchored to the node’s captured paintBox when it has one) and Layout boxes (per slot: the box’s own size and origin, its per-edge padding, the arrangement gap and any defaultMinSize floor). The compact legend row carries what fits on one line; the row’s tooltip carries the whole resolved token map. All three are served by /render/<id>.annotations as DesignAnnotations, the same shape the design-comparison page draws its producer-authored spec layers from — so the Layout layer is the code-side counterpart of the reference-side layout redline, and quotes the same tokens as the published layout wireframe.

Companion products

  • Accessibility — a11y/hierarchy for the assistive-technology view of the same nodes.
  • Recomposition — compose/recomposition for per-node recomposition counts keyed off the same node ids.
  • Theme — compose/theme for the tokens consumed at each node.

Apache 2.0 licensed. Source on GitHub.

This site uses Just the Docs, a documentation theme for Jekyll.