From d7fa3d4d3a9061a248e633fd2de364da151af6bf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Oskar=20Kwa=C5=9Bniewski?= <oskarkwasniewski@icloud.com>
Date: Mon, 26 Feb 2024 12:13:58 +0100
Subject: [PATCH] feat: add multi-window support (#117)

* feat: add multi-window support

* feat: introduce WindowManager

fix: RCTReactViewController properly check props to update

fix: use clearColor instead of systemBackgroundColor for visionOS (#125)

# Conflicts:
#	packages/react-native/Libraries/AppDelegate/RCTRootViewFactory.mm
---
 .../Libraries/AppDelegate/RCTAppDelegate.h    |   4 +-
 .../Libraries/AppDelegate/RCTAppDelegate.mm   |   4 +
 .../AppDelegate/RCTRootViewFactory.mm         |   9 +
 .../SwiftExtensions/RCTMainWindow.swift       |  53 ++-
 .../SwiftExtensions/RCTReactContext.swift     |  45 ++
 .../SwiftExtensions/RCTReactViewController.h  |   2 +
 .../RCTRootViewRepresentable.swift            |   6 +-
 .../Libraries/SwiftExtensions/RCTWindow.swift |  45 ++
 .../React-RCTSwiftExtensions.podspec          |   1 +
 .../WindowManager/NativeWindowManager.js      |   8 +
 .../WindowManager/RCTWindowManager.h          |   6 +
 .../WindowManager/RCTWindowManager.mm         |  90 ++++
 .../WindowManager/WindowManager.d.ts          |  16 +
 .../Libraries/WindowManager/WindowManager.js  |  63 +++
 .../Libraries/XR/ImmersiveBridge.swift        |   8 +-
 .../react-native/Libraries/XR/RCTXRModule.mm  |  63 +--
 packages/react-native/Libraries/XR/XR.d.ts    |   3 +-
 packages/react-native/Libraries/XR/XR.js      |  14 +-
 .../__snapshots__/public-api-test.js.snap     |  26 +-
 packages/react-native/React-Core.podspec      |   1 +
 packages/react-native/React.podspec           |   1 +
 packages/react-native/React/Base/RCTUtils.m   |  12 +-
 packages/react-native/index.js                |   4 +
 .../react-native/scripts/react_native_pods.rb |   1 +
 .../visionos_modules/NativeWindowManager.js   |  24 ++
 .../specs/visionos_modules/NativeXRModule.js  |   9 +-
 packages/react-native/types/index.d.ts        |   1 +
 packages/rn-tester/Podfile.lock               | 403 +++++++++++++-----
 .../rn-tester/RNTester-visionOS/App.swift     |   8 +-
 packages/rn-tester/js/RNTesterApp.ios.js      |   3 +
 .../js/examples/SecondWindow/SecondWindow.js  |  52 +++
 .../rn-tester/js/examples/XR/XRExample.js     |  28 +-
 32 files changed, 850 insertions(+), 163 deletions(-)
 create mode 100644 packages/react-native/Libraries/SwiftExtensions/RCTReactContext.swift
 create mode 100644 packages/react-native/Libraries/SwiftExtensions/RCTWindow.swift
 create mode 100644 packages/react-native/Libraries/WindowManager/NativeWindowManager.js
 create mode 100644 packages/react-native/Libraries/WindowManager/RCTWindowManager.h
 create mode 100644 packages/react-native/Libraries/WindowManager/RCTWindowManager.mm
 create mode 100644 packages/react-native/Libraries/WindowManager/WindowManager.d.ts
 create mode 100644 packages/react-native/Libraries/WindowManager/WindowManager.js
 create mode 100644 packages/react-native/src/private/specs/visionos_modules/NativeWindowManager.js
 create mode 100644 packages/rn-tester/js/examples/SecondWindow/SecondWindow.js

diff --git a/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.h b/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.h
index d61c3d115e3044..62ceaaa5db26ae 100644
--- a/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.h
+++ b/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.h
@@ -58,7 +58,9 @@ NS_ASSUME_NONNULL_BEGIN
 
 /// The window object, used to render the UViewControllers
 @property (nonatomic, strong, nonnull) UIWindow *window;
-@property (nonatomic, nullable) RCTBridge *bridge;
+/// Store last focused window to properly handle multi-window scenarios
+@property (nonatomic, weak, nullable) UIWindow *lastFocusedWindow;
+@property (nonatomic, strong, nullable) RCTBridge *bridge;
 @property (nonatomic, strong, nullable) NSString *moduleName;
 @property (nonatomic, strong, nullable) NSDictionary *initialProps;
 @property (nonatomic, strong, nonnull) RCTRootViewFactory *rootViewFactory;
diff --git a/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.mm b/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.mm
index 43202046cf37d3..8cbc5add3f2990 100644
--- a/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.mm
+++ b/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.mm
@@ -84,7 +84,11 @@ - (UIView *)createRootViewWithBridge:(RCTBridge *)bridge
   BOOL enableFabric = self.fabricEnabled;
   UIView *rootView = RCTAppSetupDefaultRootView(bridge, moduleName, initProps, enableFabric);
 
+#if TARGET_OS_VISION
+  rootView.backgroundColor = [UIColor clearColor];
+#else
   rootView.backgroundColor = [UIColor systemBackgroundColor];
+#endif
 
   return rootView;
 }
diff --git a/packages/react-native/Libraries/AppDelegate/RCTRootViewFactory.mm b/packages/react-native/Libraries/AppDelegate/RCTRootViewFactory.mm
index e8ebdefba1dc7e..fc39fecdc8a2fa 100644
--- a/packages/react-native/Libraries/AppDelegate/RCTRootViewFactory.mm
+++ b/packages/react-native/Libraries/AppDelegate/RCTRootViewFactory.mm
@@ -131,6 +131,11 @@ - (UIView *)viewWithModuleName:(NSString *)moduleName
         initWithSurface:surface
         sizeMeasureMode:RCTSurfaceSizeMeasureModeWidthExact | RCTSurfaceSizeMeasureModeHeightExact];
 
+#if TARGET_OS_VISION
+    surfaceHostingProxyRootView.backgroundColor = [UIColor clearColor];
+#else
+    surfaceHostingProxyRootView.backgroundColor = [UIColor systemBackgroundColor];
+#endif
     return surfaceHostingProxyRootView;
   }
 
@@ -156,7 +161,11 @@ - (UIView *)createRootViewWithBridge:(RCTBridge *)bridge
   BOOL enableFabric = self->_configuration.fabricEnabled;
   UIView *rootView = RCTAppSetupDefaultRootView(bridge, moduleName, initProps, enableFabric);
 
+#if TARGET_OS_VISION
+  rootView.backgroundColor = [UIColor clearColor];
+#else
   rootView.backgroundColor = [UIColor systemBackgroundColor];
+#endif
 
   return rootView;
 }
