Jetpack Compose for XR
| Latest Update | Stable Release | Release Candidate | Beta Release | Alpha Release |
|---|---|---|---|---|
| October 22, 2025 | - | - | - | 1.0.0-alpha08 |
Declaring dependencies
To add a dependency on XR compose, you must add the Google Maven repository to your project. Read Google's Maven repository for more information.
Add the dependencies for the artifacts you need in the build.gradle file for
your app or module:
Groovy
dependencies { implementation "androidx.xr.compose:compose:1.0.0-alpha08" // Use to write unit tests testImplementation "androidx.xr.compose:compose-testing:1.0.0-alpha08" }
Kotlin
dependencies { implementation("androidx.xr.compose:compose:1.0.0-alpha08") // Use to write unit tests testImplementation("androidx.xr.compose:compose-testing:1.0.0-alpha08") }
For more information about dependencies, see Add build dependencies.
Feedback
Your feedback helps make Jetpack better. Let us know if you discover new issues or have ideas for improving this library. Please take a look at the existing issues in this library before you create a new one. You can add your vote to an existing issue by clicking the star button.
See the Issue Tracker documentation for more information.
Version 1.0
Version 1.0.0-alpha08
October 22, 2025
androidx.xr.compose:compose:1.0.0-alpha08 and androidx.xr.compose:compose-testing:1.0.0-alpha08 are released. Version 1.0.0-alpha08 contains these commits.
API Changes
- Changed
ResizePolicyto acceptonResizeStart,onResizeUpdate, andonResizeEnd. (I7e21f)
Bug Fixes
- Prevent crash when destroying an Activity with a Subspace. (I595a1)
Version 1.0.0-alpha07
September 24, 2025
androidx.xr.compose:compose:1.0.0-alpha07 and androidx.xr.compose:compose-testing:1.0.0-alpha07 are released. Version 1.0.0-alpha07 contains these commits.
API Changes
- Improved KDocs for
SpatialMainPanel. (I27b70, b/444467891) - Introduced
SpatialArrangementfor arranging children along the main axis in 3D layouts likeSpatialRowandSpatialColumn. This new API provides familiar arrangement options from 2D Compose, includingStart,End,Center,SpaceBetween,SpaceAround, andSpaceEvenly, with full support for both LTR and RTL layout directions. (I7db38, b/436289959) - Added a base interface for
SubspaceModifier.Nodeto improve type safety and usability of extension interfaces; such asCompositionLocalConsumerSubspaceModifierNodeLayoutCoordinatesAwareModifierNodeSubspaceLayoutModifierNodeCoreEntityNode(internal) (Iede00, b/440599394, b/440599394)
- Unrestrict
SpatialExternalSurface(I33315, b/439646773) - Introduce
SubspaceModifierto Subspace composables and replace constraints parameter withSubspaceModifierwith size-relatedSubspaceModifiers. IfallowUnboundedSubspaceis true, Subspaces can still have unbounded constraints. (Ib06e6, b/433331675) - Deprecating movable and resizable
SubspaceModifiersnow thatDragPolicy()andResizePolicy()are a part of theSpatialPanelandSpatialExternalSurfaceAPI (I397bf, b/437924639) - Added support for
LayoutDirectionin spatial layouts. Composable usingSpatialAlignmentwill now correctly position elements in both LTR and RTL contexts. (I964bb, b/436300273) - Add Resizable and Movable parameters to the
PanelAPIs to ensure that these behaviors can only be applied to supported containers. (Id491c) - Added
sizeIn,widthIn,heightIn,depthInSubspaceModifiersthat let you set exact minimum and maximum constraints for width, height and depth. (I1af09, b/433330761)
Version 1.0.0-alpha06
August 13, 2025
androidx.xr.compose:compose:1.0.0-alpha06 and androidx.xr.compose:compose-testing:1.0.0-alpha06 are released. Version 1.0.0-alpha06 contains these commits.
Bug Fixes
- Recreate the
ComposeXrOwnerLocalswhen the lifecycle owner is destroyed. (9123ce1)
Version 1.0.0-alpha05
July 30, 2025
androidx.xr.compose:compose:1.0.0-alpha05 and androidx.xr.compose:compose-testing:1.0.0-alpha05 are released. Version 1.0.0-alpha05 contains these commits.
New Features
- Made
SubspaceComposableannotation class public. (Ic2a34, b/399432430) - Two new
SpatialExternalSurfaceComposables representing 180 and 360 degree spheres. (I40ef2, b/391705799) - Added
SubspaceModifier.aspectRatio(Ide5ab, b/399729509, b/414762147) - Added the
SceneCoreEntityAPI to improve interoperability betweenSceneCoreand Compose for XR. (I50bb3, b/423020989) - Provided
GravityAlignedsubspaceAPI to support the unscaled AndGravityAlignedfeature (I07359)
API Changes
SpatialDialog()will followSpatialDialogProperties.dismissOnBackpress configuration. (Ib453b, b/416797132)- Update
minimumPanelDimensionto a new default Dimension size ofDimensions(0.1f, 0.1f, 0.1f)due its representation in Meters. (Ib852a) - Subspaces and Orbiters will now retain their internal state in home space and when the app is in the background. In home space mode, Subspace will still set up its scene in preparation for the switch to full space mode. (I40317, b/416037751)
SpatialDialogswill now retain their state when the app is in the background. (I6aa56)ApplicationSubspacewill now inherit its recommended scale and position from the system. (I4565f, b/418834194)- Added a better error message and trigger the error earlier when a
SubspaceComposableis used in a non-SubspaceComposablecontext. (Iee2ae, b/416484684) - Updating
ExperimentalSubspaceVolumeApifrom Warning to Error because warnings are often overlooked when misusing composable APIs. (I427aa, b/424864286) - Subspace and
ApplicationSubspaceare now constrained byrecommendedContentBoxInFullSpace. Previously it was constrained bySpatialUser's Field of View. (I41015, b/423074142) - Update
SpatialElevationto use min size to no longer use hard coded size (I2dbe6, b/427785338) - Update how we scrim the
SpatialAcitivityPanelto update when a key variable is modified. (I0f64d, b/427999029) - Remove
VolumeConstraints.Unboundedin favor of setting the default constraint values to the equivalent. (Ie24ec, b/407938414) SpatialFeatheringSizeis no longer public (I1c15b, b/399432430)- Renamed the XR
PlaceabletoSubspacePlaceableto distinguish it from Compose'sPlaceable. (I74874) - Removing Orbiter settings and adding
shouldRenderInNonSpatialas a new param. In addition, removing classEdgeOffsetand addingorbiterOffsetTypeas a new param to consolidateOrbiter()Functions. As well as renamingOrbiterEdgetoContentEdge. (Iebf3d) - Renamed
MeasurabletoSubspaceMeasurableto differentiate the type from Compose'sMeasurabletype. (I9726c) - Rename
MeasureResulttoSubspaceMeasureResult(I9f34d) - Removed the
setSubspaceContentAPI in favor of using Compose'ssetContentwith aSubspacecomposable. (Ifff4c, b/421427391, b/421427391) MeasurePolicyis renamed toSubspaceMeasurePolicy. (I37a9b, b/422553904)- Turn
SubspaceSemanticsInfointo a sealed interface because we won't be able to add members without the defaults. (I372f9, b/423704068) - Updated
SpatialExternalSurfacedocumentation, renamedContentSecurityLeveltoSurfaceProtection(I3c460, b/420982808) - Provided overloaded constructor for movable modifier which allows anchoring. (Ic0c70)
- Add more position provider for tooltips so now developers can control if the tooltip is placed above, below, left, or right of the anchor. Add an API that takes in a Shape for carets, so more custom shapes can be provided. (Ie513c, b/374766087, b/418854637)
- Removed
CoreEntityas aPublishedApi(Ifee05)
Bug Fixes
- Fixed issue where
SpatialDialogwould flash when being rendered. (Ife73c, b/401619909) - Fixes issue where
SpatialDialogcould not scrim the Activity Panel. (I8ca6c, b/367442109) - Fix XR dialog not showing some content (I17cd5, b/418062437)
- Fixed issue where
SpatialPopupwas being dismissed when clicked inside of the content. (If262c, b/417245722) - Fixed the issue where when chaining
resizable().movable()the SpatialPanel failed to resize correctly to the new size. (I02ee3, b/422264230) - Fixed
topBaroverlapping with menu inSpatialComposeVideoPlayer(Id33bc, b/427168167) - Fixed corner radius not rendering (I975fe, b/428261830)
Version 1.0.0-alpha04
May 7, 2025
androidx.xr.compose:compose:1.0.0-alpha04 and androidx.xr.compose:compose-testing:1.0.0-alpha04 are released. Version 1.0.0-alpha04 contains these commits.
New Features
- Added
CompositionLocalConsumerSubspaceModifierNodeinterface to allow customSubspaceModifiertypes to access composition local values. - Added a new
SpatialPanelAPI that follows the composeAndroidViewimplementation style and deprecates the previousViewBased SpatialPanel. - Added
VolumeConstraints.Unboundedcompanion object which represents unbounded constraints. - Added
SubspaceModifier.onPointSourceParamsto allow a spatialized audio source. - A public
ApplicationSubspacehas been added, offering optionalVolumeConstraintsto define a 3D area where the app can render spatial content. By default, if no constraints are specified, the Subspace will be bounded by theSpatialUser's current field of view in width and height. Users can provide constraints to be used if the field of view cannot be determined. Otherwise, the default field of view width and height values are used. - Added
SpatialExternalSurface, which can be used to render stereoscopic content.SpatialExternalSurfaceis customizable with modifiers (except alpha), and an edge feathering effect. - Added a new
pointerHoverIconSubspace Modifier that allows users to set the icon for the spatial pointer.
API Changes
- Removed
RequiresApi(34)restriction on all Jetpack XR packages. This restriction was redundant as Jetpack XR is currently only available on devices with API level 34+. (Iae0f8) - Projects released with Kotlin 2.0 require KGP 2.0.0 or newer to be consumed. (Idb6b5)
- Back handling will now work on spatial panels without embedded activities. For back handling to work you need to specify
android:enableOnBackInvokedCallback="true"in the android manifest. - Backhandling will now work on spatial dialogs. For backhandling to work you need to specify
android:enableOnBackInvokedCallback="true"in the android manifest. - Compose-based and View-based
SpatialPanels can now size themselves based on their contents. - Developers may now set their own custom
SpatialElevationLevelvalues and are not limited to the predefined levels. - Orbiter elevation level may now be customized via the
elevationparameter. - Subspace can now be bounded by the
SpatialUser's field of view in width and height by default. If the field of view cannot be determined, the default field of view width and height values are used. - Added new callbacks
onMoveStartandonMoveEndto theMovablemodifier. TheonMoveStartandonMoveEndcallbacks are called when the user starts and ends moving a subspace composable with the movable modifier. - The
nameparameter has been removed from spatial APIs such asSpatialRowandSpatialPanel. For debugging spatial compose trees useSubspaceModifier.testTaginstead. - Removed an unsupported overload of
SpatialPopupthat only hasspatialElevationLevelandcontent. Please use the interface that supportsonDimissRequest. - The
onPoseChangecallback from the Movable modifier has been removed. UseonMoveinstead. SubspaceModifierswill no longer apply their effects if they are detached or currently detaching.- The existing
SpatialRowAPI has been split intoSpatialRowandSpatialCurvedRow. If previously usingSpatialRow'scurveRadiusparameter, useSpatialCurvedRownow instead which offers the same behavior. MainPanelandActivityPanelno longer have title bars when run on a similarly recent system image.- Alpha and scale modifiers are now stackable and will multiply their values for the final applied alpha or scale value.
- The
onPoseChangecallback from the Movable modifier has been optimized to perform smoother pose movement. - The movable and resizable modifiers will now perform their callbacks on the main thread to ensure that state changes will trigger recomposition.
- Added state observation to the layout and measure phases to ensure that state changes in
SubspaceLayoutwill trigger relayout. - Optimized modifier chain updates to better reuse existing modifiers.
Bug Fixes
- Stopped scrimming when a
SpatialDialogis shown. (Ic4594) - Relayout requests made while modifier nodes are detached will now be ignored.
- Removed relayout phases triggered by Movable and Resizable modifiers.
- Fixed a crash in
MainPanel()composable that occurred when either dimension was set to zero, either directly or during a layout calculation, e.g., aSpatialRow/SpatialColumncalculation. The panel will now be hidden instead. Note that this fix specifically addresses crashes during the layout phase; resizing the panel to zero via user interaction will be handled separately. The hidden panel lacks UI affordances. - Fixed issue with
maintainAspectRatiofrom the resizable modifier. The aspect ratio should be kept now. - Fixed an issue with nested Subspaces where they would be incorrectly positioned for a single frame.
- Fixed issue where rounded corners were sometimes not applied when they should be.
NestedSubspaceswill no longer appear for one frame in the wrong location.
Version 1.0.0-alpha03
February 26, 2025
androidx.xr.compose:compose:1.0.0-alpha03 and androidx.xr.compose:compose-testing:1.0.0-alpha03 are released with no notable changes since the last alpha. Version 1.0.0-alpha03 contains these commits
Version 1.0.0-alpha02
February 12, 2025
androidx.xr.compose:compose:1.0.0-alpha02 and androidx.xr.compose:compose-testing:1.0.0-alpha02 are released. Version 1.0.0-alpha02 contains these commits.
New Features
- The Activity Panel can now scrim its content when a Spatial Dialog is activated.
- The
OrbiterAPI is now usable inSubspaceComposablecontexts and will attach Orbiters to their nearestSubspaceLayout-based composable parent. - Introduced
LayoutCoordinatesAwareModifierNodeto allow custom positioning-based modifiers. - Added attach/detach lifecycle methods to
SubspaceModifier.Node. - Added
scaleWithDistanceto the movable modifier. WhenscaleWithDistanceis enabled, the subspace element moved will grow or shrink. It will also maintain any explicit scale that it had before movement.
API Changes
- Removed
SessionCallbackProviderin favor ofSpatialCapabilities.
Other changes
- Reduced
minSDKto 24. All Jetpack XR APIs continue to require API 34 at runtime. OrbiterEdgeOffset.inner,EdgeOffset.outer, andEdgeOffset.overlapconstructors are no longer@Composablemethods, which allows them to be used in non-composable contexts.- Update Spatial Elevation Levels to match the latest UX spec.
- Implement
SubspaceSemanticsInfointerface intoMeasurableLayout. - Renamed
SubspaceModifierElementtoSubspaceModifierNodeElement.
Bug fixes
- Fixes to stabilize
SubspaceModifierordering.SubspaceModifiershould behave more reliably. Offset, rotate, scale, movable, and resizable modifier should now be usable in any order.
Version 1.0.0-alpha01
December 12, 2024
androidx.xr.compose:compose-*1.0.0-alpha01 is released.
Features of Initial Release
Initial developer release of Jetpack Compose for XR. Use familiar Compose concepts such as rows and columns to create spatial UI layouts in XR, whether you're porting an existing 2D app to XR or creating a new XR app from scratch. This library provides subspace and spatial composables: such as spatial panels and orbiters, which let you place your existing 2D Compose or Views-based UI in a spatial layout. It introduces the Volume subspace composable, which allows you to place SceneCore entities, such as 3D models, relative to your UI. Learn more in this developer guide:
Subspace: This composable can be placed anywhere within your app’s UI hierarchy, allowing you to maintain layouts for 2D and spatial UI without losing context between files. This makes it easier to share things like existing app architecture between XR and other form factors without needing to hoist state through your whole UI tree or re-architect your app.SpatialPanel: A spatial panel is a subspace composable that lets you display app content–for example, you could display video playback, still images, or any other content in a spatial panel.
Orbiter: An orbiter is a spatial UI component. It's designed to be attached to a corresponding spatial panel, and contains navigation and contextual action items related to that spatial panel. For example, if you've created a spatial panel to display video content, you could add video playback controls inside an orbiter.
Volume: Place SceneCore entities, such as 3D models, relative to your UI.
Spatial Layout: You can create multiple spatial panels and place them within a Spatial Layout using
SpatialRow,SpatialColumn,SpatialBox, andSpatialLayoutSpacer. UseSubspaceModifiers to customize your layout.Spatial UI components: These elements can be reused in your 2D UI, and their spatial attributes will only be visible when spatial capabilities are enabled.
SpatialDialog: Panel will push slightly back in z-depth to display an elevated dialog.SpatialPopUp: Panel will push slightly back in z-depth to display an elevated popupSpatialElevation:SpatialElevationLevelcan be set to add elevation.
SpatialCapabilities: Spatial capabilities can change as users interact with your app or the system, or can even be changed by your app itself—for example, moving into Home Space or Full Space. To avoid issues, your app needs to check for
LocalSpatialCapabilities.currentto determine which APIs are supported in the current environment.isSpatialUiEnabled: Spatial UI elements (e.g. SpatialPanel)isContent3dEnabled: 3D objectsisAppEnvironmentEnabled: The environmentisPassthroughControlEnabled: Whether or not the application can control the passthrough stateisSpatialAudioEnabled: Spatial audio
Known Issues
- Currently a minSDK of 30 is required to use Jetpack Compose for XR. As a workaround you may add the following manifest entry
<uses-sdk tools:overrideLibrary="androidx.xr.scenecore, androidx.xr.compose"/>to be able to build and run with a minSDK of 23. - Jetpack XR apps currently require requesting
android.permission.SCENE_UNDERSTANDINGpermission in the AndroidManifest. - When an app launches directly into Full Space using the
PROPERTY_XR_ACTIVITY_START_MODEproperty in their manifest, Activities/Applications are initially opened in Home Space before transitioning into Full Space. - glTFs in Volume Composables may initially flicker at the wrong location.
- Using a SpatialDialog in a panel that has been moved significantly will push the content in the wrong direction.