Anchoring and layout rules
Updated: Oct 30, 2026
After you
set up the Meta VR Layout SDK, use anchors and offsets to describe where a spatial window belongs relative to your app’s main window. Horizon OS chooses the final placement within the available space.
Spatial window dimensions use density-independent pixels (dp) and must be positive. In Jetpack Compose, add size(width, height) to the window modifier; a window with no size modifier uses the SDK default of 256 dp on each axis. In React Native, set the required windowWidth and windowHeight props.
Both frameworks define an anchor with a point on the parent window and a point on the spatial window. The Layout SDK places the windows so those two points meet.
Jetpack Compose provides WindowAnchor.Start, WindowAnchor.End, WindowAnchor.Top, WindowAnchor.Bottom, and WindowAnchor.Center helpers for common placements. For custom placement, construct a WindowAnchor with explicit parent and child points.
React Native uses the same parent-and-child model. Pass an explicit {parent, child} pair, or pass a single point such as 'end' and the child mirrors it on every axis you name: one axis gives edge-to-edge placement, two axes give corner-to-corner. Omitting the anchor centers the window on the parent.
The following examples place app-defined ToolsPanel content relative to the main window.
// Fully outside the parent on the right in left-to-right layouts.
SpatialWindow(
key = "tools-end",
modifier = WindowModifier
.size(320.dp, 480.dp)
.anchor(WindowAnchor.End)
.offset(z = OffsetStep.Near),
) { ToolsPanel() }
// Partially overlaps the parent on the left in left-to-right layouts.
SpatialWindow(
key = "tools-start-overlap",
modifier = WindowModifier
.size(320.dp, 480.dp)
.anchor(
WindowAnchor(
parent = WindowEdge.Start,
child = WindowEdge.Center,
)
)
.offset(z = OffsetStep.Near),
) { ToolsPanel() }
<SpatialWindow
label="tools"
windowWidth={320}
windowHeight={480}
anchor={ {parent: 'end', child: 'start'} }
offset={ {z: OffsetNear} }>
<ToolsPanel />
</SpatialWindow>
Semantic offsets use bounded tiers. Compose provides None, Near, MidNear, Mid, MidFar, and Far, which represent approximately 0, 8, 16, 24, 32, and 40 dp. Negative values reverse direction, and custom values clamp to the range from -5 through 5. React Native exports matching constants from OffsetNone through OffsetFar and accepts signed tiers from -5 through 5.
For example, Compose accepts .offset(x = -OffsetStep.Mid, z = OffsetStep(4)).
The equivalent React Native prop is offset={ {x: -OffsetMid, z: 4} }. Import OffsetMid from @metavr/layout-window-compat for this form.
Use exact offsets when a window needs to align with content geometry that semantic tiers cannot represent. In Compose, pass dp values to offset(x, y). In React Native, set planeUnit: 'point' to interpret horizontal and vertical values as layout points, which map to dp on Android. Omitting planeUnit keeps the semantic-step behavior.
Exact offsets apply after anchoring and remain relative to the parent window. Horizontal and vertical values must be finite and are rounded to whole dp. The optional z offset still uses semantic tiers.
The following examples offset app-defined ToolsPanel content from the center of the main window.
SpatialWindow(
key = "tools",
modifier = WindowModifier
.size(320.dp, 480.dp)
.anchor(WindowAnchor.Center)
.offset(x = 24.dp, y = -12.dp, z = OffsetStep.Near),
) { ToolsPanel() }
import {OffsetNear, SpatialWindow} from '@metavr/layout-window-compat';
<SpatialWindow
label="tools"
windowWidth={320}
windowHeight={480}
anchor="center"
offset={ {planeUnit: 'point', x: 24, y: -12, z: OffsetNear} }>
<ToolsPanel />
</SpatialWindow>
In React Native, x is a physical horizontal offset that does not mirror in right-to-left layouts. Use start instead of x for a logical horizontal offset that mirrors. In Compose, each offset call replaces the full previous offset, so include z in the same call when combining exact planar offsets with semantic depth.
Placement space is finite and controlled by Horizon OS. Anchors and offsets express intent, but they do not guarantee exact physical positions, automatic collision avoidance, or identical layouts in Meta Spatial Simulator and on a physical device.