diff --git a/packages/react-native/Libraries/SwiftExtensions/RCTMainWindow.swift b/packages/react-native/Libraries/SwiftExtensions/RCTMainWindow.swift
index 1bf0bca5901b63..bbf3a3c203252e 100644
--- a/packages/react-native/Libraries/SwiftExtensions/RCTMainWindow.swift
+++ b/packages/react-native/Libraries/SwiftExtensions/RCTMainWindow.swift
@@ -15,8 +15,8 @@ import SwiftUI
  }
  ```
  
- Note: If you want to create additional windows in your app, create a new `WindowGroup {}` and pass it a `RCTRootViewRepresentable`.
-*/
+ Note: If you want to create additional windows in your app, use `RCTWindow()`.
+ */
 public struct RCTMainWindow: Scene {
   var moduleName: String
   var initialProps: RCTRootViewRepresentable.InitialPropsType
@@ -29,6 +29,55 @@ public struct RCTMainWindow: Scene {
   public var body: some Scene {
     WindowGroup {
       RCTRootViewRepresentable(moduleName: moduleName, initialProps: initialProps)
+        .modifier(WindowHandlingModifier())
+    }
+  }
+}
+
+/**
+ Handles data sharing between React Native and SwiftUI views.
+ */
+struct WindowHandlingModifier: ViewModifier {
+  typealias UserInfoType = Dictionary<String, AnyHashable>
+  
+  @Environment(\.reactContext) private var reactContext
+  @Environment(\.openWindow) private var openWindow
+  @Environment(\.dismissWindow) private var dismissWindow
+  @Environment(\.supportsMultipleWindows) private var supportsMultipleWindows
+  
+  func body(content: Content) -> some View {
+    // Attach listeners only if app supports multiple windows
+    if supportsMultipleWindows {
+      content
+        .onReceive(NotificationCenter.default.publisher(for: NSNotification.Name("RCTOpenWindow"))) { data in
+          guard let id = data.userInfo?["id"] as? String else { return }
+          reactContext.scenes.updateValue(RCTSceneData(id: id, props: data.userInfo?["userInfo"] as? UserInfoType), forKey: id)
+          openWindow(id: id)
+        }
+        .onReceive(NotificationCenter.default.publisher(for: NSNotification.Name("RCTUpdateWindow"))) { data in
+          guard
+            let id = data.userInfo?["id"] as? String,
+            let userInfo = data.userInfo?["userInfo"] as? UserInfoType else { return }
+          reactContext.scenes[id]?.props = userInfo
+        }
+        .onReceive(NotificationCenter.default.publisher(for: NSNotification.Name("RCTDismissWindow"))) { data in
+          guard let id = data.userInfo?["id"] as? String else { return }
+          dismissWindow(id: id)
+          reactContext.scenes.removeValue(forKey: id)
+        }
+        .onReceive(NotificationCenter.default.publisher(for: NSNotification.Name("RCTOpenImmersiveSpace"))) { data in
+          guard let id = data.userInfo?["id"] as? String else { return }
+          reactContext.scenes.updateValue(
+            RCTSceneData(id: id, props: data.userInfo?["userInfo"] as? UserInfoType),
+            forKey: id
+          )
+        }
+        .onReceive(NotificationCenter.default.publisher(for: NSNotification.Name("RCTDismissImmersiveSpace"))) { data in
+          guard let id = data.userInfo?["id"] as? String else { return }
+          reactContext.scenes.removeValue(forKey: id)
+        }
+    } else {
+      content
     }
   }
 }
diff --git a/packages/react-native/Libraries/SwiftExtensions/RCTReactContext.swift b/packages/react-native/Libraries/SwiftExtensions/RCTReactContext.swift
new file mode 100644
index 00000000000000..4f5c3b3738b0e7
--- /dev/null
+++ b/packages/react-native/Libraries/SwiftExtensions/RCTReactContext.swift
@@ -0,0 +1,45 @@
+import SwiftUI
+import Observation
+
+@Observable
+public class RCTSceneData: Identifiable {
+  public var id: String
+  public var props: Dictionary<String, AnyHashable>?
+  
+  init(id: String, props: Dictionary<String, AnyHashable>?) {
+    self.id = id
+    self.props = props
+  }
+}
+
+extension RCTSceneData: Equatable {
+  public static func == (lhs: RCTSceneData, rhs: RCTSceneData) -> Bool {
+    lhs.id == rhs.id && NSDictionary(dictionary: lhs.props ?? [:]).isEqual(to: rhs.props ?? [:])
+  }
+}
+
+@Observable
+public class RCTReactContext {
+  public var scenes: Dictionary<String, RCTSceneData> = [:]
+  
+  public func getSceneData(id: String) -> RCTSceneData? {
+    return scenes[id]
+  }
+}
+
+extension RCTReactContext: Equatable {
+  public static func == (lhs: RCTReactContext, rhs: RCTReactContext) -> Bool {
+    NSDictionary(dictionary: lhs.scenes).isEqual(to: rhs.scenes)
+  }
+}
+
+public extension EnvironmentValues {
+  var reactContext: RCTReactContext {
+    get { self[RCTSceneContextKey.self] }
+    set { self[RCTSceneContextKey.self] = newValue }
+  }
+}
+
+private struct RCTSceneContextKey: EnvironmentKey {
+  static var defaultValue: RCTReactContext = RCTReactContext()
+}
diff --git a/packages/react-native/Libraries/SwiftExtensions/RCTReactViewController.h b/packages/react-native/Libraries/SwiftExtensions/RCTReactViewController.h
index 13de19c37cf0e2..aa77150ce21c92 100644
--- a/packages/react-native/Libraries/SwiftExtensions/RCTReactViewController.h
+++ b/packages/react-native/Libraries/SwiftExtensions/RCTReactViewController.h
@@ -13,4 +13,6 @@
 - (instancetype _Nonnull)initWithModuleName:(NSString *_Nonnull)moduleName
                                    initProps:(NSDictionary *_Nullable)initProps;
 
+-(void)updateProps:(NSDictionary *_Nullable)newProps;
+
 @end
diff --git a/packages/react-native/Libraries/SwiftExtensions/RCTRootViewRepresentable.swift b/packages/react-native/Libraries/SwiftExtensions/RCTRootViewRepresentable.swift
index 6a89db9d08e2d7..8a839541ebb8ea 100644
--- a/packages/react-native/Libraries/SwiftExtensions/RCTRootViewRepresentable.swift
+++ b/packages/react-native/Libraries/SwiftExtensions/RCTRootViewRepresentable.swift
@@ -22,11 +22,11 @@ public struct RCTRootViewRepresentable: UIViewControllerRepresentable {
     self.initialProps = initialProps
   }
   
-  public func makeUIViewController(context: Context) -> UIViewController {
+  public func makeUIViewController(context: Context) -> RCTReactViewController {
     RCTReactViewController(moduleName: moduleName, initProps: initialProps)
   }
   
-  public func updateUIViewController(_ uiViewController: UIViewController, context: Context) {
-    // noop
+  public func updateUIViewController(_ uiViewController: RCTReactViewController, context: Context) {
+    uiViewController.updateProps(initialProps)
   }
 }
diff --git a/packages/react-native/Libraries/SwiftExtensions/RCTWindow.swift b/packages/react-native/Libraries/SwiftExtensions/RCTWindow.swift
new file mode 100644
index 00000000000000..12bb37085cd1dd
--- /dev/null
+++ b/packages/react-native/Libraries/SwiftExtensions/RCTWindow.swift
@@ -0,0 +1,45 @@
+import SwiftUI
+import React
+
+/**
+ `RCTWindow` is a SwiftUI struct that returns additional scenes.
+ 
+ Example usage:
+ ```
+ RCTWindow(id: "SecondWindow", sceneData: reactContext.getSceneData(id: "SecondWindow"))
+ ```
+ */
+public struct RCTWindow : Scene {
+  var id: String
+  var sceneData: RCTSceneData?
+  var moduleName: String
+  
+  public init(id: String, moduleName: String, sceneData: RCTSceneData?) {
+    self.id = id
+    self.moduleName = moduleName
+    self.sceneData = sceneData
+  }
+  
+  public var body: some Scene {
+    WindowGroup(id: id) {
+      Group {
+        if let sceneData {
+          RCTRootViewRepresentable(moduleName: moduleName, initialProps: sceneData.props)
+        }
+      }
+      .onAppear {
+        if sceneData == nil {
+          RCTFatal(RCTErrorWithMessage("Passed scene data is nil, make sure to pass sceneContext to RCTWindow() in App.swift"))
+        }
+      }
+    }
+  }
+}
+
+extension RCTWindow {
+  public init(id: String, sceneData: RCTSceneData?) {
+    self.id = id
+    self.moduleName = id
+    self.sceneData = sceneData
+  }
+}
diff --git a/packages/react-native/Libraries/SwiftExtensions/React-RCTSwiftExtensions.podspec b/packages/react-native/Libraries/SwiftExtensions/React-RCTSwiftExtensions.podspec
index 531f1d8172ca7d..9d61b8e4cf31c3 100644
--- a/packages/react-native/Libraries/SwiftExtensions/React-RCTSwiftExtensions.podspec
+++ b/packages/react-native/Libraries/SwiftExtensions/React-RCTSwiftExtensions.podspec
@@ -25,4 +25,5 @@ Pod::Spec.new do |s|
 
   s.dependency "React-Core"
   s.dependency "React-RCTXR" 
+  s.dependency "React-RCTWindowManager" 
 end
diff --git a/packages/react-native/Libraries/WindowManager/NativeWindowManager.js b/packages/react-native/Libraries/WindowManager/NativeWindowManager.js
new file mode 100644
index 00000000000000..a1904df0228866
--- /dev/null
+++ b/packages/react-native/Libraries/WindowManager/NativeWindowManager.js
@@ -0,0 +1,8 @@
+/**
+ * @flow strict
+ * @format
+ */
+
+export * from '../../src/private/specs/visionos_modules/NativeWindowManager';
+import NativeWindowManager from '../../src/private/specs/visionos_modules/NativeWindowManager';
+export default NativeWindowManager;
diff --git a/packages/react-native/Libraries/WindowManager/RCTWindowManager.h b/packages/react-native/Libraries/WindowManager/RCTWindowManager.h
new file mode 100644
index 00000000000000..8d782b1bfe77e7
--- /dev/null
+++ b/packages/react-native/Libraries/WindowManager/RCTWindowManager.h
@@ -0,0 +1,6 @@
+#import <Foundation/Foundation.h>
+#import <React/RCTBridgeModule.h>
+
+@interface RCTWindowManager : NSObject <RCTBridgeModule>
+
+@end
diff --git a/packages/react-native/Libraries/WindowManager/RCTWindowManager.mm b/packages/react-native/Libraries/WindowManager/RCTWindowManager.mm
new file mode 100644
index 00000000000000..3700bceba20b95
--- /dev/null
+++ b/packages/react-native/Libraries/WindowManager/RCTWindowManager.mm
@@ -0,0 +1,90 @@
+#import <React/RCTWindowManager.h>
+
+#import <FBReactNativeSpec_visionOS/FBReactNativeSpec_visionOS.h>
+
+#import <React/RCTBridge.h>
+#import <React/RCTConvert.h>
+#import <React/RCTUtils.h>
+
+// Events
+static NSString *const RCTOpenWindow = @"RCTOpenWindow";
+static NSString *const RCTDismissWindow = @"RCTDismissWindow";
+static NSString *const RCTUpdateWindow = @"RCTUpdateWindow";
+
+@interface RCTWindowManager () <NativeWindowManagerSpec>
+@end
+
+@implementation RCTWindowManager
+
+RCT_EXPORT_MODULE(WindowManager)
+
+RCT_EXPORT_METHOD(openWindow
+                  : (NSString *)windowId userInfo
+                  : (NSDictionary *)userInfo resolve
+                  : (RCTPromiseResolveBlock)resolve reject
+                  : (RCTPromiseRejectBlock)reject)
+{
+  RCTExecuteOnMainQueue(^{
+    if (!RCTSharedApplication().supportsMultipleScenes) {
+      reject(@"ERROR", @"Multiple scenes not supported", nil);
+    }
+    NSMutableDictionary *userInfoDict = [[NSMutableDictionary alloc] init];
+    [userInfoDict setValue:windowId forKey:@"id"];
+    if (userInfo != nil) {
+      [userInfoDict setValue:userInfo forKey:@"userInfo"];
+    }
+    [[NSNotificationCenter defaultCenter] postNotificationName:RCTOpenWindow object:self userInfo:userInfoDict];
+    resolve(nil);
+  });
+}
+
+RCT_EXPORT_METHOD(closeWindow
+                  : (NSString *)windowId resolve
+                  : (RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
+{
+  RCTExecuteOnMainQueue(^{
+    [[NSNotificationCenter defaultCenter] postNotificationName:RCTDismissWindow object:self userInfo:@{@"id": windowId}];
+    resolve(nil);
+  });
+}
+
+RCT_EXPORT_METHOD(updateWindow
+                  : (NSString *)windowId userInfo
+                  : (NSDictionary *)userInfo resolve
+                  : (RCTPromiseResolveBlock)resolve reject
+                  : (RCTPromiseRejectBlock)reject)
+{
+  RCTExecuteOnMainQueue(^{
+    if (!RCTSharedApplication().supportsMultipleScenes) {
+      reject(@"ERROR", @"Multiple scenes not supported", nil);
+    }
+    NSMutableDictionary *userInfoDict = [[NSMutableDictionary alloc] init];
+    [userInfoDict setValue:windowId forKey:@"id"];
+    if (userInfo != nil) {
+      [userInfoDict setValue:userInfo forKey:@"userInfo"];
+    }
+    [[NSNotificationCenter defaultCenter] postNotificationName:RCTUpdateWindow object:self userInfo:userInfoDict];
+    resolve(nil);
+  });
+}
+
+- (facebook::react::ModuleConstants<JS::NativeWindowManager::Constants::Builder>)constantsToExport {
+  return [self getConstants];
+}
+
+- (facebook::react::ModuleConstants<JS::NativeWindowManager::Constants>)getConstants {
+  __block facebook::react::ModuleConstants<JS::NativeWindowManager::Constants> constants;
+  RCTUnsafeExecuteOnMainQueueSync(^{
+    constants = facebook::react::typedConstants<JS::NativeWindowManager::Constants>({
+      .supportsMultipleScenes = RCTSharedApplication().supportsMultipleScenes
+    });
+  });
+  
+  return constants;
+}
+
+- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const facebook::react::ObjCTurboModule::InitParams &)params {
+  return std::make_shared<facebook::react::NativeWindowManagerSpecJSI>(params);
+}
+
+@end
diff --git a/packages/react-native/Libraries/WindowManager/WindowManager.d.ts b/packages/react-native/Libraries/WindowManager/WindowManager.d.ts
new file mode 100644
index 00000000000000..bcdf96c272c21c
--- /dev/null
+++ b/packages/react-native/Libraries/WindowManager/WindowManager.d.ts
@@ -0,0 +1,16 @@
+export interface WindowStatic {
+  id: String;
+  open (props?: Object): Promise<void>;
+  update (props: Object): Promise<void>;
+  close (): Promise<void>;
+}
+
+export interface WindowManagerStatic {
+  getWindow(id: String): Window;
+  supportsMultipleScenes: boolean;
+}
+
+export const WindowManager: WindowManagerStatic;
+export type WindowManager = WindowManagerStatic;
+export const Window: WindowStatic;
+export type Window = WindowStatic;
diff --git a/packages/react-native/Libraries/WindowManager/WindowManager.js b/packages/react-native/Libraries/WindowManager/WindowManager.js
new file mode 100644
index 00000000000000..bb39535a65bb1a
--- /dev/null
+++ b/packages/react-native/Libraries/WindowManager/WindowManager.js
@@ -0,0 +1,63 @@
+/**
+ * @format
+ * @flow strict
+ * @jsdoc
+ */
+
+import NativeWindowManager from './NativeWindowManager';
+
+const WindowManager = {
+  getWindow: function (id: string): Window {
+    return new Window(id);
+  },
+
+  // $FlowIgnore[unsafe-getters-setters]
+  get supportsMultipleScenes(): boolean {
+    if (NativeWindowManager == null) {
+      return false;
+    }
+
+    const nativeConstants = NativeWindowManager.getConstants();
+    return nativeConstants.supportsMultipleScenes || false;
+  },
+};
+
+class Window {
+  id: string;
+
+  constructor(id: string) {
+    this.id = id;
+  }
+
+  // $FlowIgnore[unclear-type]
+  open(props: ?Object): Promise<void> {
+    if (NativeWindowManager != null && NativeWindowManager.openWindow != null) {
+      return NativeWindowManager.openWindow(this.id, props);
+    }
+    return Promise.reject(new Error('NativeWindowManager is not available'));
+  }
+
+  // $FlowIgnore[unclear-type]
+  close(): Promise<void> {
+    if (
+      NativeWindowManager != null &&
+      NativeWindowManager.closeWindow != null
+    ) {
+      return NativeWindowManager.closeWindow(this.id);
+    }
+    return Promise.reject(new Error('NativeWindowManager is not available'));
+  }
+
+  // $FlowIgnore[unclear-type]
+  update(props: ?Object): Promise<void> {
+    if (
+      NativeWindowManager != null &&
+      NativeWindowManager.updateWindow != null
+    ) {
+      return NativeWindowManager.updateWindow(this.id, props);
+    }
+    return Promise.reject(new Error('NativeWindowManager is not available'));
+  }
+}
+
+module.exports = WindowManager;
diff --git a/packages/react-native/Libraries/XR/ImmersiveBridge.swift b/packages/react-native/Libraries/XR/ImmersiveBridge.swift
index 45fdbcf4087b00..43bdfe5b170739 100644
--- a/packages/react-native/Libraries/XR/ImmersiveBridge.swift
+++ b/packages/react-native/Libraries/XR/ImmersiveBridge.swift
@@ -9,6 +9,7 @@ import SwiftUI
 
 public typealias CompletionHandlerType = (_ result: ImmersiveSpaceResult) -> Void
 
+#if os(visionOS)
 /**
  * Utility view used to bridge the gap between SwiftUI environment and UIKit.
  *
@@ -44,12 +45,17 @@ struct ImmersiveBridgeView: View {
       }
   }
 }
+#endif
 
-@objc public class ImmersiveBridgeFactory: NSObject {
+@objc public class SwiftUIBridgeFactory: NSObject {
   @objc public static func makeImmersiveBridgeView(
     spaceId: String,
     completionHandler: @escaping CompletionHandlerType
   ) -> UIViewController {
+#if os(visionOS)
     return UIHostingController(rootView: ImmersiveBridgeView(spaceId: spaceId, completionHandler: completionHandler))
+#else
+    return UIViewController()
+#endif
   }
 }
diff --git a/packages/react-native/Libraries/XR/RCTXRModule.mm b/packages/react-native/Libraries/XR/RCTXRModule.mm
index 8b5db6c7cbd008..f0c600b3a09c99 100644
--- a/packages/react-native/Libraries/XR/RCTXRModule.mm
+++ b/packages/react-native/Libraries/XR/RCTXRModule.mm
@@ -7,11 +7,16 @@
 #import <React/RCTUtils.h>
 #import "RCTXR-Swift.h"
 
+// Events
+static NSString *const RCTOpenImmersiveSpace = @"RCTOpenImmersiveSpace";
+static NSString *const RCTDismissImmersiveSpace = @"RCTDismissImmersiveSpace";
+
 @interface RCTXRModule () <NativeXRModuleSpec>
 @end
 
 @implementation RCTXRModule {
   UIViewController *_immersiveBridgeView;
+  NSString *_currentSessionId;
 }
 
 RCT_EXPORT_MODULE()
@@ -20,28 +25,51 @@ @implementation RCTXRModule {
                   : (RCTPromiseResolveBlock)resolve reject
                   : (RCTPromiseRejectBlock)reject)
 {
-  [self removeImmersiveBridge];
+  [self removeViewController:self->_immersiveBridgeView];
+  self->_immersiveBridgeView = nil;
+  RCTExecuteOnMainQueue(^{
+    if (self->_currentSessionId != nil) {
+      [[NSNotificationCenter defaultCenter] postNotificationName:RCTDismissImmersiveSpace object:self userInfo:@{@"id": self->_currentSessionId}];
+    }
+  });
+  _currentSessionId = nil;
   resolve(nil);
 }
 
 
 RCT_EXPORT_METHOD(requestSession
-                  : (NSString *)sessionId resolve
-                  : (RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
+                  : (NSString *)sessionId userInfo
+                  : (NSDictionary *)userInfo resolve
+                  : (RCTPromiseResolveBlock)resolve reject
+                  : (RCTPromiseRejectBlock)reject)
 {
   RCTExecuteOnMainQueue(^{
+    if (!RCTSharedApplication().supportsMultipleScenes) {
+      reject(@"ERROR", @"Multiple scenes not supported", nil);
+    }
     UIWindow *keyWindow = RCTKeyWindow();
     UIViewController *rootViewController = keyWindow.rootViewController;
     
     if (self->_immersiveBridgeView == nil) {
-      self->_immersiveBridgeView = [ImmersiveBridgeFactory makeImmersiveBridgeViewWithSpaceId:sessionId
+      NSMutableDictionary *userInfoDict = [[NSMutableDictionary alloc] init];
+      [userInfoDict setValue:sessionId forKey:@"id"];
+      if (userInfo != nil) {
+        [userInfoDict setValue:userInfo forKey:@"userInfo"];
+      }
+      NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
+          [notificationCenter postNotificationName:RCTOpenImmersiveSpace object:self userInfo:userInfoDict];
+      self->_currentSessionId = sessionId;
+      
+      self->_immersiveBridgeView = [SwiftUIBridgeFactory makeImmersiveBridgeViewWithSpaceId:sessionId
                                                                             completionHandler:^(enum ImmersiveSpaceResult result){
         if (result == ImmersiveSpaceResultError) {
           reject(@"ERROR", @"Immersive Space failed to open, the system cannot fulfill the request.", nil);
-          [self removeImmersiveBridge];
+          [self removeViewController:self->_immersiveBridgeView];
+          self->_immersiveBridgeView = nil;
         } else if (result == ImmersiveSpaceResultUserCancelled) {
           reject(@"ERROR", @"Immersive Space canceled by user", nil);
-          [self removeImmersiveBridge];
+          [self removeViewController:self->_immersiveBridgeView];
+          self->_immersiveBridgeView = nil;
         } else if (result == ImmersiveSpaceResultOpened) {
           resolve(nil);
         }
@@ -56,28 +84,13 @@ @implementation RCTXRModule {
   });
 }
 
-- (facebook::react::ModuleConstants<JS::NativeXRModule::Constants::Builder>)constantsToExport {
-  return [self getConstants];
-}
-
-- (facebook::react::ModuleConstants<JS::NativeXRModule::Constants>)getConstants {
-  __block facebook::react::ModuleConstants<JS::NativeXRModule::Constants> constants;
-  RCTUnsafeExecuteOnMainQueueSync(^{
-    constants = facebook::react::typedConstants<JS::NativeXRModule::Constants>({
-      .supportsMultipleScenes = RCTSharedApplication().supportsMultipleScenes
-    });
-  });
-  
-  return constants;
-}
 
-- (void) removeImmersiveBridge
+- (void)removeViewController:(UIViewController*)viewController
 {
   RCTExecuteOnMainQueue(^{
-    [self->_immersiveBridgeView willMoveToParentViewController:nil];
-    [self->_immersiveBridgeView.view removeFromSuperview];
-    [self->_immersiveBridgeView removeFromParentViewController];
-    self->_immersiveBridgeView = nil;
+    [viewController willMoveToParentViewController:nil];
+    [viewController.view removeFromSuperview];
+    [viewController removeFromParentViewController];
   });
 }
 
diff --git a/packages/react-native/Libraries/XR/XR.d.ts b/packages/react-native/Libraries/XR/XR.d.ts
index 11d397a4ebde34..293a97bb084c3e 100644
--- a/packages/react-native/Libraries/XR/XR.d.ts
+++ b/packages/react-native/Libraries/XR/XR.d.ts
@@ -1,8 +1,7 @@
 
 export interface XRStatic {
-  requestSession(sessionId: string): Promise<void>;
+  requestSession(sessionId: string, userInfo: Object): Promise<void>;
   endSession(): Promise<void>;
-  supportsMultipleScenes: boolean;
 }
 
 export const XR: XRStatic;
diff --git a/packages/react-native/Libraries/XR/XR.js b/packages/react-native/Libraries/XR/XR.js
index 3487429aff1bb5..923a3184c71dea 100644
--- a/packages/react-native/Libraries/XR/XR.js
+++ b/packages/react-native/Libraries/XR/XR.js
@@ -7,9 +7,10 @@
 import NativeXRModule from './NativeXRModule';
 
 const XR = {
-  requestSession: (sessionId?: string): Promise<void> => {
+  // $FlowIgnore[unclear-type]
+  requestSession: (sessionId: string, userInfo: ?Object): Promise<void> => {
     if (NativeXRModule != null && NativeXRModule.requestSession != null) {
-      return NativeXRModule.requestSession(sessionId);
+      return NativeXRModule.requestSession(sessionId, userInfo);
     }
     return Promise.reject(new Error('NativeXRModule is not available'));
   },
@@ -19,15 +20,6 @@ const XR = {
     }
     return Promise.reject(new Error('NativeXRModule is not available'));
   },
-  // $FlowIgnore[unsafe-getters-setters]
-  get supportsMultipleScenes(): boolean {
-    if (NativeXRModule == null) {
-      return false;
-    }
-
-    const nativeConstants = NativeXRModule.getConstants();
-    return nativeConstants.supportsMultipleScenes || false;
-  },
 };
 
 module.exports = XR;
diff --git a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap
index 30c776f1a6d006..952c7998b448e1 100644
--- a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap
+++ b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap
@@ -8922,6 +8922,28 @@ exports[`public API should not change unintentionally Libraries/WebSocket/WebSoc
 
 exports[`public API should not change unintentionally Libraries/WebSocket/WebSocketInterceptor.js 1`] = `"UNTYPED MODULE"`;
 
