Repository: facebook/react-native (language: cpp)

Issue:
Static images are not rendered on Android for 0.71.0-rc.0
### Description

Static images (like the logo in the header of a newly generated application) are not rendered on Android in 0.71.0-rc.0.

#### Cause of the bug

I've done a bit of investigation, here is what I found:

In the [react-native-gradle-plugin](https://github.com/facebook/react-native/blob/2df63e52f4570f348156bcd47696b8395a73fbc7/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/TaskConfiguration.kt#L74), we use `variant.sources.res?.addGeneratedSourceDirectory(bundleTask, BundleHermesCTask::resourcesDir)` which changes the `resourcesDir` of the `bundleTask` to `RES/createBundleReleaseJsAndAssets`: https://android.googlesource.com/platform/tools/base/+blame/186d0522f7fc1f02e33c197f40a5b7ce8834f110/build-system/gradle-core/src/main/java/com/android/build/api/variant/impl/SourceDirectoriesImpl.kt#54

There has been [a fix](https://android.googlesource.com/platform/tools/base/+/374b58dfff28dbaccbb2815db66c412b0bccf013%5E%21/build-system/gradle-core/src/main/java/com/android/build/api/variant/impl/SourceDirectoriesImpl.kt) applied in android-gradle-plugin version 7.4.0-beta05, so the new path is then `generates/res/createBundleReleaseJsAndAssets`, and with this version I can see the image 🥳.

So one solution is to wait for android-gradle-plugin version 7.4.0 to be released.

However, resources won't be in "generated/res/react/Release" which is the path [specified in the react-native-gradle-plugin](https://github.com/facebook/react-native/blob/2df63e52f4570f348156bcd47696b8395a73fbc7/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/TaskConfiguration.kt#L26), I think this can be misleading.
This path should be changed as well, or the resources should be copied over to that directory as well, as what used to be done with `react.gradle`.

This is exactly the same cause as https://github.com/facebook/react-native/issues/35398.

### Version

0.71.0-rc.0

### Output of `npx react-native info`

```
System:
    OS: macOS 12.6.1
    CPU: (10) arm64 Apple M1 Max
    Memory: 7.11 GB / 64.00 GB
    Shell: 5.8.1 - /bin/zsh
  Binaries:
    Node: 18.11.0 - /opt/homebrew/bin/node
    Yarn: 1.22.19 - ~/.npm-global/bin/yarn
    npm: 8.19.2 - /opt/homebrew/bin/npm
    Watchman: 2022.10.24.00 - /opt/homebrew/bin/watchman
  Managers:
    CocoaPods: 1.11.3 - /opt/homebrew/bin/pod
  SDKs:
    iOS SDK:
      Platforms: DriverKit 22.1, iOS 16.1, macOS 13.0, tvOS 16.1, watchOS 9.1
    Android SDK: Not Found
  IDEs:
    Android Studio: 2021.3 AI-213.7172.25.2113.9014738
    Xcode: 14.1/14B47b - /usr/bin/xcodebuild
  Languages:
    Java: 11.0.16.1 - /usr/bin/javac
  npmPackages:
    @react-native-community/cli: Not Found
    react: 18.2.0 => 18.2.0
    react-native: 0.71.0-rc.0 => 0.71.0-rc.0
    react-native-macos: Not Found
  npmGlobalPackages:
    *react-native*: Not Found
```

### Steps to reproduce

- Create a new app using the command: `npx react-native init <YourAppName> --version 0.71.0-rc.0`
- Manually download the [maven-local.zip](https://github.com/facebook/react-native/releases/download/v0.71.0-rc.0/maven-local.zip) archive (you can also find the link in [this release](https://github.com/facebook/react-native/releases/tag/v0.71.0-rc.0)).
- Unzip the `maven-local.zip` on a folder on your disk.
- Add the `REACT_NATIVE_MAVEN_LOCAL_REPO=<path_to_the_maven-local_unzipped_folder>` setting to the android/gradle.properties file
- Build with `yarn android --variant=release`


### Snack, code example, screenshot, or link to a repository

With `"com.android.tools.build:gradle:7.3.1"`:
![image](https://user-images.githubusercontent.com/8973379/203518221-1872b643-24a9-4027-81fc-a02739b3d61c.png)


With `"com.android.tools.build:gradle:7.4.0-beta05"`:
![image](https://user-images.githubusercontent.com/8973379/203517985-f5d0ce0a-c412-451d-9006-27989f41922f.png)



Discussion / hints:
Thansk for sharing this @louiszawadzki It's under my radar. I'll try to reproduce and get back to you
I was able to reproduce. That's a bug on AGP 7.3
https://issuetracker.google.com/issues/237421684
The issue is fixed on AGP 7.4.0-beta05. I've tried to bump locally and the images are bundled correctly.

So either we bump AGP to 7.4.0-beta05 or we try to ask for a backport of that fix on AGP 7.3

Fix patch:
diff --git a/.gitignore b/.gitignore
index fadf52a7f1c187..01027b3802aef0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -64,7 +64,8 @@ buck-out
 .gradle
 local.properties
 *.iml
-/android/
+/android/*
+!/android/README.md
 
 # Node
 node_modules
diff --git a/BUCK b/BUCK
index 084c651442d027..4325eaa291eae9 100644
--- a/BUCK
+++ b/BUCK
@@ -115,7 +115,7 @@ rn_xplat_cxx_library2(
         react_native_root_target("React/CoreModules:CoreModules"),
         react_native_xplat_target("cxxreact:bridge"),
         react_native_xplat_target("cxxreact:jsbigstring"),
-        react_native_xplat_target("jsi:JSCRuntime"),
+        react_native_xplat_target("jsc:JSCRuntime"),
         react_native_xplat_target("jsiexecutor:jsiexecutor"),
         react_native_xplat_target("reactperflogger:reactperflogger"),
     ],
diff --git a/React/CxxBridge/JSCExecutorFactory.mm b/React/CxxBridge/JSCExecutorFactory.mm
index 4d8a1ba1b2940e..78584cd4e6c121 100644
--- a/React/CxxBridge/JSCExecutorFactory.mm
+++ b/React/CxxBridge/JSCExecutorFactory.mm
@@ -7,7 +7,7 @@
 
 #include "JSCExecutorFactory.h"
 
-#import <jsi/JSCRuntime.h>
+#import <jsc/JSCRuntime.h>
 
 #import <memory>
 
diff --git a/ReactAndroid/build.gradle b/ReactAndroid/build.gradle
index d43535934995e3..72f5b7c6ce2ac3 100644
--- a/ReactAndroid/build.gradle
+++ b/ReactAndroid/build.gradle
@@ -144,6 +144,7 @@ final def preparePrefab = tasks.register("preparePrefab", PreparePrefabHeadersTa
                     new Pair(new File(buildDir, "third-party-ndk/boost/boost_1_76_0/").absolutePath, ""),
                     new Pair(new File(buildDir, "third-party-ndk/double-conversion/").absolutePath, ""),
                     new Pair(new File(buildDir, "third-party-ndk/folly/").absolutePath, ""),
+                    new Pair(new File(buildDir, "third-party-ndk/glog/exported/").absolutePath, ""),
                     new Pair("../ReactCommon/butter/", "butter/"),
                     new Pair("../ReactCommon/callinvoker/", ""),
                     new Pair("../ReactCommon/react/bridging/", "react/bridging/"),
@@ -152,6 +153,8 @@ final def preparePrefab = tasks.register("preparePrefab", PreparePrefabHeadersTa
                     new Pair("../ReactCommon/react/nativemodule/core/platform/android/", ""),
                     new Pair("../ReactCommon/react/renderer/componentregistry/", "react/renderer/componentregistry/"),
                     new Pair("../ReactCommon/react/renderer/components/root/", "react/renderer/components/root/"),
+                    new Pair("../ReactCommon/react/renderer/core/", "react/renderer/core/"),
+                    new Pair("../ReactCommon/react/renderer/debug/", "react/renderer/debug/"),
                     new Pair("../ReactCommon/react/renderer/leakchecker/", "react/renderer/leakchecker/"),
                     new Pair("../ReactCommon/react/renderer/mapbuffer/", "react/renderer/mapbuffer/"),
                     new Pair("../ReactCommon/react/renderer/mounting/", "react/renderer/mounting/"),
@@ -159,6 +162,7 @@ final def preparePrefab = tasks.register("preparePrefab", PreparePrefabHeadersTa
                     new Pair("../ReactCommon/react/renderer/scheduler/", "react/renderer/scheduler/"),
                     new Pair("../ReactCommon/react/renderer/telemetry/", "react/renderer/telemetry/"),
                     new Pair("../ReactCommon/react/renderer/uimanager/", "react/renderer/uimanager/"),
+                    new Pair("../ReactCommon/react/debug/", "react/debug/"),
                     new Pair("../ReactCommon/react/utils/", "react/utils/"),
                     new Pair("src/main/jni/react/jni", "react/jni/"),
                 ]
@@ -174,6 +178,35 @@ final def preparePrefab = tasks.register("preparePrefab", PreparePrefabHeadersTa
                 "rrc_image",
                 new Pair("../ReactCommon/react/renderer/components/image/", "react/renderer/components/image/")
             ),
+            // These prefab targets are used by Expo & Reanimated
+            new PrefabPreprocessingEntry(
+                "hermes_executor",
+                // "hermes_executor" is statically linking against "hermes_executor_common"
+                // and "hermes_inspector". Here we expose only the headers that we know are needed.
+                new Pair("../ReactCommon/hermes/inspector/", "hermes/inspector/")
+            ),
+            new PrefabPreprocessingEntry(
+                "jscexecutor",
+                // "jscexecutor" is statically linking against "jscruntime"
+                // Here we expose only the headers that we know are needed.
+                new Pair("../ReactCommon/jsc/", "jsc/")
+            ),
+            new PrefabPreprocessingEntry(
+                "react_render_uimanager",
+                new Pair("../ReactCommon/react/renderer/uimanager/", "react/renderer/uimanager/"),
+            ),
+            new PrefabPreprocessingEntry(
+                "react_render_scheduler",
+                new Pair("../ReactCommon/react/renderer/scheduler/", "react/renderer/scheduler/"),
+            ),
+            new PrefabPreprocessingEntry(
+                "react_render_mounting",
+                new Pair("../ReactCommon/react/renderer/mounting/", "react/renderer/mounting/"),
+            ),
+            new PrefabPreprocessingEntry(
+                "reactnativejni",
+                new Pair("src/main/jni/react/jni", "react/jni/"),
+            ),
         ]
     )
     it.outputDir.set(prefabHeadersDir)
@@ -402,12 +435,12 @@ android {
                     "-DANDROID_TOOLCHAIN=clang",
                     "-DANDROID_PLATFORM=android-21"
 
-                targets "reactnativejni",
-                    "jscexecutor",
+                targets "jscexecutor",
                     "jsijniprofiler",
                     "reactnativeblob",
                     "reactperfloggerjni",
                     // prefab targets
+                    "reactnativejni",
                     "react_render_debug",
                     "turbomodulejsijni",
                     "runtimeexecutor",
@@ -426,7 +459,11 @@ android {
                     "yoga",
                     "folly_runtime",
                     "react_nativemodule_core",
-                    "react_render_imagemanager"
+                    "react_render_imagemanager",
+                    "react_render_uimanager",
+                    "react_render_scheduler",
+                    "react_render_mounting",
+                    "hermes_executor"
             }
         }
         ndk {
@@ -434,24 +471,6 @@ android {
         }
     }
 
-    buildTypes {
-        debug {
-            externalNativeBuild {
-                cmake {
-                    targets "hermes-executor-debug"
-                }
-            }
-        }
-
-        release {
-            externalNativeBuild {
-                cmake {
-                    targets "hermes-executor-release"
-                }
-            }
-        }
-    }
-
     externalNativeBuild {
         cmake {
             path "src/main/jni/CMakeLists.txt"
@@ -549,6 +568,21 @@ android {
         react_render_imagemanager {
             headers(new File(prefabHeadersDir, "react_render_imagemanager").absolutePath)
         }
+        react_render_uimanager {
+            headers(new File(prefabHeadersDir, "react_render_uimanager").absolutePath)
+        }
+        react_render_scheduler {
+            headers(new File(prefabHeadersDir, "react_render_scheduler").absolutePath)
+        }
+        react_render_mounting {
+            headers(new File(prefabHeadersDir, "react_render_mounting").absolutePath)
+        }
+        reactnativejni {
+            headers(new File(prefabHeadersDir, "reactnativejni").absolutePath)
+        }
+        hermes_executor {
+            headers(new File(prefabHeadersDir, "hermes_executor").absolutePath)
+        }
     }
 
     publishing {
diff --git a/ReactAndroid/src/main/java/com/facebook/hermes/reactexecutor/BUCK b/ReactAndroid/src/main/java/com/facebook/hermes/reactexecutor/BUCK
index 0c00d480eddb44..2c954374c38dcf 100644
--- a/ReactAndroid/src/main/java/com/facebook/hermes/reactexecutor/BUCK
+++ b/ReactAndroid/src/main/java/com/facebook/hermes/reactexecutor/BUCK
@@ -17,6 +17,7 @@ rn_android_library(
         react_native_target("java/com/facebook/hermes/instrumentation:instrumentation"),
         react_native_target("java/com/facebook/hermes/instrumentation:hermes_samplingprofiler"),
         react_native_target("java/com/facebook/react/bridge:bridge"),
+        react_native_target("java/com/facebook/react/common:common"),
         react_native_target("jni/react/hermes/reactexecutor:jni"),
         ":runtimeconfig",
     ],
diff --git a/ReactAndroid/src/main/java/com/facebook/hermes/reactexecutor/HermesExecutor.java b/ReactAndroid/src/main/java/com/facebook/hermes/reactexecutor/HermesExecutor.java
index 48eaaa4c0668ba..b0e4f24d10d912 100644
--- a/ReactAndroid/src/main/java/com/facebook/hermes/reactexecutor/HermesExecutor.java
+++ b/ReactAndroid/src/main/java/com/facebook/hermes/reactexecutor/HermesExecutor.java
@@ -9,6 +9,7 @@
 
 import com.facebook.jni.HybridData;
 import com.facebook.react.bridge.JavaScriptExecutor;
+import com.facebook.react.common.build.ReactBuildConfig;
 import com.facebook.soloader.SoLoader;
 import javax.annotation.Nullable;
 
@@ -23,11 +24,11 @@ public static void loadLibrary() throws UnsatisfiedLinkError {
     if (mode_ == null) {
       // libhermes must be loaded explicitly to invoke its JNI_OnLoad.
       SoLoader.loadLibrary("hermes");
-      try {
-        SoLoader.loadLibrary("hermes-executor-debug");
+      SoLoader.loadLibrary("hermes_executor");
+      // libhermes_executor is built differently for Debug & Release so we load the proper mode.
+      if (ReactBuildConfig.DEBUG == true) {
         mode_ = "Debug";
-      } catch (UnsatisfiedLinkError e) {
-        SoLoader.loadLibrary("hermes-executor-release");
+      } else {
         mode_ = "Release";
       }
     }
diff --git a/ReactAndroid/src/main/jni/CMakeLists.txt b/ReactAndroid/src/main/jni/CMakeLists.txt
index 420794146092e8..c7ee6155e9cc5a 100644
--- a/ReactAndroid/src/main/jni/CMakeLists.txt
+++ b/ReactAndroid/src/main/jni/CMakeLists.txt
@@ -56,6 +56,7 @@ add_react_common_subdir(reactperflogger)
 add_react_common_subdir(logger)
 add_react_common_subdir(jsiexecutor)
 add_react_common_subdir(cxxreact)
+add_react_common_subdir(jsc)
 add_react_common_subdir(jsi)
 add_react_common_subdir(butter)
 add_react_common_subdir(callinvoker)
diff --git a/ReactAndroid/src/main/jni/react/hermes/reactexecutor/BUCK b/ReactAndroid/src/main/jni/react/hermes/reactexecutor/BUCK
index 94229f186158e8..e292584fa62864 100644
--- a/ReactAndroid/src/main/jni/react/hermes/reactexecutor/BUCK
+++ b/ReactAndroid/src/main/jni/react/hermes/reactexecutor/BUCK
@@ -14,6 +14,6 @@ rn_xplat_cxx_library(
     headers = [],
     header_namespace = "",
     compiler_flags = ["-fexceptions"],
-    soname = "libhermes-executor.$(ext)",
+    soname = "libhermes_executor.$(ext)",
     visibility = ["PUBLIC"],
 )
diff --git a/ReactAndroid/src/main/jni/react/hermes/reactexecutor/CMakeLists.txt b/ReactAndroid/src/main/jni/react/hermes/reactexecutor/CMakeLists.txt
index d446141c7ed92d..550b324e821950 100644
--- a/ReactAndroid/src/main/jni/react/hermes/reactexecutor/CMakeLists.txt
+++ b/ReactAndroid/src/main/jni/react/hermes/reactexecutor/CMakeLists.txt
@@ -8,29 +8,20 @@ set(CMAKE_VERBOSE_MAKEFILE on)
 
 file(GLOB_RECURSE hermes_executor_SRC CONFIGURE_DEPENDS *.cpp)
 
-if(${CMAKE_BUILD_TYPE} MATCHES Debug)
-        set(HERMES_TARGET_SUFFIX debug)
-else()
-        set(HERMES_TARGET_SUFFIX release)
-endif()
-
-set(HERMES_TARGET_NAME hermes-executor-${HERMES_TARGET_SUFFIX})
-
-add_library(
-        ${HERMES_TARGET_NAME}
+add_library(hermes_executor
         SHARED
         ${hermes_executor_SRC}
 )
 target_compile_options(
-        ${HERMES_TARGET_NAME}
+        hermes_executor
         PRIVATE
         $<$<CONFIG:Debug>:-DHERMES_ENABLE_DEBUGGER=1>
         -fexceptions
 )
-target_include_directories(${HERMES_TARGET_NAME} PRIVATE .)
+target_include_directories(hermes_executor PRIVATE .)
 target_link_libraries(
-        ${HERMES_TARGET_NAME}
-        hermes-executor-common
+        hermes_executor
+        hermes_executor_common
         jsireact
         fb
         fbjni
diff --git a/ReactAndroid/src/main/jni/react/jscexecutor/BUCK b/ReactAndroid/src/main/jni/react/jscexecutor/BUCK
index 7719f27dbc9601..8b3e82eb665f94 100644
--- a/ReactAndroid/src/main/jni/react/jscexecutor/BUCK
+++ b/ReactAndroid/src/main/jni/react/jscexecutor/BUCK
@@ -16,7 +16,7 @@ rn_xplat_cxx_library(
     deps = [
         FBJNI_TARGET,
         react_native_target("jni/react/jni:jni"),
-        react_native_xplat_target("jsi:JSCRuntime"),
+        react_native_xplat_target("jsc:JSCRuntime"),
         react_native_xplat_target("jsiexecutor:jsiexecutor"),
     ],
 )
diff --git a/ReactAndroid/src/main/jni/react/jscexecutor/OnLoad.cpp b/ReactAndroid/src/main/jni/react/jscexecutor/OnLoad.cpp
index 60450b5c404b33..9d38412d1cb9cd 100644
--- a/ReactAndroid/src/main/jni/react/jscexecutor/OnLoad.cpp
+++ b/ReactAndroid/src/main/jni/react/jscexecutor/OnLoad.cpp
@@ -6,7 +6,7 @@
  */
 
 #include <fbjni/fbjni.h>
-#include <jsi/JSCRuntime.h>
+#include <jsc/JSCRuntime.h>
 #include <jsireact/JSIExecutor.h>
 #include <react/jni/JReactMarker.h>
 #include <react/jni/JSLogging.h>
diff --git a/ReactCommon/hermes/executor/CMakeLists.txt b/ReactCommon/hermes/executor/CMakeLists.txt
index a6d8bbac1ddf01..10cf67f5f0e78d 100644
--- a/ReactCommon/hermes/executor/CMakeLists.txt
+++ b/ReactCommon/hermes/executor/CMakeLists.txt
@@ -8,21 +8,22 @@ set(CMAKE_VERBOSE_MAKEFILE on)
 
 file(GLOB_RECURSE hermes_executor_SRC CONFIGURE_DEPENDS *.cpp)
 add_library(
-        hermes-executor-common
+        hermes_executor_common
         STATIC
         ${hermes_executor_SRC}
 )
-target_include_directories(hermes-executor-common PUBLIC .)
-target_link_libraries(hermes-executor-common
+target_include_directories(hermes_executor_common PUBLIC .)
+target_link_libraries(hermes_executor_common
         jsireact
         hermes-engine::libhermes
         jsi
-        debug hermes-inspector
+        debug
+        hermes_inspector
 )
 
 if(${CMAKE_BUILD_TYPE} MATCHES Debug)
         target_compile_options(
-                hermes-executor-common
+                hermes_executor_common
                 PRIVATE
                 -DHERMES_ENABLE_DEBUGGER=1
         )
diff --git a/ReactCommon/hermes/inspector/CMakeLists.txt b/ReactCommon/hermes/inspector/CMakeLists.txt
index 14f6f1ce263900..1b4c6a3b59f4ad 100644
--- a/ReactCommon/hermes/inspector/CMakeLists.txt
+++ b/ReactCommon/hermes/inspector/CMakeLists.txt
@@ -8,20 +8,20 @@ set(CMAKE_VERBOSE_MAKEFILE on)
 
 file(GLOB hermesinspector_SRC CONFIGURE_DEPENDS *.cpp detail/*.cpp chrome/*.cpp)
 
-add_library(hermes-inspector
+add_library(hermes_inspector
         STATIC
         ${hermesinspector_SRC})
 
 target_compile_options(
-        hermes-inspector
+        hermes_inspector
         PRIVATE
         -DHERMES_ENABLE_DEBUGGER=1
         -DHERMES_INSPECTOR_FOLLY_KLUDGE=1
         -fexceptions
 )
 
-target_include_directories(hermes-inspector PUBLIC ${REACT_COMMON_DIR})
-target_link_libraries(hermes-inspector
+target_include_directories(hermes_inspector PUBLIC ${REACT_COMMON_DIR})
+target_link_libraries(hermes_inspector
         jsinspector
         fb
         fbjni
diff --git a/ReactCommon/jsc/.clang-tidy b/ReactCommon/jsc/.clang-tidy
new file mode 100644
index 00000000000000..9f33ef5a06d828
--- /dev/null
+++ b/ReactCommon/jsc/.clang-tidy
@@ -0,0 +1,6 @@
+---
+Checks: '>
+clang-diagnostic-*,
+'
+InheritParentConfig: true
+...
diff --git a/ReactCommon/jsc/BUCK b/ReactCommon/jsc/BUCK
new file mode 100644
index 00000000000000..3981ca830a7bbc
--- /dev/null
+++ b/ReactCommon/jsc/BUCK
@@ -0,0 +1,34 @@
+load("//tools/build_defs/oss:rn_defs.bzl", "APPLE", "IOS", "MACOSX", "get_apple_compiler_flags", "get_apple_inspector_flags", "get_preprocessor_flags_for_build_mode", "react_native_xplat_dep", "rn_xplat_cxx_library")
+
+APPLE_COMPILER_FLAGS = get_apple_compiler_flags()
+
+rn_xplat_cxx_library(
+    name = "JSCRuntime",
+    srcs = [
+        "JSCRuntime.cpp",
+    ],
+    header_namespace = "jsc",
+    exported_headers = [
+        "JSCRuntime.h",
+    ],
+    apple_sdks = (IOS, MACOSX),
+    compiler_flags_pedantic = True,
+    fbobjc_compiler_flags = APPLE_COMPILER_FLAGS + [
+        "-Os",
+    ],
+    fbobjc_frameworks = [
+        "$SDKROOT/System/Library/Frameworks/JavaScriptCore.framework",
+    ],
+    fbobjc_preprocessor_flags = get_preprocessor_flags_for_build_mode() + get_apple_inspector_flags(),
+    labels = [
+        "pfh:ReactNative_CommonInfrastructurePlaceholder",
+    ],
+    platforms = APPLE,
+    visibility = ["PUBLIC"],
+    xplat_mangled_args = {
+        "soname": "libjscjsi.$(ext)",
+    },
+    exported_deps = [
+        react_native_xplat_dep("jsi:jsi"),
+    ],
+)
diff --git a/ReactCommon/jsc/CMakeLists.txt b/ReactCommon/jsc/CMakeLists.txt
new file mode 100644
index 00000000000000..2f387fa996f644
--- /dev/null
+++ b/ReactCommon/jsc/CMakeLists.txt
@@ -0,0 +1,35 @@
+# 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.
+
+##################
+### jscruntime ###
+##################
+
+cmake_minimum_required(VERSION 3.13)
+set(CMAKE_VERBOSE_MAKEFILE on)
+
+add_compile_options(
+        -fexceptions
+        -frtti
+        -O3
+        -Wno-unused-lambda-capture
+        -DLOG_TAG=\"ReactNative\")
+
+add_library(jscruntime
+        STATIC
+        JSCRuntime.h
+        JSCRuntime.cpp)
+
+target_include_directories(jscruntime PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
+
+target_link_libraries(jscruntime
+        folly_runtime
+        jsc
+        jsi
+        glog)
+
+# TODO: Remove this flag when ready.
+# Android has this enabled by default, but the flag is still needed for iOS.
+target_compile_options(jscruntime PRIVATE -DRN_FABRIC_ENABLED)
diff --git a/ReactCommon/jsi/JSCRuntime.cpp b/ReactCommon/jsc/JSCRuntime.cpp
similarity index 100%
rename from ReactCommon/jsi/JSCRuntime.cpp
rename to ReactCommon/jsc/JSCRuntime.cpp
diff --git a/ReactCommon/jsi/JSCRuntime.h b/ReactCommon/jsc/JSCRuntime.h
similarity index 100%
rename from ReactCommon/jsi/JSCRuntime.h
rename to ReactCommon/jsc/JSCRuntime.h
diff --git a/ReactCommon/jsi/React-jsc.podspec b/ReactCommon/jsc/React-jsc.podspec
similarity index 94%
rename from ReactCommon/jsi/React-jsc.podspec
rename to ReactCommon/jsc/React-jsc.podspec
index ce59f0e69e6ac9..6bb2347e57edcc 100644
--- a/ReactCommon/jsi/React-jsc.podspec
+++ b/ReactCommon/jsc/React-jsc.podspec
@@ -28,12 +28,8 @@ Pod::Spec.new do |s|
   s.source_files           = "JSCRuntime.{cpp,h}"
   s.exclude_files          = "**/test/*"
   s.framework              = "JavaScriptCore"
-  s.dependency "React-jsi", version
-  s.default_subspec        = "Default"
 
-  s.subspec "Default" do
-    # no-op
-  end
+  s.dependency "React-jsi", version
 
   s.subspec "Fabric" do |ss|
     ss.pod_target_xcconfig  = { "OTHER_CFLAGS" => "$(inherited) -DRN_FABRIC_ENABLED" }
diff --git a/ReactCommon/jsi/BUCK b/ReactCommon/jsi/BUCK
index 2d5e68fe3de0b6..72d8a39190def5 100644
--- a/ReactCommon/jsi/BUCK
+++ b/ReactCommon/jsi/BUCK
@@ -1,4 +1,4 @@
-load("//tools/build_defs/oss:rn_defs.bzl", "APPLE", "IOS", "MACOSX", "react_native_xplat_dep", "rn_xplat_cxx_library")
+load("//tools/build_defs/oss:rn_defs.bzl", "react_native_xplat_dep", "rn_xplat_cxx_library")
 
 rn_xplat_cxx_library(
     name = "jsi",
@@ -56,33 +56,3 @@ rn_xplat_cxx_library(
         react_native_xplat_dep("jsi:jsi"),
     ],
 )
-
-rn_xplat_cxx_library(
-    name = "JSCRuntime",
-    srcs = [
-        "JSCRuntime.cpp",
-    ],
-    header_namespace = "jsi",
-    exported_headers = [
-        "JSCRuntime.h",
-    ],
-    apple_sdks = (IOS, MACOSX),
-    compiler_flags_pedantic = True,
-    fbobjc_compiler_flags = [
-        "-Os",
-    ],
-    fbobjc_frameworks = [
-        "$SDKROOT/System/Library/Frameworks/JavaScriptCore.framework",
-    ],
-    labels = [
-        "pfh:ReactNative_CommonInfrastructurePlaceholder",
-    ],
-    platforms = APPLE,
-    visibility = ["PUBLIC"],
-    xplat_mangled_args = {
-        "soname": "libjscjsi.$(ext)",
-    },
-    exported_deps = [
-        react_native_xplat_dep("jsi:jsi"),
-    ],
-)
diff --git a/ReactCommon/jsi/CMakeLists.txt b/ReactCommon/jsi/CMakeLists.txt
index 3f2a8c15d3faaa..0967a7d7ee69b1 100644
--- a/ReactCommon/jsi/CMakeLists.txt
+++ b/ReactCommon/jsi/CMakeLists.txt
@@ -25,19 +25,3 @@ target_include_directories(jsi PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
 target_link_libraries(jsi
         folly_runtime
         glog)
-
-##################
-### jscruntime ###
-##################
-
-add_library(jscruntime STATIC
-        JSCRuntime.h
-        JSCRuntime.cpp)
-
-target_include_directories(jscruntime PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
-
-target_link_libraries(jscruntime folly_runtime jsc glog)
-
-# TODO: Remove this flag when ready.
-# Android has this enabled by default, but the flag is still needed for iOS.
-target_compile_options(jscruntime PRIVATE -DRN_FABRIC_ENABLED)
diff --git a/android/README.md b/android/README.md
new file mode 100644
index 00000000000000..613d9a3f28392f
--- /dev/null
+++ b/android/README.md
@@ -0,0 +1,21 @@
+# The `/android` folder inside `react-native`
+
+Starting from React Native 0.71, we're not shipping the `/android` folder inside the React Native NPM package
+anymore due to sizing constraints on NPM. The Android artifacts are distributed via Maven Central.
+You can read more about it in this RFC:
+https://github.com/react-native-community/discussions-and-proposals/pull/508
+
+If you're a library author and you're manipulating the React Native .aar files, to extract headers,
+extract `.so` files or do anything with it, you're probably doing something wrong. React Native
+0.71 ships with all the necessary logic to let you consume it transparently by just using:
+
+```
+implementation("com.facebook.react:react-android")
+// or to keep backward compatibility with older versions of React Native:
+implementation("com.facebook.react:react-native:+")
+```
+
+You should consider refactoring your library code not to unzip/manipulate the React Native .aar files.
+
+This README.md file is kept in this folder as some libraries are checking the existence of the `/android` folder
+and failing user builds if the folder is missing.
diff --git a/packages/react-native-gradle-plugin/build.gradle.kts b/packages/react-native-gradle-plugin/build.gradle.kts
index dd9a08ae099193..b1b2dd61012c83 100644
--- a/packages/react-native-gradle-plugin/build.gradle.kts
+++ b/packages/react-native-gradle-plugin/build.gradle.kts
@@ -33,7 +33,7 @@ group = "com.facebook.react"
 
 dependencies {
   implementation(gradleApi())
-  implementation("com.android.tools.build:gradle:7.3.1")
+  implementation("com.android.tools.build:gradle:7.4.0-beta05")
   implementation("com.google.code.gson:gson:2.8.9")
   implementation("com.google.guava:guava:31.0.1-jre")
   implementation("com.squareup:javapoet:1.13.0")
@@ -50,8 +50,8 @@ dependencies {
 }
 
 java {
-  sourceCompatibility = JavaVersion.VERSION_1_8
-  targetCompatibility = JavaVersion.VERSION_1_8
+  sourceCompatibility = JavaVersion.VERSION_11
+  targetCompatibility = JavaVersion.VERSION_11
 }
 
 tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
diff --git a/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/ReactPlugin.kt b/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/ReactPlugin.kt
index 8538eaa9941d48..af47458d37f50a 100644
--- a/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/ReactPlugin.kt
+++ b/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/ReactPlugin.kt
@@ -14,6 +14,7 @@ import com.facebook.react.tasks.GenerateCodegenArtifactsTask
 import com.facebook.react.tasks.GenerateCodegenSchemaTask
 import com.facebook.react.utils.AgpConfiguratorUtils.configureBuildConfigFields
 import com.facebook.react.utils.AgpConfiguratorUtils.configureDevPorts
+import com.facebook.react.utils.BackwardCompatUtils.configureBackwardCompatibilityReactMap
 import com.facebook.react.utils.DependencyUtils.configureDependencies
 import com.facebook.react.utils.DependencyUtils.configureRepositories
 import com.facebook.react.utils.DependencyUtils.readVersionString
@@ -46,9 +47,12 @@ class ReactPlugin : Plugin<Project> {
       configureReactNativeNdk(project, extension)
       configureBuildConfigFields(project)
       configureDevPorts(project)
+      configureBackwardCompatibilityReactMap(project)
 
-      project.extensions.getByType(AndroidComponentsExtension::class.java).onVariants { variant ->
-        project.configureReactTasks(variant = variant, config = extension)
+      project.extensions.getByType(AndroidComponentsExtension::class.java).apply {
+        onVariants(selector().all()) { variant ->
+          project.configureReactTasks(variant = variant, config = extension)
+        }
       }
       configureCodegen(project, extension, isLibrary = false)
     }
@@ -96,7 +100,8 @@ class ReactPlugin : Plugin<Project> {
           // Please note that appNeedsCodegen is triggering a read of the package.json at
           // configuration time as we need to feed the onlyIf condition of this task.
           // Therefore, the appNeedsCodegen needs to be invoked inside this lambda.
-          it.onlyIf { isLibrary || project.needsCodegenFromPackageJson(extension) }
+          val needsCodegenFromPackageJson = project.needsCodegenFromPackageJson(extension)
+          it.onlyIf { isLibrary || needsCodegenFromPackageJson }
         }
 
     // We create the task to produce schema from JS files.
@@ -120,7 +125,8 @@ class ReactPlugin : Plugin<Project> {
               } else {
                 it.jsRootDir.set(extension.jsRootDir)
               }
-              it.onlyIf { isLibrary || project.needsCodegenFromPackageJson(parsedPackageJson) }
+              val needsCodegenFromPackageJson = project.needsCodegenFromPackageJson(extension)
+              it.onlyIf { isLibrary || needsCodegenFromPackageJson }
             }
 
     // We create the task to generate Java code from schema.
@@ -130,7 +136,6 @@ class ReactPlugin : Plugin<Project> {
               it.dependsOn(generateCodegenSchemaTask)
               it.reactNativeDir.set(extension.reactNativeDir)
               it.nodeExecutableAndArgs.set(extension.nodeExecutableAndArgs)
-              it.codegenDir.set(extension.codegenDir)
               it.generatedSrcDir.set(generatedSrcDir)
               it.packageJsonFile.set(findPackageJsonFile(project, extension))
               it.codegenJavaPackageName.set(extension.codegenJavaPackageName)
@@ -139,7 +144,8 @@ class ReactPlugin : Plugin<Project> {
               // Please note that appNeedsCodegen is triggering a read of the package.json at
               // configuration time as we need to feed the onlyIf condition of this task.
               // Therefore, the appNeedsCodegen needs to be invoked inside this lambda.
-              it.onlyIf { isLibrary || project.needsCodegenFromPackageJson(extension) }
+              val needsCodegenFromPackageJson = project.needsCodegenFromPackageJson(extension)
+              it.onlyIf { isLibrary || needsCodegenFromPackageJson }
             }
 
     // We update the android configuration to include the generated sources.
diff --git a/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/TaskConfiguration.kt b/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/TaskConfiguration.kt
index bb3699d58df095..a2b60f425794d8 100644
--- a/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/TaskConfiguration.kt
+++ b/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/TaskConfiguration.kt
@@ -46,8 +46,7 @@ internal fun Project.configureReactTasks(variant: Variant, config: ReactExtensio
       config.debuggableVariants.get().any { it.equals(variant.name, ignoreCase = true) }
 
   configureNewArchPackagingOptions(project, variant)
-  configureJsEnginePackagingOptions(
-      config, variant, isHermesEnabledInThisVariant, isDebuggableVariant)
+  configureJsEnginePackagingOptions(config, variant, isHermesEnabledInThisVariant)
 
   if (!isDebuggableVariant) {
     val bundleTask =
diff --git a/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/tasks/GenerateCodegenArtifactsTask.kt b/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/tasks/GenerateCodegenArtifactsTask.kt
index 12830982d0cabe..b6003eeb5e14e6 100644
--- a/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/tasks/GenerateCodegenArtifactsTask.kt
+++ b/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/tasks/GenerateCodegenArtifactsTask.kt
@@ -26,8 +26,6 @@ abstract class GenerateCodegenArtifactsTask : Exec() {
 
   @get:Internal abstract val reactNativeDir: DirectoryProperty
 
-  @get:Internal abstract val codegenDir: DirectoryProperty
-
   @get:Internal abstract val generatedSrcDir: DirectoryProperty
 
   @get:InputFile abstract val packageJsonFile: RegularFileProperty
@@ -38,10 +36,6 @@ abstract class GenerateCodegenArtifactsTask : Exec() {
 
   @get:Input abstract val libraryName: Property<String>
 
-  @get:InputFile
-  val combineJsToSchemaCli: Provider<RegularFile> =
-      codegenDir.file("lib/cli/combine/combine-js-to-schema-cli.js")
-
   @get:InputFile
   val generatedSchemaFile: Provider<RegularFile> = generatedSrcDir.file("schema.json")
 
diff --git a/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/BackwardCompatUtils.kt b/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/BackwardCompatUtils.kt
new file mode 100644
index 00000000000000..5c39266900f61c
--- /dev/null
+++ b/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/BackwardCompatUtils.kt
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+package com.facebook.react.utils
+
+import java.util.*
+import org.gradle.api.Project
+
+internal object BackwardCompatUtils {
+
+  fun configureBackwardCompatibilityReactMap(project: Project) {
+    if (project.extensions.extraProperties.has("react")) {
+      @Suppress("UNCHECKED_CAST")
+      val reactMap =
+          project.extensions.extraProperties.get("react") as? Map<String, Any?> ?: mapOf()
+      if (reactMap.isNotEmpty()) {
+        project.logger.error(
+            """
+          ********************************************************************************
+ 
+          ERROR: Using old project.ext.react configuration.
+          We identified that your project is using a old configuration block as:
+          
+          project.ext.react = [
+              // ...
+          ]
+          
+          You should migrate to the new configuration:
+          
+          react {
+              // ...
+          }
+          You can find documentation inside `android/app/build.gradle` on how to use it.
+        
+          ********************************************************************************
+          """
+                .trimIndent())
+      }
+    }
+
+    // We set an empty react[] map so if a library is reading it, they will find empty values.
+    project.extensions.extraProperties.set("react", mapOf<String, String>())
+  }
+}
diff --git a/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/DependencyUtils.kt b/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/DependencyUtils.kt
index d11199ed2cdcf4..c8760f644d8dbe 100644
--- a/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/DependencyUtils.kt
+++ b/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/DependencyUtils.kt
@@ -15,44 +15,57 @@ import org.gradle.api.artifacts.repositories.MavenArtifactRepository
 
 internal object DependencyUtils {
 
+  /**
+   * This method takes care of configuring the repositories{} block for both the app and all the 3rd
+   * party libraries which are auto-linked.
+   */
   fun configureRepositories(project: Project, reactNativeDir: File) {
-    with(project) {
-      if (hasProperty("REACT_NATIVE_MAVEN_LOCAL_REPO")) {
-        mavenRepoFromUrl("file://${property("REACT_NATIVE_MAVEN_LOCAL_REPO")}")
+    project.rootProject.allprojects { eachProject ->
+      with(eachProject) {
+        if (hasProperty("REACT_NATIVE_MAVEN_LOCAL_REPO")) {
+          val mavenLocalRepoPath = property("REACT_NATIVE_MAVEN_LOCAL_REPO") as String
+          mavenRepoFromURI(File(mavenLocalRepoPath).toURI())
+        }
+        // We add the snapshot for users on nightlies.
+        mavenRepoFromUrl("https://oss.sonatype.org/content/repositories/snapshots/")
+        repositories.mavenCentral()
+        // Android JSC is installed from npm
+        mavenRepoFromURI(File(reactNativeDir, "../jsc-android/dist").toURI())
+        repositories.google()
+        mavenRepoFromUrl("https://www.jitpack.io")
       }
-      // We add the snapshot for users on nightlies.
-      mavenRepoFromUrl("https://oss.sonatype.org/content/repositories/snapshots/")
-      repositories.mavenCentral()
-      // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
-      mavenRepoFromUrl("file://${reactNativeDir}/android")
-      // Android JSC is installed from npm
-      mavenRepoFromUrl("file://${reactNativeDir}/../jsc-android/dist")
-      repositories.google()
-      mavenRepoFromUrl("https://www.jitpack.io")
     }
   }
 
+  /**
+   * This method takes care of configuring the resolution strategy for both the app and all the 3rd
+   * party libraries which are auto-linked. Specifically it takes care of:
+   * - Forcing the react-android/hermes-android version to the one specified in the package.json
+   * - Substituting `react-native` with `react-android` and `hermes-engine` with `hermes-android`.
+   */
   fun configureDependencies(project: Project, versionString: String) {
     if (versionString.isBlank()) return
-    project.configurations.all { configuration ->
-      // Here we set a dependencySubstitution for both react-native and hermes-engine as those
-      // coordinates are voided due to https://github.com/facebook/react-native/issues/35210
-      // This allows users to import libraries that are still using
-      // implementation("com.facebook.react:react-native:+") and resolve the right dependency.
-      configuration.resolutionStrategy.dependencySubstitution {
-        it.substitute(it.module("com.facebook.react:react-native"))
-            .using(it.module("com.facebook.react:react-android:${versionString}"))
-            .because(
-                "The react-native artifact was deprecated in favor of react-android due to https://github.com/facebook/react-native/issues/35210.")
-        it.substitute(it.module("com.facebook.react:hermes-engine"))
-            .using(it.module("com.facebook.react:hermes-android:${versionString}"))
-            .because(
-                "The hermes-engine artifact was deprecated in favor of hermes-android due to https://github.com/facebook/react-native/issues/35210.")
+    project.rootProject.allprojects { eachProject ->
+      eachProject.configurations.all { configuration ->
+        // Here we set a dependencySubstitution for both react-native and hermes-engine as those
+        // coordinates are voided due to https://github.com/facebook/react-native/issues/35210
+        // This allows users to import libraries that are still using
+        // implementation("com.facebook.react:react-native:+") and resolve the right dependency.
+        configuration.resolutionStrategy.dependencySubstitution {
+          it.substitute(it.module("com.facebook.react:react-native"))
+              .using(it.module("com.facebook.react:react-android:${versionString}"))
+              .because(
+                  "The react-native artifact was deprecated in favor of react-android due to https://github.com/facebook/react-native/issues/35210.")
+          it.substitute(it.module("com.facebook.react:hermes-engine"))
+              .using(it.module("com.facebook.react:hermes-android:${versionString}"))
+              .because(
+                  "The hermes-engine artifact was deprecated in favor of hermes-android due to https://github.com/facebook/react-native/issues/35210.")
+        }
+        configuration.resolutionStrategy.force(
+            "com.facebook.react:react-android:${versionString}",
+            "com.facebook.react:hermes-android:${versionString}",
+        )
       }
-      configuration.resolutionStrategy.force(
-          "com.facebook.react:react-android:${versionString}",
-          "com.facebook.react:hermes-android:${versionString}",
-      )
     }
   }
 
@@ -70,4 +83,7 @@ internal object DependencyUtils {
 
   fun Project.mavenRepoFromUrl(url: String): MavenArtifactRepository =
       project.repositories.maven { it.url = URI.create(url) }
+
+  fun Project.mavenRepoFromURI(uri: URI): MavenArtifactRepository =
+      project.repositories.maven { it.url = uri }
 }
diff --git a/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/NdkConfiguratorUtils.kt b/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/NdkConfiguratorUtils.kt
index 479c3f742eda99..9d0e6b9740c8e4 100644
--- a/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/NdkConfiguratorUtils.kt
+++ b/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/NdkConfiguratorUtils.kt
@@ -112,36 +112,25 @@ internal object NdkConfiguratorUtils {
       config: ReactExtension,
       variant: Variant,
       hermesEnabled: Boolean,
-      debuggableVariant: Boolean
   ) {
     if (config.enableSoCleanup.get()) {
-      val (excludes, includes) = getPackagingOptionsForVariant(hermesEnabled, debuggableVariant)
+      val (excludes, includes) = getPackagingOptionsForVariant(hermesEnabled)
       variant.packaging.jniLibs.excludes.addAll(excludes)
       variant.packaging.jniLibs.pickFirsts.addAll(includes)
     }
   }
 
-  fun getPackagingOptionsForVariant(
-      hermesEnabled: Boolean,
-      debuggableVariant: Boolean
-  ): Pair<List<String>, List<String>> {
+  fun getPackagingOptionsForVariant(hermesEnabled: Boolean): Pair<List<String>, List<String>> {
     val excludes = mutableListOf<String>()
     val includes = mutableListOf<String>()
     if (hermesEnabled) {
       excludes.add("**/libjsc.so")
       excludes.add("**/libjscexecutor.so")
       includes.add("**/libhermes.so")
-      if (debuggableVariant) {
-        excludes.add("**/libhermes-executor-release.so")
-        includes.add("**/libhermes-executor-debug.so")
-      } else {
-        excludes.add("**/libhermes-executor-debug.so")
-        includes.add("**/libhermes-executor-release.so")
-      }
+      includes.add("**/libhermes_executor.so")
     } else {
       excludes.add("**/libhermes.so")
-      excludes.add("**/libhermes-executor-debug.so")
-      excludes.add("**/libhermes-executor-release.so")
+      excludes.add("**/libhermes_executor.so")
       includes.add("**/libjsc.so")
       includes.add("**/libjscexecutor.so")
     }
diff --git a/react.gradle b/react.gradle
index da5505975a0c78..250299bb78359f 100644
--- a/react.gradle
+++ b/react.gradle
@@ -442,11 +442,11 @@ afterEvaluate {
 
                     if (cleanup) {
                         // Reduce size by deleting the debugger/inspector
-                        include '**/libhermes-executor-debug.so'
+                        include '**/libhermes_executor_debug.so'
                     } else {
                         // Release libs take precedence and must be removed
                         // to allow debugging
-                        include '**/libhermes-executor-release.so'
+                        include '**/libhermes_executor_release.so'
                     }
                 } else {
                     // For JSC, delete all the libhermes* files
diff --git a/scripts/cocoapods/jsengine.rb b/scripts/cocoapods/jsengine.rb
index 48a20e6a156307..7f941c127ccbfa 100644
--- a/scripts/cocoapods/jsengine.rb
+++ b/scripts/cocoapods/jsengine.rb
@@ -11,9 +11,9 @@
 # @parameter fabric_enabled: whether Fabirc is enabled
 def setup_jsc!(react_native_path: "../node_modules/react-native", fabric_enabled: false)
     pod 'React-jsi', :path => "#{react_native_path}/ReactCommon/jsi"
-    pod 'React-jsc', :path => "#{react_native_path}/ReactCommon/jsi"
+    pod 'React-jsc', :path => "#{react_native_path}/ReactCommon/jsc"
     if fabric_enabled
-        pod 'React-jsc/Fabric', :path => "#{react_native_path}/ReactCommon/jsi"
+        pod 'React-jsc/Fabric', :path => "#{react_native_path}/ReactCommon/jsc"
     end
 end
 
diff --git a/template/android/build.gradle b/template/android/build.gradle
index 4631930d4a5c42..baa44e144bbac1 100644
--- a/template/android/build.gradle
+++ b/template/android/build.gradle
@@ -15,7 +15,7 @@ buildscript {
         mavenCentral()
     }
     dependencies {
-        classpath("com.android.tools.build:gradle:7.3.1")
+        classpath("com.android.tools.build:gradle:7.4.0-beta05")
         classpath("com.facebook.react:react-native-gradle-plugin")
     }
 }


Test patch:
diff --git a/packages/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/tasks/GenerateCodegenArtifactsTaskTest.kt b/packages/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/tasks/GenerateCodegenArtifactsTaskTest.kt
index 86f45fec3207d8..e188e47c849525 100644
--- a/packages/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/tasks/GenerateCodegenArtifactsTaskTest.kt
+++ b/packages/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/tasks/GenerateCodegenArtifactsTaskTest.kt
@@ -29,28 +29,16 @@ class GenerateCodegenArtifactsTaskTest {
     val codegenDir = tempFolder.newFolder("codegen")
     val outputDir = tempFolder.newFolder("output")
 
-    val task =
-        createTestTask<GenerateCodegenArtifactsTask> {
-          it.codegenDir.set(codegenDir)
-          it.generatedSrcDir.set(outputDir)
-        }
+    val task = createTestTask<GenerateCodegenArtifactsTask> { it.generatedSrcDir.set(outputDir) }
 
-    assertEquals(
-        File(codegenDir, "lib/cli/combine/combine-js-to-schema-cli.js"),
-        task.combineJsToSchemaCli.get().asFile)
     assertEquals(File(outputDir, "schema.json"), task.generatedSchemaFile.get().asFile)
   }
 
   @Test
   fun generateCodegenSchema_outputFile_isSetCorrectly() {
-    val codegenDir = tempFolder.newFolder("codegen")
     val outputDir = tempFolder.newFolder("output")
 
-    val task =
-        createTestTask<GenerateCodegenArtifactsTask> {
-          it.codegenDir.set(codegenDir)
-          it.generatedSrcDir.set(outputDir)
-        }
+    val task = createTestTask<GenerateCodegenArtifactsTask> { it.generatedSrcDir.set(outputDir) }
 
     assertEquals(File(outputDir, "java"), task.generatedJavaFiles.get().asFile)
     assertEquals(File(outputDir, "jni"), task.generatedJniFiles.get().asFile)
@@ -80,13 +68,11 @@ class GenerateCodegenArtifactsTaskTest {
   @WithOs(OS.LINUX)
   fun setupCommandLine_willSetupCorrectly() {
     val reactNativeDir = tempFolder.newFolder("node_modules/react-native/")
-    val codegenDir = tempFolder.newFolder("codegen")
     val outputDir = tempFolder.newFolder("output")
 
     val task =
         createTestTask<GenerateCodegenArtifactsTask> {
           it.reactNativeDir.set(reactNativeDir)
-          it.codegenDir.set(codegenDir)
           it.generatedSrcDir.set(outputDir)
           it.nodeExecutableAndArgs.set(listOf("--verbose"))
         }
diff --git a/packages/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/BackwardCompatUtilsTest.kt b/packages/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/BackwardCompatUtilsTest.kt
new file mode 100644
index 00000000000000..da08d88ad06a71
--- /dev/null
+++ b/packages/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/BackwardCompatUtilsTest.kt
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+package com.facebook.react.utils
+
+import com.facebook.react.tests.createProject
+import com.facebook.react.utils.BackwardCompatUtils.configureBackwardCompatibilityReactMap
+import org.junit.Assert.assertTrue
+import org.junit.Rule
+import org.junit.Test
+import org.junit.rules.TemporaryFolder
+
+class BackwardCompatUtilsTest {
+
+  @get:Rule val tempFolder = TemporaryFolder()
+
+  @Test
+  fun configureBackwardCompatibilityReactMap_addsEmptyReactMap() {
+    val project = createProject()
+
+    configureBackwardCompatibilityReactMap(project)
+
+    assertTrue(project.extensions.extraProperties.has("react"))
+    @Suppress("UNCHECKED_CAST")
+    assertTrue((project.extensions.extraProperties.get("react") as Map<String, Any?>).isEmpty())
+  }
+
+  @Test
+  fun configureBackwardCompatibilityReactMap_withExistingMapSetByUser_wipesTheMap() {
+    val project = createProject()
+    project.extensions.extraProperties.set("react", mapOf("enableHermes" to true))
+
+    configureBackwardCompatibilityReactMap(project)
+
+    assertTrue(project.extensions.extraProperties.has("react"))
+    @Suppress("UNCHECKED_CAST")
+    assertTrue((project.extensions.extraProperties.get("react") as Map<String, Any?>).isEmpty())
+  }
+}
diff --git a/packages/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/DependencyUtilsTest.kt b/packages/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/DependencyUtilsTest.kt
index 4386e33233d36e..1b7c728cc4b4f6 100644
--- a/packages/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/DependencyUtilsTest.kt
+++ b/packages/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/DependencyUtilsTest.kt
@@ -10,10 +10,12 @@ package com.facebook.react.utils
 import com.facebook.react.tests.createProject
 import com.facebook.react.utils.DependencyUtils.configureDependencies
 import com.facebook.react.utils.DependencyUtils.configureRepositories
+import com.facebook.react.utils.DependencyUtils.mavenRepoFromURI
 import com.facebook.react.utils.DependencyUtils.mavenRepoFromUrl
 import com.facebook.react.utils.DependencyUtils.readVersionString
 import java.net.URI
 import org.gradle.api.artifacts.repositories.MavenArtifactRepository
+import org.gradle.testfixtures.ProjectBuilder
 import org.junit.Assert.*
 import org.junit.Rule
 import org.junit.Test
@@ -26,9 +28,9 @@ class DependencyUtilsTest {
   @Test
   fun configureRepositories_withProjectPropertySet_configuresMavenLocalCorrectly() {
     val localMaven = tempFolder.newFolder("m2")
-    val localMavenURI = URI.create("file://$localMaven/")
+    val localMavenURI = localMaven.toURI()
     val project = createProject()
-    project.extensions.extraProperties.set("REACT_NATIVE_MAVEN_LOCAL_REPO", localMaven)
+    project.extensions.extraProperties.set("REACT_NATIVE_MAVEN_LOCAL_REPO", localMaven.absolutePath)
 
     configureRepositories(project, tempFolder.root)
 
@@ -51,21 +53,6 @@ class DependencyUtilsTest {
         })
   }
 
-  @Test
-  fun configureRepositories_containsReactNativeNpmLocalMavenRepo() {
-    val projectFolder = tempFolder.newFolder()
-    val reactNativeDir = tempFolder.newFolder("react-native")
-    val repositoryURI = URI.create("file://${reactNativeDir}/android")
-    val project = createProject(projectFolder)
-
-    configureRepositories(project, reactNativeDir)
-
-    assertNotNull(
-        project.repositories.firstOrNull {
-          it is MavenArtifactRepository && it.url == repositoryURI
-        })
-  }
-
   @Test
   fun configureRepositories_containsJscLocalMavenRepo() {
     val projectFolder = tempFolder.newFolder()
@@ -124,10 +111,10 @@ class DependencyUtilsTest {
   @Test
   fun configureRepositories_withProjectPropertySet_hasHigherPriorityThanMavenCentral() {
     val localMaven = tempFolder.newFolder("m2")
-    val localMavenURI = URI.create("file://$localMaven/")
+    val localMavenURI = localMaven.toURI()
     val mavenCentralURI = URI.create("https://repo.maven.apache.org/maven2/")
     val project = createProject()
-    project.extensions.extraProperties.set("REACT_NATIVE_MAVEN_LOCAL_REPO", localMaven)
+    project.extensions.extraProperties.set("REACT_NATIVE_MAVEN_LOCAL_REPO", localMaven.absolutePath)
 
     configureRepositories(project, tempFolder.root)
 
@@ -161,6 +148,46 @@ class DependencyUtilsTest {
     assertTrue(indexOfSnapshotRepo < indexOfMavenCentral)
   }
 
+  @Test
+  fun configureRepositories_appliesToAllProjects() {
+    val repositoryURI = URI.create("https://repo.maven.apache.org/maven2/")
+    val rootProject = ProjectBuilder.builder().build()
+    val appProject = ProjectBuilder.builder().withName("app").withParent(rootProject).build()
+    val libProject = ProjectBuilder.builder().withName("lib").withParent(rootProject).build()
+
+    configureRepositories(appProject, tempFolder.root)
+
+    assertNotNull(
+        appProject.repositories.firstOrNull {
+          it is MavenArtifactRepository && it.url == repositoryURI
+        })
+    assertNotNull(
+        libProject.repositories.firstOrNull {
+          it is MavenArtifactRepository && it.url == repositoryURI
+        })
+  }
+
+  @Test
+  fun configureRepositories_withPreviousExclusionRulesOnMavenCentral_appliesCorrectly() {
+    val repositoryURI = URI.create("https://repo.maven.apache.org/maven2/")
+    val rootProject = ProjectBuilder.builder().build()
+    val appProject = ProjectBuilder.builder().withName("app").withParent(rootProject).build()
+    val libProject = ProjectBuilder.builder().withName("lib").withParent(rootProject).build()
+
+    // Let's emulate a library which set an `excludeGroup` on `com.facebook.react` for Central.
+    libProject.repositories.mavenCentral { repo ->
+      repo.content { content -> content.excludeGroup("com.facebook.react") }
+    }
+
+    configureRepositories(appProject, tempFolder.root)
+
+    // We need to make sure we have Maven Central defined twice, one by the library,
+    // and another is the override by RNGP.
+    assertEquals(
+        2,
+        libProject.repositories.count { it is MavenArtifactRepository && it.url == repositoryURI })
+  }
+
   @Test
   fun configureDependencies_withEmptyVersion_doesNothing() {
     val project = createProject()
@@ -181,6 +208,24 @@ class DependencyUtilsTest {
     assertTrue(forcedModules.any { it.toString() == "com.facebook.react:hermes-android:1.2.3" })
   }
 
+  @Test
+  fun configureDependencies_withVersionString_appliesOnAllProjects() {
+    val rootProject = ProjectBuilder.builder().build()
+    val appProject = ProjectBuilder.builder().withName("app").withParent(rootProject).build()
+    val libProject = ProjectBuilder.builder().withName("lib").withParent(rootProject).build()
+    appProject.plugins.apply("com.android.application")
+    libProject.plugins.apply("com.android.library")
+
+    configureDependencies(appProject, "1.2.3")
+
+    val appForcedModules = appProject.configurations.first().resolutionStrategy.forcedModules
+    val libForcedModules = libProject.configurations.first().resolutionStrategy.forcedModules
+    assertTrue(appForcedModules.any { it.toString() == "com.facebook.react:react-android:1.2.3" })
+    assertTrue(appForcedModules.any { it.toString() == "com.facebook.react:hermes-android:1.2.3" })
+    assertTrue(libForcedModules.any { it.toString() == "com.facebook.react:react-android:1.2.3" })
+    assertTrue(libForcedModules.any { it.toString() == "com.facebook.react:hermes-android:1.2.3" })
+  }
+
   @Test
   fun readVersionString_withCorrectVersionString_returnsIt() {
     val propertiesFile =
@@ -253,4 +298,13 @@ class DependencyUtilsTest {
 
     assertEquals(URI.create("https://hello.world"), mavenRepo.url)
   }
+
+  @Test
+  fun mavenRepoFromURI_worksCorrectly() {
+    val process = createProject()
+    val repoFolder = tempFolder.newFolder("maven-repo")
+    val mavenRepo = process.mavenRepoFromURI(repoFolder.toURI())
+
+    assertEquals(repoFolder.toURI(), mavenRepo.url)
+  }
 }
diff --git a/packages/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/NdkConfiguratorUtilsTest.kt b/packages/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/NdkConfiguratorUtilsTest.kt
index 2d0093c6a565d2..bf2f27926ab357 100644
--- a/packages/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/NdkConfiguratorUtilsTest.kt
+++ b/packages/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/NdkConfiguratorUtilsTest.kt
@@ -15,70 +15,28 @@ import org.junit.Test
 class NdkConfiguratorUtilsTest {
 
   @Test
-  fun getPackagingOptionsForVariant_withHermesEnabled_andDebuggableVariant() {
-    val (excludes, includes) =
-        getPackagingOptionsForVariant(hermesEnabled = true, debuggableVariant = true)
+  fun getPackagingOptionsForVariant_withHermesEnabled() {
+    val (excludes, includes) = getPackagingOptionsForVariant(hermesEnabled = true)
 
     assertTrue("**/libjsc.so" in excludes)
     assertTrue("**/libjscexecutor.so" in excludes)
-    assertTrue("**/libhermes-executor-release.so" in excludes)
     assertFalse("**/libjsc.so" in includes)
     assertFalse("**/libjscexecutor.so" in includes)
-    assertFalse("**/libhermes-executor-release.so" in includes)
 
     assertTrue("**/libhermes.so" in includes)
-    assertTrue("**/libhermes-executor-debug.so" in includes)
+    assertTrue("**/libhermes_executor.so" in includes)
     assertFalse("**/libhermes.so" in excludes)
-    assertFalse("**/libhermes-executor-debug.so" in excludes)
+    assertFalse("**/libhermes_executor.so" in excludes)
   }
 
   @Test
-  fun getPackagingOptionsForVariant_withHermesEnabled_andNonDebuggableVariant() {
-    val (excludes, includes) =
-        getPackagingOptionsForVariant(hermesEnabled = true, debuggableVariant = false)
-
-    assertTrue("**/libjsc.so" in excludes)
-    assertTrue("**/libjscexecutor.so" in excludes)
-    assertTrue("**/libhermes-executor-debug.so" in excludes)
-    assertFalse("**/libjsc.so" in includes)
-    assertFalse("**/libjscexecutor.so" in includes)
-    assertFalse("**/libhermes-executor-debug.so" in includes)
-
-    assertTrue("**/libhermes.so" in includes)
-    assertTrue("**/libhermes-executor-release.so" in includes)
-    assertFalse("**/libhermes.so" in excludes)
-    assertFalse("**/libhermes-executor-release.so" in excludes)
-  }
-
-  @Test
-  fun getPackagingOptionsForVariant_withHermesDisabled_andDebuggableVariant() {
-    val (excludes, includes) =
-        getPackagingOptionsForVariant(hermesEnabled = false, debuggableVariant = true)
-
-    assertTrue("**/libhermes.so" in excludes)
-    assertTrue("**/libhermes-executor-debug.so" in excludes)
-    assertTrue("**/libhermes-executor-release.so" in excludes)
-    assertFalse("**/libhermes.so" in includes)
-    assertFalse("**/libhermes-executor-debug.so" in includes)
-    assertFalse("**/libhermes-executor-release.so" in includes)
-
-    assertTrue("**/libjsc.so" in includes)
-    assertTrue("**/libjscexecutor.so" in includes)
-    assertFalse("**/libjsc.so" in excludes)
-    assertFalse("**/libjscexecutor.so" in excludes)
-  }
-
-  @Test
-  fun getPackagingOptionsForVariant_withHermesDisabled_andNonDebuggableVariant() {
-    val (excludes, includes) =
-        getPackagingOptionsForVariant(hermesEnabled = false, debuggableVariant = false)
+  fun getPackagingOptionsForVariant_withHermesDisabled() {
+    val (excludes, includes) = getPackagingOptionsForVariant(hermesEnabled = false)
 
     assertTrue("**/libhermes.so" in excludes)
-    assertTrue("**/libhermes-executor-debug.so" in excludes)
-    assertTrue("**/libhermes-executor-release.so" in excludes)
+    assertTrue("**/libhermes_executor.so" in excludes)
     assertFalse("**/libhermes.so" in includes)
-    assertFalse("**/libhermes-executor-debug.so" in includes)
-    assertFalse("**/libhermes-executor-release.so" in includes)
+    assertFalse("**/libhermes_executor.so" in includes)
 
     assertTrue("**/libjsc.so" in includes)
     assertTrue("**/libjscexecutor.so" in includes)
diff --git a/packages/rn-tester/RNTesterPods.xcodeproj/project.pbxproj b/packages/rn-tester/RNTesterPods.xcodeproj/project.pbxproj
index 73488e795ff4e0..6ed49246169050 100644
--- a/packages/rn-tester/RNTesterPods.xcodeproj/project.pbxproj
+++ b/packages/rn-tester/RNTesterPods.xcodeproj/project.pbxproj
@@ -412,6 +412,7 @@
 				5CF0FD27207FC6EC00C13D65 /* Start Metro */,
 				2FCDFB64B37634EC8EC3139B /* [CP] Embed Pods Frameworks */,
 				A8DE6393E2BB72D8FBBF6C27 /* [CP] Copy Pods Resources */,
+				992FB5A50F2847F7EB2C285C /* [RN] Copy Hermes Framework */,
 			);
 			buildRules = (
 			);
@@ -696,6 +697,24 @@
 			shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests-resources.sh\"\n";
 			showEnvVarsInLog = 0;
 		};
+		992FB5A50F2847F7EB2C285C /* [RN] Copy Hermes Framework */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputFileListPaths = (
+			);
+			inputPaths = (
+			);
+			name = "[RN] Copy Hermes Framework";
+			outputFileListPaths = (
+			);
+			outputPaths = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = ". ../../sdks/hermes-engine/utils/copy-hermes-xcode.sh";
+		};
 		9A596313B3964A4DEB794409 /* [CP] Copy Pods Resources */ = {
 			isa = PBXShellScriptBuildPhase;
 			buildActionMask = 2147483647;
diff --git a/scripts/cocoapods/__tests__/jsengine-test.rb b/scripts/cocoapods/__tests__/jsengine-test.rb
index 14c76d0c6d810c..ef18a72c6be0fb 100644
--- a/scripts/cocoapods/__tests__/jsengine-test.rb
+++ b/scripts/cocoapods/__tests__/jsengine-test.rb
@@ -44,7 +44,7 @@ def test_setupJsc_installsPods
         # Assert
         assert_equal($podInvocationCount, 2)
         assert_equal($podInvocation["React-jsi"][:path], "../../ReactCommon/jsi")
-        assert_equal($podInvocation["React-jsc"][:path], "../../ReactCommon/jsi")
+        assert_equal($podInvocation["React-jsc"][:path], "../../ReactCommon/jsc")
     end
 
     def test_setupJsc_installsPods_installsFabricSubspecWhenFabricEnabled
@@ -57,8 +57,8 @@ def test_setupJsc_installsPods_installsFabricSubspecWhenFabricEnabled
         # Assert
         assert_equal($podInvocationCount, 3)
         assert_equal($podInvocation["React-jsi"][:path], "../../ReactCommon/jsi")
-        assert_equal($podInvocation["React-jsc"][:path], "../../ReactCommon/jsi")
-        assert_equal($podInvocation["React-jsc/Fabric"][:path], "../../ReactCommon/jsi")
+        assert_equal($podInvocation["React-jsc"][:path], "../../ReactCommon/jsc")
+        assert_equal($podInvocation["React-jsc/Fabric"][:path], "../../ReactCommon/jsc")
     end
 
     # ================== #