Skip to main content

Immersive Spaces

One of the key features of visionOS are ImmersiveSpaces, which allow to display unbounded content in a person’s surroundings.


Make sure to set UIApplicationSupportsMultipleScenes to true in Info.plist as described here.

Declare ImmersiveSpace in App.swift

struct HelloWorldApp: App {
@UIApplicationDelegateAdaptor var delegate: AppDelegate
@State private var immersionLevel: ImmersionStyle = .mixed

var body: some Scene {
RCTMainWindow(moduleName: "HelloWorldApp")
ImmersiveSpace(id: "TestImmersiveSpace") {
// RealityKit content goes here
.immersionStyle(selection: $immersionLevel, in: .mixed, .progressive, .full)

ImmersiveSpaces can have multiple levels of immersion:

  • The mixed style blends your content with passthrough.
  • The full style displays only your content, with passthrough turned off.
  • The progressive style completely replaces passthrough in a portion of the display.

For more information about ImmersiveSpace API refer to Apple documentation.

Open new ImmersiveSpace from JS

In order to open a new ImmersiveSpace, call XR.requestSession(). Additionally you can pass data that can be retrieved in SwiftUI, checkout use SwiftUI to render windows to learn more.

import { XR } from "@callstack/react-native-visionos";
const openXRSession = async () => {
try {
if (!XR.supportsMultipleScenes) {
Alert.alert("Error", "Multiple scenes are not supported");
await XR.requestSession("TestImmersiveSpace", { title: "Hey!" }); // Pass the same identifier from `App.swift`
} catch (e) {
Alert.alert("Error", e.message);

Opening an ImmersiveSpace can fail in following scenarios:

  • ImmersiveSpace is not declared.
  • UIApplicationSupportsMultipleScenes is set to false.
  • User cancels the request.

This will open a new immersive space for the user. Later on if you want to close it, call:

const closeXRSession = async () => {
await XR.endSession();

Only one immersive space can be open at a time.