+exports[`public API should not change unintentionally Libraries/WindowManager/NativeWindowManager.js 1`] = `
+"export * from \\"../../src/private/specs/visionos_modules/NativeWindowManager\\";
+declare export default typeof NativeWindowManager;
+"
+`;
+
+exports[`public API should not change unintentionally Libraries/WindowManager/WindowManager.js 1`] = `
+"declare const WindowManager: {
+  getWindow: (id: string) => Window,
+  get supportsMultipleScenes(): boolean,
+};
+declare class Window {
+  id: string;
+  constructor(id: string): void;
+  open(props: ?Object): Promise<void>;
+  close(): Promise<void>;
+  update(props: ?Object): Promise<void>;
+}
+declare module.exports: WindowManager;
+"
+`;
+
 exports[`public API should not change unintentionally Libraries/XR/NativeXRModule.js 1`] = `
 "export * from \\"../../src/private/specs/visionos_modules/NativeXRModule\\";
 declare export default typeof NativeXRModule;
@@ -8930,9 +8952,8 @@ declare export default typeof NativeXRModule;
 
 exports[`public API should not change unintentionally Libraries/XR/XR.js 1`] = `
 "declare const XR: {
-  requestSession: (sessionId?: string) => Promise<void>,
+  requestSession: (sessionId: string, userInfo: ?Object) => Promise<void>,
   endSession: () => Promise<void>,
-  get supportsMultipleScenes(): boolean,
 };
 declare module.exports: XR;
 "
@@ -9057,6 +9078,7 @@ declare module.exports: {
   get Settings(): Settings,
   get Share(): Share,
   get XR(): XR,
+  get WindowManager(): WindowManager,
   get StyleSheet(): StyleSheet,
   get Systrace(): Systrace,
   get ToastAndroid(): ToastAndroid,
diff --git a/packages/react-native/React-Core.podspec b/packages/react-native/React-Core.podspec
index 9433decb19dfb9..b9a250841cd8ca 100644
--- a/packages/react-native/React-Core.podspec
+++ b/packages/react-native/React-Core.podspec
@@ -38,6 +38,7 @@ header_subspecs = {
   'RCTTextHeaders'              => 'Libraries/Text/**/*.h',
   'RCTVibrationHeaders'         => 'Libraries/Vibration/*.h',
   'RCTXRHeaders'                => 'Libraries/XR/*.h',
+  'RCTWindowManagerHeaders'     => 'Libraries/WindowManager/*.h',
 }
 
 frameworks_search_paths = []
diff --git a/packages/react-native/React.podspec b/packages/react-native/React.podspec
index 2d085e63040906..50397b11182021 100644
--- a/packages/react-native/React.podspec
+++ b/packages/react-native/React.podspec
@@ -54,4 +54,5 @@ Pod::Spec.new do |s|
   s.dependency "React-RCTText", version
   s.dependency "React-RCTVibration", version
   s.dependency "React-RCTXR", version
+  s.dependency "React-RCTWindowManager", version
 end
diff --git a/packages/react-native/React/Base/RCTUtils.m b/packages/react-native/React/Base/RCTUtils.m
index 866016b4729b32..03b2dae31bdc43 100644
--- a/packages/react-native/React/Base/RCTUtils.m
+++ b/packages/react-native/React/Base/RCTUtils.m
@@ -566,7 +566,17 @@ BOOL RCTRunningInAppExtension(void)
   if (RCTRunningInAppExtension()) {
     return nil;
   }
-
+  
+  id<UIApplicationDelegate> delegate = RCTSharedApplication().delegate;
+  
+  SEL lastFocusedWindowSelector = NSSelectorFromString(@"lastFocusedWindow");
+  if ([delegate respondsToSelector:lastFocusedWindowSelector]) {
+    UIWindow *lastFocusedWindow = [delegate performSelector:lastFocusedWindowSelector];
+    if (lastFocusedWindow) {
+      return lastFocusedWindow;
+    }
+  }
+  
   for (UIScene *scene in RCTSharedApplication().connectedScenes) {
     if (scene.activationState != UISceneActivationStateForegroundActive ||
         ![scene isKindOfClass:[UIWindowScene class]]) {
diff --git a/packages/react-native/index.js b/packages/react-native/index.js
index 555cf263a3019a..02b5377f43ed11 100644
--- a/packages/react-native/index.js
+++ b/packages/react-native/index.js
@@ -90,6 +90,7 @@ import typeof Platform from './Libraries/Utilities/Platform';
 import typeof useColorScheme from './Libraries/Utilities/useColorScheme';
 import typeof useWindowDimensions from './Libraries/Utilities/useWindowDimensions';
 import typeof Vibration from './Libraries/Vibration/Vibration';
+import typeof WindowManager from './Libraries/WindowManager/WindowManager';
 import typeof XR from './Libraries/XR/XR';
 import typeof YellowBox from './Libraries/YellowBox/YellowBoxDeprecated';
 
@@ -304,6 +305,9 @@ module.exports = {
   get XR(): XR {
     return require('./Libraries/XR/XR');
   },
+  get WindowManager(): WindowManager {
+    return require('./Libraries/WindowManager/WindowManager');
+  },
   get StyleSheet(): StyleSheet {
     return require('./Libraries/StyleSheet/StyleSheet');
   },
diff --git a/packages/react-native/scripts/react_native_pods.rb b/packages/react-native/scripts/react_native_pods.rb
index 464eb81d03147b..b8e3d3efd08bc2 100644
--- a/packages/react-native/scripts/react_native_pods.rb
+++ b/packages/react-native/scripts/react_native_pods.rb
@@ -135,6 +135,7 @@ def use_react_native! (
   pod 'RCTDeprecation', :path => "#{prefix}/ReactApple/Libraries/RCTFoundation/RCTDeprecation"
   pod 'React-RCTSwiftExtensions', :path => "#{prefix}/Libraries/SwiftExtensions"
   pod 'React-RCTXR', :path => "#{prefix}/Libraries/XR"
+  pod 'React-RCTWindowManager', :path => "#{prefix}/Libraries/WindowManager", :modular_headers => true
 
   if hermes_enabled
     setup_hermes!(:react_native_path => prefix)
diff --git a/packages/react-native/src/private/specs/visionos_modules/NativeWindowManager.js b/packages/react-native/src/private/specs/visionos_modules/NativeWindowManager.js
new file mode 100644
index 00000000000000..db0332702236c4
--- /dev/null
+++ b/packages/react-native/src/private/specs/visionos_modules/NativeWindowManager.js
@@ -0,0 +1,24 @@
+/**
+ * @flow strict
+ * @format
+ */
+
+import type {TurboModule} from '../../../../Libraries/TurboModule/RCTExport';
+
+import * as TurboModuleRegistry from '../../../../Libraries/TurboModule/TurboModuleRegistry';
+
+export type WindowManagerConstants = {|
+  +supportsMultipleScenes?: boolean,
+|};
+
+export interface Spec extends TurboModule {
+  +getConstants: () => WindowManagerConstants;
+
+  // $FlowIgnore[unclear-type]
+  +openWindow: (windowId: string, userInfo: Object) => Promise<void>;
+  // $FlowIgnore[unclear-type]
+  +updateWindow: (windowId: string, userInfo: Object) => Promise<void>;
+  +closeWindow: (windowId: string) => Promise<void>;
+}
+
+export default (TurboModuleRegistry.get<Spec>('WindowManager'): ?Spec);
diff --git a/packages/react-native/src/private/specs/visionos_modules/NativeXRModule.js b/packages/react-native/src/private/specs/visionos_modules/NativeXRModule.js
index ce8d22dca68c49..f96c2a84a48ac4 100644
--- a/packages/react-native/src/private/specs/visionos_modules/NativeXRModule.js
+++ b/packages/react-native/src/private/specs/visionos_modules/NativeXRModule.js
@@ -7,14 +7,9 @@ import type {TurboModule} from '../../../../Libraries/TurboModule/RCTExport';
 
 import * as TurboModuleRegistry from '../../../../Libraries/TurboModule/TurboModuleRegistry';
 
-export type XRModuleConstants = {|
-  +supportsMultipleScenes?: boolean,
-|};
-
 export interface Spec extends TurboModule {
-  +getConstants: () => XRModuleConstants;
-
-  +requestSession: (sessionId?: string) => Promise<void>;
+  // $FlowIgnore[unclear-type]
+  +requestSession: (sessionId?: string, userInfo: Object) => Promise<void>;
   +endSession: () => Promise<void>;
 }
 
diff --git a/packages/react-native/types/index.d.ts b/packages/react-native/types/index.d.ts
index 917b5cc65d098d..5c89c19b97c707 100644
--- a/packages/react-native/types/index.d.ts
+++ b/packages/react-native/types/index.d.ts
@@ -148,6 +148,7 @@ export * from '../Libraries/Utilities/PixelRatio';
 export * from '../Libraries/Utilities/Platform';
 export * from '../Libraries/Vibration/Vibration';
 export * from '../Libraries/XR/XR';
+export * from '../Libraries/WindowManager/WindowManager';
 export * from '../Libraries/YellowBox/YellowBoxDeprecated';
 export * from '../Libraries/vendor/core/ErrorUtils';
 export {
diff --git a/packages/rn-tester/Podfile.lock b/packages/rn-tester/Podfile.lock
index 676ad01127ab66..5bd7e46f4c1758 100644
--- a/packages/rn-tester/Podfile.lock
+++ b/packages/rn-tester/Podfile.lock
@@ -5,51 +5,55 @@ PODS:
   - fmt (9.1.0)
   - glog (0.3.5)
   - hermes-engine (1000.0.0):
+    - hermes-engine/cdp (= 1000.0.0)
     - hermes-engine/Hermes (= 1000.0.0)
     - hermes-engine/inspector (= 1000.0.0)
     - hermes-engine/inspector_chrome (= 1000.0.0)
     - hermes-engine/Public (= 1000.0.0)
+  - hermes-engine/cdp (1000.0.0)
   - hermes-engine/Hermes (1000.0.0)
   - hermes-engine/inspector (1000.0.0)
   - hermes-engine/inspector_chrome (1000.0.0)
   - hermes-engine/Public (1000.0.0)
-  - MyNativeView (0.0.1):
+  - MyNativeView (0.75.0-main):
     - DoubleConversion
     - glog
     - hermes-engine
     - RCT-Folly (= 2024.01.01.00)
     - RCTRequired
     - RCTTypeSafety
-    - React-Codegen
     - React-Core
     - React-debug
     - React-Fabric
+    - React-featureflags
     - React-graphics
     - React-ImageManager
     - React-NativeModulesApple
     - React-RCTFabric
     - React-rendererdebug
     - React-utils
+    - ReactCodegen
     - ReactCommon/turbomodule/bridging
     - ReactCommon/turbomodule/core
     - Yoga
-  - NativeCxxModuleExample (0.0.1):
+  - NativeCxxModuleExample (0.75.0-main):
     - DoubleConversion
     - glog
     - hermes-engine
     - RCT-Folly (= 2024.01.01.00)
     - RCTRequired
     - RCTTypeSafety
-    - React-Codegen
     - React-Core
     - React-debug
     - React-Fabric
+    - React-featureflags
     - React-graphics
     - React-ImageManager
     - React-NativeModulesApple
     - React-RCTFabric
     - React-rendererdebug
     - React-utils
+    - ReactCodegen
     - ReactCommon/turbomodule/bridging
     - ReactCommon/turbomodule/core
     - Yoga
@@ -89,27 +93,9 @@ PODS:
     - React-RCTSettings (= 1000.0.0)
     - React-RCTText (= 1000.0.0)
     - React-RCTVibration (= 1000.0.0)
+    - React-RCTWindowManager (= 1000.0.0)
     - React-RCTXR (= 1000.0.0)
   - React-callinvoker (1000.0.0)
-  - React-Codegen (1000.0.0):
-    - DoubleConversion
-    - glog
-    - hermes-engine
-    - RCT-Folly
-    - RCTRequired
-    - RCTTypeSafety
-    - React-Core
-    - React-debug
-    - React-Fabric
-    - React-FabricImage
-    - React-graphics
-    - React-jsi
-    - React-jsiexecutor
-    - React-NativeModulesApple
-    - React-rendererdebug
-    - React-utils
-    - ReactCommon/turbomodule/bridging
-    - ReactCommon/turbomodule/core
   - React-Core (1000.0.0):
     - glog
     - hermes-engine
@@ -117,9 +103,11 @@ PODS:
     - RCTDeprecation
     - React-Core/Default (= 1000.0.0)
     - React-cxxreact
+    - React-featureflags
     - React-hermes
     - React-jsi
     - React-jsiexecutor
+    - React-jsinspector
     - React-perflogger
     - React-runtimescheduler
     - React-utils
@@ -132,9 +120,11 @@ PODS:
     - RCTDeprecation
     - React-Core/Default
     - React-cxxreact
+    - React-featureflags
     - React-hermes
     - React-jsi
     - React-jsiexecutor
+    - React-jsinspector
     - React-perflogger
     - React-runtimescheduler
     - React-utils
@@ -146,10 +136,11 @@ PODS:
     - RCT-Folly (= 2024.01.01.00)
     - RCTDeprecation
     - React-cxxreact
+    - React-featureflags
     - React-hermes
     - React-jsi
     - React-jsiexecutor
-    - React-jsinspector (= 1000.0.0)
+    - React-jsinspector
     - React-perflogger
     - React-runtimescheduler
     - React-utils
@@ -163,10 +154,11 @@ PODS:
     - React-Core/Default (= 1000.0.0)
     - React-Core/RCTWebSocket (= 1000.0.0)
     - React-cxxreact
+    - React-featureflags
     - React-hermes
     - React-jsi
     - React-jsiexecutor
-    - React-jsinspector (= 1000.0.0)
+    - React-jsinspector
     - React-perflogger
     - React-runtimescheduler
     - React-utils
@@ -179,9 +171,11 @@ PODS:
     - RCTDeprecation
     - React-Core/Default
     - React-cxxreact
+    - React-featureflags
     - React-hermes
     - React-jsi
     - React-jsiexecutor
+    - React-jsinspector
     - React-perflogger
     - React-runtimescheduler
     - React-utils
@@ -194,9 +188,11 @@ PODS:
     - RCTDeprecation
     - React-Core/Default
     - React-cxxreact
+    - React-featureflags
     - React-hermes
     - React-jsi
     - React-jsiexecutor
+    - React-jsinspector
     - React-perflogger
     - React-runtimescheduler
     - React-utils
@@ -209,9 +205,11 @@ PODS:
     - RCTDeprecation
     - React-Core/Default
     - React-cxxreact
+    - React-featureflags
     - React-hermes
     - React-jsi
     - React-jsiexecutor
+    - React-jsinspector
     - React-perflogger
     - React-runtimescheduler
     - React-utils
@@ -224,9 +222,11 @@ PODS:
     - RCTDeprecation
     - React-Core/Default
     - React-cxxreact
+    - React-featureflags
     - React-hermes
     - React-jsi
     - React-jsiexecutor
+    - React-jsinspector
     - React-perflogger
     - React-runtimescheduler
     - React-utils
@@ -239,9 +239,11 @@ PODS:
     - RCTDeprecation
     - React-Core/Default
     - React-cxxreact
+    - React-featureflags
     - React-hermes
     - React-jsi
     - React-jsiexecutor
+    - React-jsinspector
     - React-perflogger
     - React-runtimescheduler
     - React-utils
@@ -254,9 +256,11 @@ PODS:
     - RCTDeprecation
     - React-Core/Default
     - React-cxxreact
+    - React-featureflags
     - React-hermes
     - React-jsi
     - React-jsiexecutor
+    - React-jsinspector
     - React-perflogger
     - React-runtimescheduler
     - React-utils
@@ -269,9 +273,11 @@ PODS:
     - RCTDeprecation
     - React-Core/Default
     - React-cxxreact
+    - React-featureflags
     - React-hermes
     - React-jsi
     - React-jsiexecutor
+    - React-jsinspector
     - React-perflogger
     - React-runtimescheduler
     - React-utils
@@ -284,9 +290,11 @@ PODS:
     - RCTDeprecation
     - React-Core/Default
     - React-cxxreact
+    - React-featureflags
     - React-hermes
     - React-jsi
     - React-jsiexecutor
+    - React-jsinspector
     - React-perflogger
     - React-runtimescheduler
     - React-utils
@@ -299,9 +307,11 @@ PODS:
     - RCTDeprecation
     - React-Core/Default
     - React-cxxreact
+    - React-featureflags
     - React-hermes
     - React-jsi
     - React-jsiexecutor
+    - React-jsinspector
     - React-perflogger
     - React-runtimescheduler
     - React-utils
@@ -314,9 +324,11 @@ PODS:
     - RCTDeprecation
     - React-Core/Default
     - React-cxxreact
+    - React-featureflags
     - React-hermes
     - React-jsi
     - React-jsiexecutor
+    - React-jsinspector
     - React-perflogger
     - React-runtimescheduler
     - React-utils
@@ -329,9 +341,28 @@ PODS:
     - RCTDeprecation
     - React-Core/Default (= 1000.0.0)
     - React-cxxreact
+    - React-featureflags
+    - React-hermes
+    - React-jsi
+    - React-jsiexecutor
+    - React-jsinspector
+    - React-perflogger
+    - React-runtimescheduler
+    - React-utils
+    - SocketRocket (= 0.7.0.1)
+    - Yoga
+  - React-Core/RCTWindowManagerHeaders (1000.0.0):
+    - glog
+    - hermes-engine
+    - RCT-Folly (= 2024.01.01.00)
+    - RCTDeprecation
+    - React-Core/Default
+    - React-cxxreact
+    - React-featureflags
     - React-hermes
     - React-jsi
     - React-jsiexecutor
+    - React-jsinspector
     - React-perflogger
     - React-runtimescheduler
     - React-utils
@@ -344,23 +375,28 @@ PODS:
     - RCTDeprecation
     - React-Core/Default
     - React-cxxreact
+    - React-featureflags
     - React-hermes
     - React-jsi
     - React-jsiexecutor
+    - React-jsinspector
     - React-perflogger
     - React-runtimescheduler
     - React-utils
     - SocketRocket (= 0.7.0.1)
     - Yoga
   - React-CoreModules (1000.0.0):
+    - DoubleConversion
+    - fmt (= 9.1.0)
     - RCT-Folly (= 2024.01.01.00)
     - RCTTypeSafety (= 1000.0.0)
-    - React-Codegen
     - React-Core/CoreModulesHeaders (= 1000.0.0)
     - React-jsi (= 1000.0.0)
+    - React-jsinspector
     - React-NativeModulesApple
     - React-RCTBlob
     - React-RCTImage (= 1000.0.0)
+    - ReactCodegen
     - ReactCommon
     - SocketRocket (= 0.7.0.1)
   - React-cxxreact (1000.0.0):
@@ -373,7 +409,7 @@ PODS:
     - React-callinvoker (= 1000.0.0)
     - React-debug (= 1000.0.0)
     - React-jsi (= 1000.0.0)
-    - React-jsinspector (= 1000.0.0)
+    - React-jsinspector
     - React-logger (= 1000.0.0)
     - React-perflogger (= 1000.0.0)
     - React-runtimeexecutor (= 1000.0.0)
@@ -403,6 +439,7 @@ PODS:
     - React-Fabric/templateprocessor (= 1000.0.0)
     - React-Fabric/textlayoutmanager (= 1000.0.0)
     - React-Fabric/uimanager (= 1000.0.0)
+    - React-featureflags
     - React-graphics
     - React-jsi
     - React-jsiexecutor
@@ -422,6 +459,7 @@ PODS:
     - React-Core
     - React-cxxreact
     - React-debug
+    - React-featureflags
     - React-graphics
     - React-jsi
     - React-jsiexecutor
@@ -441,6 +479,7 @@ PODS:
     - React-Core
     - React-cxxreact
     - React-debug
+    - React-featureflags
     - React-graphics
     - React-jsi
     - React-jsiexecutor
@@ -460,6 +499,7 @@ PODS:
     - React-Core
     - React-cxxreact
     - React-debug
+    - React-featureflags
     - React-graphics
     - React-jsi
     - React-jsiexecutor
@@ -479,6 +519,7 @@ PODS:
     - React-Core
     - React-cxxreact
     - React-debug
+    - React-featureflags
     - React-graphics
     - React-jsi
     - React-jsiexecutor
@@ -499,6 +540,7 @@ PODS:
     - React-cxxreact
     - React-debug
     - React-Fabric/components/inputaccessory (= 1000.0.0)
+    - React-Fabric/components/iostextinput (= 1000.0.0)
     - React-Fabric/components/legacyviewmanagerinterop (= 1000.0.0)
     - React-Fabric/components/modal (= 1000.0.0)
     - React-Fabric/components/rncore (= 1000.0.0)
@@ -509,6 +551,7 @@ PODS:
     - React-Fabric/components/textinput (= 1000.0.0)
     - React-Fabric/components/unimplementedview (= 1000.0.0)
     - React-Fabric/components/view (= 1000.0.0)
+    - React-featureflags
     - React-graphics
     - React-jsi
     - React-jsiexecutor
@@ -528,6 +571,27 @@ PODS:
     - React-Core
     - React-cxxreact
     - React-debug
+    - React-featureflags
+    - React-graphics
+    - React-jsi
+    - React-jsiexecutor
+    - React-logger
+    - React-rendererdebug
+    - React-runtimescheduler
+    - React-utils
+    - ReactCommon/turbomodule/core
+  - React-Fabric/components/iostextinput (1000.0.0):
+    - DoubleConversion
+    - fmt (= 9.1.0)
+    - glog
+    - hermes-engine
+    - RCT-Folly/Fabric (= 2024.01.01.00)
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-cxxreact
+    - React-debug
+    - React-featureflags
     - React-graphics
     - React-jsi
     - React-jsiexecutor
@@ -547,6 +611,7 @@ PODS:
     - React-Core
     - React-cxxreact
     - React-debug
+    - React-featureflags
     - React-graphics
     - React-jsi
     - React-jsiexecutor
@@ -566,6 +631,7 @@ PODS:
     - React-Core
     - React-cxxreact
     - React-debug
+    - React-featureflags
     - React-graphics
     - React-jsi
     - React-jsiexecutor
@@ -585,6 +651,7 @@ PODS:
     - React-Core
     - React-cxxreact
     - React-debug
+    - React-featureflags
     - React-graphics
     - React-jsi
     - React-jsiexecutor
@@ -604,6 +671,7 @@ PODS:
     - React-Core
     - React-cxxreact
     - React-debug
+    - React-featureflags
     - React-graphics
     - React-jsi
     - React-jsiexecutor
@@ -623,6 +691,7 @@ PODS:
     - React-Core
     - React-cxxreact
     - React-debug
+    - React-featureflags
     - React-graphics
     - React-jsi
     - React-jsiexecutor
@@ -642,6 +711,7 @@ PODS:
     - React-Core
     - React-cxxreact
     - React-debug
+    - React-featureflags
     - React-graphics
     - React-jsi
     - React-jsiexecutor
@@ -661,6 +731,7 @@ PODS:
     - React-Core
     - React-cxxreact
     - React-debug
+    - React-featureflags
     - React-graphics
     - React-jsi
     - React-jsiexecutor
@@ -680,6 +751,7 @@ PODS:
     - React-Core
     - React-cxxreact
     - React-debug
+    - React-featureflags
     - React-graphics
     - React-jsi
     - React-jsiexecutor
@@ -699,6 +771,7 @@ PODS:
     - React-Core
     - React-cxxreact
     - React-debug
+    - React-featureflags
     - React-graphics
     - React-jsi
     - React-jsiexecutor
@@ -718,6 +791,7 @@ PODS:
     - React-Core
     - React-cxxreact
     - React-debug
+    - React-featureflags
     - React-graphics
     - React-jsi
     - React-jsiexecutor
@@ -738,6 +812,7 @@ PODS:
     - React-Core
     - React-cxxreact
     - React-debug
+    - React-featureflags
     - React-graphics
     - React-jsi
     - React-jsiexecutor
@@ -757,6 +832,7 @@ PODS:
     - React-Core
     - React-cxxreact
     - React-debug
+    - React-featureflags
     - React-graphics
     - React-jsi
     - React-jsiexecutor
@@ -776,6 +852,7 @@ PODS:
     - React-Core
     - React-cxxreact
     - React-debug
+    - React-featureflags
     - React-graphics
     - React-jsi
     - React-jsiexecutor
@@ -795,6 +872,7 @@ PODS:
     - React-Core
     - React-cxxreact
     - React-debug
+    - React-featureflags
     - React-graphics
     - React-jsi
     - React-jsiexecutor
@@ -814,6 +892,7 @@ PODS:
     - React-Core
     - React-cxxreact
     - React-debug
+    - React-featureflags
     - React-graphics
     - React-jsi
     - React-jsiexecutor
@@ -833,6 +912,7 @@ PODS:
     - React-Core
     - React-cxxreact
     - React-debug
+    - React-featureflags
     - React-graphics
     - React-jsi
     - React-jsiexecutor
@@ -852,6 +932,7 @@ PODS:
     - React-Core
     - React-cxxreact
     - React-debug
+    - React-featureflags
     - React-graphics
     - React-jsi
     - React-jsiexecutor
@@ -872,6 +953,7 @@ PODS:
     - React-cxxreact
     - React-debug
     - React-Fabric/uimanager
+    - React-featureflags
     - React-graphics
     - React-jsi
     - React-jsiexecutor
@@ -891,6 +973,7 @@ PODS:
     - React-Core
     - React-cxxreact
     - React-debug
+    - React-featureflags
     - React-graphics
     - React-jsi
     - React-jsiexecutor
@@ -917,10 +1000,35 @@ PODS:
     - React-utils
     - ReactCommon
     - Yoga
+  - React-featureflags (1000.0.0)
+  - React-featureflagsnativemodule (1000.0.0):
+    - DoubleConversion
+    - glog
+    - hermes-engine
+    - RCT-Folly (= 2024.01.01.00)
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-debug
+    - React-Fabric
+    - React-featureflags
+    - React-graphics
+    - React-ImageManager
+    - React-NativeModulesApple
+    - React-RCTFabric
+    - React-rendererdebug
+    - React-utils
+    - ReactCodegen
+    - ReactCommon/turbomodule/bridging
+    - ReactCommon/turbomodule/core
+    - Yoga
   - React-graphics (1000.0.0):
+    - DoubleConversion
+    - fmt (= 9.1.0)
     - glog
     - RCT-Folly/Fabric (= 2024.01.01.00)
-    - React-Core/Default (= 1000.0.0)
+    - React-jsi
+    - React-jsiexecutor
     - React-utils
   - React-hermes (1000.0.0):
     - DoubleConversion
@@ -931,8 +1039,9 @@ PODS:
     - React-cxxreact (= 1000.0.0)
     - React-jsi
     - React-jsiexecutor (= 1000.0.0)
-    - React-jsinspector (= 1000.0.0)
+    - React-jsinspector
     - React-perflogger (= 1000.0.0)
+    - React-runtimeexecutor
   - React-ImageManager (1000.0.0):
     - glog
     - RCT-Folly/Fabric
@@ -962,12 +1071,16 @@ PODS:
     - RCT-Folly (= 2024.01.01.00)
     - React-cxxreact (= 1000.0.0)
     - React-jsi (= 1000.0.0)
+    - React-jsinspector
     - React-perflogger (= 1000.0.0)
   - React-jsinspector (1000.0.0):
     - DoubleConversion
     - glog
+    - hermes-engine
     - RCT-Folly (= 2024.01.01.00)
-    - React-nativeconfig
+    - React-featureflags
+    - React-jsi
+    - React-runtimeexecutor (= 1000.0.0)
   - React-jsitracing (1000.0.0):
     - React-jsi
   - React-logger (1000.0.0):
@@ -975,6 +1088,27 @@ PODS:
   - React-Mapbuffer (1000.0.0):
     - glog
     - React-debug
+  - React-microtasksnativemodule (1000.0.0):
+    - DoubleConversion
+    - glog
+    - hermes-engine
+    - RCT-Folly (= 2024.01.01.00)
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-debug
+    - React-Fabric
+    - React-featureflags
+    - React-graphics
+    - React-ImageManager
+    - React-NativeModulesApple
+    - React-RCTFabric
+    - React-rendererdebug
+    - React-utils
+    - ReactCodegen
+    - ReactCommon/turbomodule/bridging
+    - ReactCommon/turbomodule/core
+    - Yoga
   - React-nativeconfig (1000.0.0)
   - React-NativeModulesApple (1000.0.0):
     - glog
@@ -983,6 +1117,7 @@ PODS:
     - React-Core
     - React-cxxreact
     - React-jsi
+    - React-jsinspector
     - React-runtimeexecutor
     - ReactCommon/turbomodule/bridging
     - ReactCommon/turbomodule/core
@@ -992,10 +1127,10 @@ PODS:
   - React-RCTAnimation (1000.0.0):
     - RCT-Folly (= 2024.01.01.00)
     - RCTTypeSafety
-    - React-Codegen
     - React-Core/RCTAnimationHeaders
     - React-jsi
     - React-NativeModulesApple
+    - ReactCodegen
     - ReactCommon
   - React-RCTAppDelegate (1000.0.0):
     - RCT-Folly (= 2024.01.01.00)
@@ -1005,9 +1140,11 @@ PODS:
     - React-CoreModules
     - React-debug
     - React-Fabric
+    - React-featureflags
+    - React-featureflagsnativemodule
     - React-graphics
     - React-hermes
-    - React-jsinspector
+    - React-microtasksnativemodule
     - React-nativeconfig
     - React-NativeModulesApple
     - React-RCTFabric
@@ -1019,16 +1156,20 @@ PODS:
     - React-RuntimeHermes
     - React-runtimescheduler
     - React-utils
+    - ReactCodegen
     - ReactCommon
   - React-RCTBlob (1000.0.0):
+    - DoubleConversion
+    - fmt (= 9.1.0)
     - hermes-engine
     - RCT-Folly (= 2024.01.01.00)
-    - React-Codegen
     - React-Core/RCTBlobHeaders
     - React-Core/RCTWebSocket
     - React-jsi
+    - React-jsinspector
     - React-NativeModulesApple
     - React-RCTNetwork
+    - ReactCodegen
     - ReactCommon
   - React-RCTFabric (1000.0.0):
     - glog
@@ -1038,9 +1179,11 @@ PODS:
     - React-debug
     - React-Fabric
     - React-FabricImage
+    - React-featureflags
     - React-graphics
     - React-ImageManager
     - React-jsi
+    - React-jsinspector
     - React-nativeconfig
     - React-RCTImage
     - React-RCTText
@@ -1051,44 +1194,45 @@ PODS:
   - React-RCTImage (1000.0.0):
     - RCT-Folly (= 2024.01.01.00)
     - RCTTypeSafety
-    - React-Codegen
     - React-Core/RCTImageHeaders
     - React-jsi
     - React-NativeModulesApple
     - React-RCTNetwork
+    - ReactCodegen
     - ReactCommon
   - React-RCTLinking (1000.0.0):
-    - React-Codegen
     - React-Core/RCTLinkingHeaders (= 1000.0.0)
     - React-jsi (= 1000.0.0)
     - React-NativeModulesApple
+    - ReactCodegen
     - ReactCommon
     - ReactCommon/turbomodule/core (= 1000.0.0)
   - React-RCTNetwork (1000.0.0):
     - RCT-Folly (= 2024.01.01.00)
     - RCTTypeSafety
-    - React-Codegen
     - React-Core/RCTNetworkHeaders
     - React-jsi
     - React-NativeModulesApple
+    - ReactCodegen
     - ReactCommon
   - React-RCTPushNotification (1000.0.0):
     - RCTTypeSafety
-    - React-Codegen
     - React-Core/RCTPushNotificationHeaders
     - React-jsi
     - React-NativeModulesApple
+    - ReactCodegen
     - ReactCommon
   - React-RCTSettings (1000.0.0):
     - RCT-Folly (= 2024.01.01.00)
     - RCTTypeSafety
-    - React-Codegen
     - React-Core/RCTSettingsHeaders
     - React-jsi
     - React-NativeModulesApple
+    - ReactCodegen
     - ReactCommon
   - React-RCTSwiftExtensions (1000.0.0):
     - React-Core
+    - React-RCTWindowManager
     - React-RCTXR
   - React-RCTTest (1000.0.0):
     - RCT-Folly (= 2024.01.01.00)
@@ -1101,18 +1245,26 @@ PODS:
     - Yoga
   - React-RCTVibration (1000.0.0):
     - RCT-Folly (= 2024.01.01.00)
-    - React-Codegen
     - React-Core/RCTVibrationHeaders
     - React-jsi
     - React-NativeModulesApple
+    - ReactCodegen
+    - ReactCommon
+  - React-RCTWindowManager (1000.0.0):
+    - RCT-Folly (= 2024.01.01.00)
+    - RCTTypeSafety
+    - React-Core/RCTWindowManagerHeaders
+    - React-jsi
+    - React-NativeModulesApple
+    - ReactCodegen
     - ReactCommon
   - React-RCTXR (1000.0.0):
     - RCT-Folly (= 2024.01.01.00)
     - RCTTypeSafety
-    - React-Codegen
     - React-Core/RCTXRHeaders
     - React-jsi
     - React-NativeModulesApple
+    - ReactCodegen
     - ReactCommon
   - React-rendererdebug (1000.0.0):
     - DoubleConversion
@@ -1143,6 +1295,7 @@ PODS:
     - hermes-engine
     - RCT-Folly/Fabric (= 2024.01.01.00)
     - React-cxxreact
+    - React-featureflags
     - React-jserrorhandler
     - React-jsi
     - React-jsiexecutor
@@ -1155,7 +1308,10 @@ PODS:
   - React-RuntimeHermes (1000.0.0):
     - hermes-engine
     - RCT-Folly/Fabric (= 2024.01.01.00)
+    - React-featureflags
+    - React-hermes
     - React-jsi
+    - React-jsinspector
     - React-jsitracing
     - React-nativeconfig
     - React-RuntimeCore
@@ -1167,27 +1323,49 @@ PODS:
     - React-callinvoker
     - React-cxxreact
     - React-debug
+    - React-featureflags
     - React-jsi
     - React-rendererdebug
     - React-runtimeexecutor
     - React-utils
   - React-utils (1000.0.0):
     - glog
+    - hermes-engine
     - RCT-Folly (= 2024.01.01.00)
     - React-debug
+    - React-jsi (= 1000.0.0)
+  - ReactCodegen (1000.0.0):
+    - DoubleConversion
+    - glog
+    - hermes-engine
+    - RCT-Folly
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-debug
+    - React-Fabric
+    - React-FabricImage
+    - React-featureflags
+    - React-graphics
+    - React-jsi
+    - React-jsiexecutor
+    - React-NativeModulesApple
+    - React-rendererdebug
+    - React-utils
+    - ReactCommon/turbomodule/bridging
+    - ReactCommon/turbomodule/core
   - ReactCommon (1000.0.0):
-    - React-logger (= 1000.0.0)
     - ReactCommon/turbomodule (= 1000.0.0)
   - ReactCommon-Samples (1000.0.0):
     - DoubleConversion
     - fmt (= 9.1.0)
     - hermes-engine
     - RCT-Folly
-    - React-Codegen
     - React-Core
     - React-cxxreact
     - React-jsi
     - React-NativeModulesApple
+    - ReactCodegen
     - ReactCommon
   - ReactCommon/turbomodule (1000.0.0):
     - DoubleConversion
@@ -1222,26 +1400,29 @@ PODS:
     - React-callinvoker (= 1000.0.0)
     - React-cxxreact (= 1000.0.0)
     - React-debug (= 1000.0.0)
+    - React-featureflags (= 1000.0.0)
     - React-jsi (= 1000.0.0)
     - React-logger (= 1000.0.0)
     - React-perflogger (= 1000.0.0)
-  - ScreenshotManager (0.0.1):
+    - React-utils (= 1000.0.0)
+  - ScreenshotManager (0.75.0-main):
     - DoubleConversion
     - glog
     - hermes-engine
     - RCT-Folly (= 2024.01.01.00)
     - RCTRequired
     - RCTTypeSafety
-    - React-Codegen
     - React-Core
     - React-debug
     - React-Fabric
+    - React-featureflags
     - React-graphics
     - React-ImageManager
     - React-NativeModulesApple
     - React-RCTFabric
     - React-rendererdebug
     - React-utils
+    - ReactCodegen
     - ReactCommon/turbomodule/bridging
     - ReactCommon/turbomodule/core
     - Yoga
@@ -1265,7 +1446,6 @@ DEPENDENCIES:
   - RCTTypeSafety (from `../react-native/Libraries/TypeSafety`)
   - React (from `../react-native/`)
   - React-callinvoker (from `../react-native/ReactCommon/callinvoker`)
-  - React-Codegen (from `build/generated/ios`)
   - React-Core (from `../react-native/`)
   - React-Core/RCTWebSocket (from `../react-native/`)
   - React-CoreModules (from `../react-native/React/CoreModules`)
@@ -1273,6 +1453,8 @@ DEPENDENCIES:
   - React-debug (from `../react-native/ReactCommon/react/debug`)
   - React-Fabric (from `../react-native/ReactCommon`)
   - React-FabricImage (from `../react-native/ReactCommon`)
+  - React-featureflags (from `../react-native/ReactCommon/react/featureflags`)
+  - React-featureflagsnativemodule (from `../react-native/ReactCommon/react/nativemodule/featureflags`)
   - React-graphics (from `../react-native/ReactCommon/react/renderer/graphics`)
   - React-hermes (from `../react-native/ReactCommon/hermes`)
   - React-ImageManager (from `../react-native/ReactCommon/react/renderer/imagemanager/platform/ios`)
@@ -1283,6 +1465,7 @@ DEPENDENCIES:
   - React-jsitracing (from `../react-native/ReactCommon/hermes/executor/`)
   - React-logger (from `../react-native/ReactCommon/logger`)
   - React-Mapbuffer (from `../react-native/ReactCommon`)
+  - React-microtasksnativemodule (from `../react-native/ReactCommon/react/nativemodule/microtasks`)
   - React-nativeconfig (from `../react-native/ReactCommon`)
   - React-NativeModulesApple (from `../react-native/ReactCommon/react/nativemodule/core/platform/ios`)
   - React-perflogger (from `../react-native/ReactCommon/reactperflogger`)
@@ -1300,6 +1483,7 @@ DEPENDENCIES:
   - React-RCTTest (from `./RCTTest`)
   - React-RCTText (from `../react-native/Libraries/Text`)
   - React-RCTVibration (from `../react-native/Libraries/Vibration`)
+  - React-RCTWindowManager (from `../react-native/Libraries/WindowManager`)
   - React-RCTXR (from `../react-native/Libraries/XR`)
   - React-rendererdebug (from `../react-native/ReactCommon/react/renderer/debug`)
   - React-rncore (from `../react-native/ReactCommon`)
@@ -1309,6 +1493,7 @@ DEPENDENCIES:
   - React-RuntimeHermes (from `../react-native/ReactCommon/react/runtime`)
   - React-runtimescheduler (from `../react-native/ReactCommon/react/renderer/runtimescheduler`)
   - React-utils (from `../react-native/ReactCommon/react/utils`)
+  - ReactCodegen (from `build/generated/ios`)
   - ReactCommon-Samples (from `../react-native/ReactCommon/react/nativemodule/samples`)
   - ReactCommon/turbomodule/core (from `../react-native/ReactCommon`)
   - ScreenshotManager (from `NativeModuleExample`)
@@ -1348,8 +1533,6 @@ EXTERNAL SOURCES:
     :path: "../react-native/"
   React-callinvoker:
     :path: "../react-native/ReactCommon/callinvoker"
-  React-Codegen:
-    :path: build/generated/ios
   React-Core:
     :path: "../react-native/"
   React-CoreModules:
@@ -1362,6 +1545,10 @@ EXTERNAL SOURCES:
     :path: "../react-native/ReactCommon"
   React-FabricImage:
     :path: "../react-native/ReactCommon"
+  React-featureflags:
+    :path: "../react-native/ReactCommon/react/featureflags"
+  React-featureflagsnativemodule:
+    :path: "../react-native/ReactCommon/react/nativemodule/featureflags"
   React-graphics:
     :path: "../react-native/ReactCommon/react/renderer/graphics"
   React-hermes:
@@ -1382,6 +1569,8 @@ EXTERNAL SOURCES:
     :path: "../react-native/ReactCommon/logger"
   React-Mapbuffer:
     :path: "../react-native/ReactCommon"
+  React-microtasksnativemodule:
+    :path: "../react-native/ReactCommon/react/nativemodule/microtasks"
   React-nativeconfig:
     :path: "../react-native/ReactCommon"
   React-NativeModulesApple:
@@ -1416,6 +1605,8 @@ EXTERNAL SOURCES:
     :path: "../react-native/Libraries/Text"
   React-RCTVibration:
     :path: "../react-native/Libraries/Vibration"
+  React-RCTWindowManager:
+    :path: "../react-native/Libraries/WindowManager"
   React-RCTXR:
     :path: "../react-native/Libraries/XR"
   React-rendererdebug:
@@ -1434,6 +1625,8 @@ EXTERNAL SOURCES:
     :path: "../react-native/ReactCommon/react/renderer/runtimescheduler"
   React-utils:
     :path: "../react-native/ReactCommon/react/utils"
+  ReactCodegen:
+    :path: build/generated/ios
   ReactCommon:
     :path: "../react-native/ReactCommon"
   ReactCommon-Samples:
@@ -1453,67 +1646,71 @@ CHECKOUT OPTIONS:
 SPEC CHECKSUMS:
   boost: 8f1e9b214fa11f71081fc8ecd5fad3daf221cf7f
   DoubleConversion: 26c660c8d88372cca1a67f8101d2d962a7064361
-  FBLazyVector: 6d72bc9033085488dab3c20cee3dab2b6a771dda
+  FBLazyVector: f7c646d10b8cd215e5dab3e26206582d1bd1f3b3
   fmt: 5d9ffa7ccba126c08b730252123601d514652320
   glog: 4f05d17aa39a829fee878689fc9a41af587fabba
-  hermes-engine: 3fed7e58e811ae8f795063cc6450714395c0276d
-  MyNativeView: 534e99e9c5dfd0bae242bdb06bb72e11d720c9a2
-  NativeCxxModuleExample: 107af3af8f5ce8802037937aabf1872ac891ad43
+  hermes-engine: bca1a39d82a348d5da84cd78a69763e639ca3c03
+  MyNativeView: 285c6f70650ff53a276f7086047921e617a4d0e3
+  NativeCxxModuleExample: 1cd42853b5ec241c6b5e70f2dd4bbc26feb97b39
   OCMock: 267d92c078398b7ce11d99e811e3a402744c06bc
-  RCT-Folly: 70c792c856324d6a518af75b3a307c14c226343a
+  RCT-Folly: 38265df22721cd15cc13ba692c23a52cceaf3752
   RCTDeprecation: 3808e36294137f9ee5668f4df2e73dc079cd1dcf
-  RCTRequired: 6426efd0d6123b35fdac9ad5796717cbcef85ff9
-  RCTTypeSafety: 7c822d061f3b0efcfb058c61cda509369bcb8602
-  React: 2f26ffcc453dbb43a07e7396d3cc568cf328f830
-  React-callinvoker: 1a7c0d6de53398862ddf642677df14231f6697d9
-  React-Codegen: 04a9ac6fd2f392534ed432102c6cbf117dcbf62b
-  React-Core: 9397cdd14ae7018850c16dea3b31ac72c4ff0324
-  React-CoreModules: 53a00162be44e3353f2a9efad243d3dafe258cdb
-  React-cxxreact: 46f736a9cace851d42a3704c0da637d8566fd7d6
-  React-debug: b1f637660400365b9b6908bd521ffce20c713dc5
-  React-Fabric: 34c01267cb5ace971a7ae1a9c720ce5b30e92465
-  React-FabricImage: 2e076721abe31734ce2a01cf82e254801ce5503f
-  React-graphics: 5ca218f8180dda07f997fa5ad145b7d5d7f35bd9
-  React-hermes: d5707721feadf6c74d53fbc7a6212a98a140954c
-  React-ImageManager: deb13029061d5b0b08b21b8ea5883c15b7f4ba93
-  React-jserrorhandler: f719009db2ae821f7df30866fa7e16676a14e85d
-  React-jsi: 9bf49563b30132199feb9b7721289ebbe61258f5
-  React-jsiexecutor: 81e5a31965bb0e29d66df963ec9bf13496e84482
-  React-jsinspector: 3b3514d648791386506f2f4eb7f1791e8b44f663
-  React-jsitracing: 84ec35538d5d28a74431e58fc245761327dcb537
-  React-logger: a41fc9cccff7de126c97e366c8909304531813ec
-  React-Mapbuffer: 3f22d38e3c903fa729061b0e8b976d102c377306
-  React-nativeconfig: 0d00e737812420344137c8b7010033675d527982
-  React-NativeModulesApple: 803f8508c47c2963cf893d74904ccc605fae4696
-  React-perflogger: 0d57e63db7d181c2c3b9d13305b89b7783615739
-  React-RCTActionSheet: aa4ae1a2a14153412e9237b10234a40e30d2b410
-  React-RCTAnimation: 7eea83acd5da45de3d2e0c3aaa8df9d2957783bf
-  React-RCTAppDelegate: d48ddb6a45470b5d5d75d35927c2342698c47e56
-  React-RCTBlob: 038dce0c29488cfbc19daa6d60b1cfcb01e9172d
-  React-RCTFabric: 131c60dc266f637d45c75c02b81d337c4e3179f9
-  React-RCTImage: af4bbba6368f6b219915ca569ae5cf67fc8585f8
-  React-RCTLinking: ce884034ffbece4c6c2ae8e1e8b4b88fb0ee406b
-  React-RCTNetwork: 488fca1b0e9f4f9802696372216029f5d1da6bc6
-  React-RCTPushNotification: 2bb0038afd0c02f65d7b74b93bddcb2639cc6edf
-  React-RCTSettings: 0ff75db9df85764bd838b1ea9411fde23247f229
-  React-RCTSwiftExtensions: 0751aeb108e9c7ae39b26710b7fb47d79fe0bfb9
-  React-RCTTest: 3144ece03e48904e7796c2a96bd931649027516d
-  React-RCTText: abc6d97f7e36f9aed66678fc712f703d5bce2dfc
-  React-RCTVibration: 2b3b6cda5f979b0d16db391e737651d0dd4147a6
-  React-RCTXR: 07a185fd7221532ccc6a5a9f237102256f823e60
-  React-rendererdebug: 48c745f05ebf3ae447ea521c2b77bb7ee3923fd6
-  React-rncore: 84944ba68705b5de9959d2206cfe7dd3181e83f2
-  React-RuntimeApple: 33e35a0c93367647120758a61c71e21c73ce54ee
-  React-RuntimeCore: 7a4d19efece49c4087fd7bb30a643397d9ba1ab1
-  React-runtimeexecutor: fb3425d082ad47c4bc7153419b3eac899d318603
-  React-RuntimeHermes: 556f92a11c0cf9b4d4e4d7240dca228bdebb4622
-  React-runtimescheduler: c101938ad407340555eb5d56557b3409785a7396
-  React-utils: c3b2a4535dfad1e3c68d371b3946a33db4ceac4a
-  ReactCommon: 93b947fa9f432e09577a5d8c3f09c0ad7a6a4fc5
-  ReactCommon-Samples: 6a59337d27861b986269a95c52aa5353b87da4ba
-  ScreenshotManager: a5f596498de38f3cf3377df636ca67355503f190
+  RCTRequired: 239aa032bf3e9e2b43f4279650d63c0514951272
+  RCTTypeSafety: e5bbadc74447a21a1cc6d98ad4d5cdfc73ad5b66
+  React: 36785b138eaf4d504269ac00ff83c830b0373cc5
+  React-callinvoker: bd85ea880a7f9ec6f795b61e3e358fde6c0b317f
+  React-Core: a26b444d25335c293811d41c9ac1e305a874f3b6
+  React-CoreModules: 4ee3dd2283abea7880db94ca0d8d74378f3ec9c7
+  React-cxxreact: 1db0679e0e4ecd9f4cd558bb3a0c7c5c61898c46
+  React-debug: 76832f0727faeabe8d5797b89af59405245303ab
+  React-Fabric: 2eb7d788b7494a689a8c037e9f19bbdfc0a98c16
+  React-FabricImage: 78fd6dd2c9941919148085b849899efe2374753d
+  React-featureflags: 0b457907abe15741d96164e86f987e44e0deb682
+  React-featureflagsnativemodule: 8099131f04c0e14100b9042e502c9f4a601a1c9f
+  React-graphics: b3dccf47ce13236169b572f2ae68294254b9d00b
+  React-hermes: 2ecd1177928bb621e1417d3355d97f712ab80ba8
+  React-ImageManager: a116cb9770a8dd1a96663949b46c62b2b88e215e
+  React-jserrorhandler: 840ed095e547ec53ab9e1358fe9d328388ad6bfe
+  React-jsi: 296634766135fc72c578f836ed11ea43c30f062a
+  React-jsiexecutor: dc33a899bb4a018c1fd782fa86b39a3244fd67da
+  React-jsinspector: 2bc546bf89903b65c6e66a822b65239ec3ffbe2f
+  React-jsitracing: 57b4ec6a2f0442242cbcbf8f017cf697020dca37
+  React-logger: be89505b09a5ee83ff68c205b1bcd2ebb3946f1c
+  React-Mapbuffer: 708e90b77110c3fa3fe2ae81c4ddc169cb7eeca0
+  React-microtasksnativemodule: b3855853e36d49824f3b99174067fc2f4ed60044
+  React-nativeconfig: 5b509000c98cbe5ca55fcc795bc41604e1c95133
+  React-NativeModulesApple: ca430b16c6130627f584bc2a13c10cf0864dd23f
+  React-perflogger: 47f5978f4e2183208b911e7b009b887602165566
+  React-RCTActionSheet: 36cbb9a32d7b0a762fa260b693f233438e2eba42
+  React-RCTAnimation: 0c19d427491635e8cf80e0d22652339317760495
+  React-RCTAppDelegate: cb18253c38d44dfdb270aaf969e212e141ff2eda
+  React-RCTBlob: 67d12c51a8dc3bf915c5dbd568fdf2420c593946
+  React-RCTFabric: 0c297f7bfff6bfc15493e6b52d926206ddf4e7f3
+  React-RCTImage: 2268b4c62d81343cb4a261b01c285140f583fefb
+  React-RCTLinking: 659311c46fc100f750d0bd06d5b347dd731f014c
+  React-RCTNetwork: 8b8df92aa1eb87bc028ee94689a747b85956db27
+  React-RCTPushNotification: bfe7a851d7c69005bf42c31262db3c388566a9a7
+  React-RCTSettings: ab9f3f94954c3e226075c51d69b4fbe5355f8cbc
+  React-RCTSwiftExtensions: 9796d287e7bbd7b11551f93ac99f2f6f637795ad
+  React-RCTTest: d2b359f29ae63fa20b90859dbf9cc01bd06319ec
+  React-RCTText: c7a31b344ff91c62c8eb51cb19ae75e94c74caaa
+  React-RCTVibration: dbb77d0546be6644df5a0d72c7c71d84074f8dd6
+  React-RCTWindowManager: 590894746aee624fcb4eab807224fc5708e6b018
+  React-RCTXR: 8ada18d6b23da3c6d1afcf8232ee9df9f3b42f2f
+  React-rendererdebug: ee39d499144ad322a5e8f2815197b2be770151fd
+  React-rncore: 9104c5cc28cd2777a641843b2297c55674593e64
+  React-RuntimeApple: e6c533fe960654098a2bc1f63a9a2b9589311b94
+  React-RuntimeCore: 8484628d9d4914ccfd1f3905cabca19b3e605419
+  React-runtimeexecutor: 2f2c677c8600c1105928a67f5f725518bf1f9d27
+  React-RuntimeHermes: cd010ffb49df509b57077716359a5275ce4db90b
+  React-runtimescheduler: 9c66554fc1cc6f28952949366150f2d39dae2eaf
+  React-utils: a94e4f22cc27a2bb874ba9d97de87fd0ec4f5d5f
+  ReactCodegen: 2fa2bfb8df604e5bbf2462cf3cced313c3131b96
+  ReactCommon: 4760f12d60e79f903e5fff832e29a925bdc8d764
+  ReactCommon-Samples: bed8a502f833c9b4c18331dc3f8ded5c090b2217
+  ScreenshotManager: 662151998cf5859591e72c76ceb9ebc6d04b425b
   SocketRocket: 0ba3e799f983d2dfa878777017659ef6c866e5c6
-  Yoga: 50572c6c7c8227a84feb5746efa5f841f75f6f1b
+  Yoga: 00ec2b1b43fcb85eb2faeb0263759b7995c9ddad
 
 PODFILE CHECKSUM: 7e999b8158f1055609ef4491bc35f1ad658fdd6c
 
diff --git a/packages/rn-tester/RNTester-visionOS/App.swift b/packages/rn-tester/RNTester-visionOS/App.swift
index 8e28482981e8a6..939cef2664d031 100644
--- a/packages/rn-tester/RNTester-visionOS/App.swift
+++ b/packages/rn-tester/RNTester-visionOS/App.swift
@@ -5,11 +5,17 @@ import React_RCTSwiftExtensions
 @main
 struct RNTesterApp: App {
   @UIApplicationDelegateAdaptor var delegate: AppDelegate
+  @Environment(\.reactContext) private var reactContext
+  
   @State private var immersionLevel: ImmersionStyle = .full
   
   var body: some Scene {
     RCTMainWindow(moduleName: "RNTesterApp")
+    
+    RCTWindow(id: "SecondWindow", sceneData: reactContext.getSceneData(id: "SecondWindow"))
+      .defaultSize(CGSize(width: 400, height: 700))
+    
     ImmersiveSpace(id: "TestImmersiveSpace") {}
-      .immersionStyle(selection: $immersionLevel, in: .mixed, .progressive, .full)
+     .immersionStyle(selection: $immersionLevel, in: .mixed, .progressive, .full)
   }
 }
diff --git a/packages/rn-tester/js/RNTesterApp.ios.js b/packages/rn-tester/js/RNTesterApp.ios.js
index 281ee25afd77a1..8ea87c26361438 100644
--- a/packages/rn-tester/js/RNTesterApp.ios.js
+++ b/packages/rn-tester/js/RNTesterApp.ios.js
@@ -24,6 +24,9 @@ AppRegistry.registerComponent('SetPropertiesExampleApp', () =>
 AppRegistry.registerComponent('RootViewSizeFlexibilityExampleApp', () =>
   require('./examples/RootViewSizeFlexibilityExample/RootViewSizeFlexibilityExampleApp'),
 );
+AppRegistry.registerComponent('SecondWindow', () =>
+  require('./examples/SecondWindow/SecondWindow'),
+);
 AppRegistry.registerComponent('RNTesterApp', () => RNTesterApp);
 
 // Register suitable examples for snapshot tests
diff --git a/packages/rn-tester/js/examples/SecondWindow/SecondWindow.js b/packages/rn-tester/js/examples/SecondWindow/SecondWindow.js
new file mode 100644
index 00000000000000..10f71a32dae917
--- /dev/null
+++ b/packages/rn-tester/js/examples/SecondWindow/SecondWindow.js
@@ -0,0 +1,52 @@
+/**
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ * @format
+ * @flow
+ */
+
+'use strict';
+
+const {WindowManager} = require('@callstack/react-native-visionos');
+const React = require('react');
+const {Button, StyleSheet, Text, View} = require('react-native');
+
+type Props = $ReadOnly<{|
+  title?: String,
+|}>;
+
+const SecondWindow = ({title}: Props): React.Node => {
+  const [counter, setCounter] = React.useState(0);
+  return (
+    <View style={styles.center}>
+      <Text style={styles.text}>{title}</Text>
+      <Text style={[styles.text, {fontSize: 20}]}>{counter}</Text>
+      <Button title="Increment" onPress={() => setCounter(counter + 1)} />
+      <Button
+        title="Close window"
+        onPress={async () =>
+          await WindowManager.getWindow('SecondWindow').close()
+        }
+      />
+    </View>
+  );
+};
+
+const styles = StyleSheet.create({
+  center: {
+    flex: 1,
+    alignItems: 'center',
+    justifyContent: 'center',
+  },
+  text: {
+    fontSize: 30,
+    color: 'white',
+    textAlign: 'center',
+    fontWeight: 'bold',
+  },
+});
+
+module.exports = SecondWindow;
diff --git a/packages/rn-tester/js/examples/XR/XRExample.js b/packages/rn-tester/js/examples/XR/XRExample.js
index b9bd48e3f5c2c3..b042657dc0472b 100644
--- a/packages/rn-tester/js/examples/XR/XRExample.js
+++ b/packages/rn-tester/js/examples/XR/XRExample.js
@@ -10,16 +10,18 @@
 
 'use strict';
 
-const {XR} = require('@callstack/react-native-visionos');
+const {WindowManager, XR} = require('@callstack/react-native-visionos');
 const React = require('react');
 const {Alert, Button, StyleSheet, Text, View} = require('react-native');
 
+const secondWindow = WindowManager.getWindow('SecondWindow');
+
 const OpenXRSession = () => {
   const [isOpen, setIsOpen] = React.useState(false);
 
   const openXRSession = async () => {
     try {
-      if (!XR.supportsMultipleScenes) {
+      if (!WindowManager.supportsMultipleScenes) {
         Alert.alert('Error', 'Multiple scenes are not supported');
         return;
       }
@@ -32,16 +34,34 @@ const OpenXRSession = () => {
   };
 
   const closeXRSession = async () => {
-    if (isOpen) {
-      await XR.endSession();
+    await XR.endSession();
+    setIsOpen(false);
+  };
+
+  const openWindow = async () => {
+    try {
+      await secondWindow.open({title: 'React Native Window'});
+    } catch (e) {
+      Alert.alert('Error', e.message);
     }
   };
 
+  const updateWindow = async () => {
+    await secondWindow.update({title: 'Updated Window'});
+  };
+
+  const closeWindow = async () => {
+    await secondWindow.close();
+  };
+
   return (
     <View style={styles.container}>
       <Text style={styles.title}>Is XR session open: {isOpen}</Text>
       <Button title="Open XR Session" onPress={openXRSession} />
       <Button title="Close XR Session" onPress={closeXRSession} />
+      <Button title="Open Second Window" onPress={openWindow} />
+      <Button title="Update Second Window" onPress={updateWindow} />
+      <Button title="Close Second Window" onPress={closeWindow} />
     </View>
   );
 };