From f28ea8994747bf532c7a1758d60e41704d2ae3dc Mon Sep 17 00:00:00 2001 From: Kudo Chien Date: Fri, 29 Nov 2024 00:07:48 +0800 Subject: [PATCH 1/4] RFC: lean-core-jsc --- proposals/0836-lean-core-jsc.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 proposals/0836-lean-core-jsc.md diff --git a/proposals/0836-lean-core-jsc.md b/proposals/0836-lean-core-jsc.md new file mode 100644 index 00000000..96d6cd4e --- /dev/null +++ b/proposals/0836-lean-core-jsc.md @@ -0,0 +1,33 @@ +--- +title: Extract JSC (JavaScriptCore) from React Native Core +author: +- Kudo Chien +date: 2024-11-28 +--- + +# RFC0836: Extract JSC (JavaScriptCore) from React Native Core + +## Summary + +This RFC proposes a Lean Core effort to extract JSC (JavaScriptCore) from React Native's core. + +## Proposed Changes and Timeline + +- Version 0.77: Remove the [`jsc-android` npm dependency](https://github.com/facebook/react-native/blob/2d337efc23c662143b3f39a6c994d80fec047054/packages/react-native/package.json#L132) from React Native and instead download the artifact from Maven Central. When using Hermes, downloading the unused npm dependency is unnecessary and removing it saves about 32 MB of uncompressed size. +- Version 0.78 or 0.79: Introduce a new `react-native-javascriptcore` npm package with a newer version of JavaScriptCore for Android. In this version, we will only provide the [Intl variant](https://github.com/react-native-community/jsc-android-buildscripts/blob/9c61fece4753902a2cd6d29dfa46b7b521f0c821/README.md#international-variant), as newer JavaScriptCore versions do not support disabling Intl. The existing JSCRuntime from the core should still function with this version but will display a deprecation warning during build time. A challenge will be managing the core JSCRuntime alongside the third-party JSCRuntime from `react-native-javascriptcore`; further study is required. +- Version 0.80: Completely remove JavaScriptCore from the core: + - Eliminate `JSCRuntime` code. + - Deprecate Gradle's `hermesEnabled` and Podfile's `hermes_enabled`, making them no-ops. + - Update documentation at https://reactnative.dev/docs/hermes. + +## Motivation + +Since Hermes has become the dominant JavaScript engine in the React Native ecosystem, it is inefficient to include unused JavaScriptCore code and binaries in the core. By extracting JavaScriptCore to a separate, third-party maintained library, we can streamline the core and reduce unnecessary bloat. + +## Adoption strategy + +We will offer a drop-in replacement with the `react-native-javascriptcore` npm package while maintaining JSC support in the core for two additional React Native releases to ensure a smooth transition. + +## How we teach this + +We will announce the upcoming changes in the version 0.77 release notes and provide guidance for developers on migrating to the new `react-native-javascriptcore` package. From f57bb733ce713ef358dfb899ee174f1d9ad3d831 Mon Sep 17 00:00:00 2001 From: Kudo Chien Date: Mon, 20 Jan 2025 00:14:07 -0800 Subject: [PATCH 2/4] Apply suggestions from code review --- proposals/0836-lean-core-jsc.md | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/proposals/0836-lean-core-jsc.md b/proposals/0836-lean-core-jsc.md index 96d6cd4e..892e06f0 100644 --- a/proposals/0836-lean-core-jsc.md +++ b/proposals/0836-lean-core-jsc.md @@ -1,7 +1,7 @@ --- title: Extract JSC (JavaScriptCore) from React Native Core author: -- Kudo Chien + - Kudo Chien date: 2024-11-28 --- @@ -13,12 +13,13 @@ This RFC proposes a Lean Core effort to extract JSC (JavaScriptCore) from React ## Proposed Changes and Timeline -- Version 0.77: Remove the [`jsc-android` npm dependency](https://github.com/facebook/react-native/blob/2d337efc23c662143b3f39a6c994d80fec047054/packages/react-native/package.json#L132) from React Native and instead download the artifact from Maven Central. When using Hermes, downloading the unused npm dependency is unnecessary and removing it saves about 32 MB of uncompressed size. -- Version 0.78 or 0.79: Introduce a new `react-native-javascriptcore` npm package with a newer version of JavaScriptCore for Android. In this version, we will only provide the [Intl variant](https://github.com/react-native-community/jsc-android-buildscripts/blob/9c61fece4753902a2cd6d29dfa46b7b521f0c821/README.md#international-variant), as newer JavaScriptCore versions do not support disabling Intl. The existing JSCRuntime from the core should still function with this version but will display a deprecation warning during build time. A challenge will be managing the core JSCRuntime alongside the third-party JSCRuntime from `react-native-javascriptcore`; further study is required. -- Version 0.80: Completely remove JavaScriptCore from the core: - - Eliminate `JSCRuntime` code. - - Deprecate Gradle's `hermesEnabled` and Podfile's `hermes_enabled`, making them no-ops. +- Version 0.78: Remove the [`jsc-android` npm dependency](https://github.com/facebook/react-native/blob/2d337efc23c662143b3f39a6c994d80fec047054/packages/react-native/package.json#L132) from React Native and instead download the artifact from Maven Central. When using Hermes, downloading the unused npm dependency is unnecessary and removing it saves about 32 MB of uncompressed build time size. +- Version 0.80: Introduce a new `react-native-javascriptcore` npm package with a newer version of JavaScriptCore for Android. In this version, we will only provide the [Intl variant](https://github.com/react-native-community/jsc-android-buildscripts/blob/9c61fece4753902a2cd6d29dfa46b7b521f0c821/README.md#international-variant), as newer JavaScriptCore versions do not support disabling Intl. The existing JSCRuntime from the core should still function with this version but will display a deprecation warning during build time. A challenge will be managing the core JSCRuntime alongside the third-party JSCRuntime from `react-native-javascriptcore`; details will be mentioned in the [Mixing `JSCRuntime` from core and third-party](#mixing-jscruntime-from-core-and-third-party) section. + - Could we support `react-native-javascriptcore` only on New Architecture mode? +- Version 0.82: Completely remove JavaScriptCore from the core: + - Eliminate `JSCRuntime` code and drop `useThirdPartyJSC` support. - Update documentation at https://reactnative.dev/docs/hermes. + - At this point, React Native will stop JSCRuntime testing from core. All the integration testing effort should move into the `react-native-javascriptcore` repository. ## Motivation @@ -28,6 +29,20 @@ Since Hermes has become the dominant JavaScript engine in the React Native ecosy We will offer a drop-in replacement with the `react-native-javascriptcore` npm package while maintaining JSC support in the core for two additional React Native releases to ensure a smooth transition. +### Mixing `JSCRuntime` from core and third-party + +Originally, the `hermesEnabled` in Android's **gradle.properties** and `hermes_enabled` in iOS's **Podfile** take two responsibilities. One is to create the Hermes bytecode bundle. The other is to choose JSCRuntime over HermesRuntime. During the transition period, we will introduce a `useThirdPartyJSC` flag for **gradle.properties** and `ENV['useThirdPartyJSC']` for CocoaPods. When `useThirdPartyJSC` is enabled, React Native will not link the `JSCRuntime` from core. + +### Setup guide for `react-native-javascriptcore` + +A rough idea to set up `react-native-javascriptcore`: + +1. `yarn add react-native-javascriptcore` +2. Set `hermesEnabled=false` +3. Add `useThirdPartyJSC=true` on React Native 0.80~0.82 +4. On Android, update MainApplication to support custom JSRuntimeFactory for JSC +5. TODO: On iOS, there are some challenges since `createJSRuntimeFactory()` requires C++ integration and we now have AppDelegate.swift. We could try to abstract the `createJSRuntimeFactory()` to an Objective-C interface first, so that people can pass their own JSRuntimeFactory through Swift. I will study some approaches and update this part later. + ## How we teach this -We will announce the upcoming changes in the version 0.77 release notes and provide guidance for developers on migrating to the new `react-native-javascriptcore` package. +We will announce the upcoming changes in the version 0.80 release notes and provide guidance for developers on migrating to the new `react-native-javascriptcore` package. After version 0.82, the core will no longer support JSCRuntime and no more integration testing will be done in the core. All the integration testing effort should move into the `react-native-javascriptcore` repository. From a88603c0c3301f489d981ea53b3a21202d02938a Mon Sep 17 00:00:00 2001 From: Nicola Corti Date: Fri, 7 Feb 2025 15:22:47 +0000 Subject: [PATCH 3/4] Update proposals/0836-lean-core-jsc.md --- proposals/0836-lean-core-jsc.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/0836-lean-core-jsc.md b/proposals/0836-lean-core-jsc.md index 892e06f0..ba377dae 100644 --- a/proposals/0836-lean-core-jsc.md +++ b/proposals/0836-lean-core-jsc.md @@ -13,7 +13,7 @@ This RFC proposes a Lean Core effort to extract JSC (JavaScriptCore) from React ## Proposed Changes and Timeline -- Version 0.78: Remove the [`jsc-android` npm dependency](https://github.com/facebook/react-native/blob/2d337efc23c662143b3f39a6c994d80fec047054/packages/react-native/package.json#L132) from React Native and instead download the artifact from Maven Central. When using Hermes, downloading the unused npm dependency is unnecessary and removing it saves about 32 MB of uncompressed build time size. +- Version 0.77: Remove the [`jsc-android` npm dependency](https://github.com/facebook/react-native/blob/2d337efc23c662143b3f39a6c994d80fec047054/packages/react-native/package.json#L132) from React Native and instead download the artifact from Maven Central. When using Hermes, downloading the unused npm dependency is unnecessary and removing it saves about 32 MB of uncompressed build time size. - Version 0.80: Introduce a new `react-native-javascriptcore` npm package with a newer version of JavaScriptCore for Android. In this version, we will only provide the [Intl variant](https://github.com/react-native-community/jsc-android-buildscripts/blob/9c61fece4753902a2cd6d29dfa46b7b521f0c821/README.md#international-variant), as newer JavaScriptCore versions do not support disabling Intl. The existing JSCRuntime from the core should still function with this version but will display a deprecation warning during build time. A challenge will be managing the core JSCRuntime alongside the third-party JSCRuntime from `react-native-javascriptcore`; details will be mentioned in the [Mixing `JSCRuntime` from core and third-party](#mixing-jscruntime-from-core-and-third-party) section. - Could we support `react-native-javascriptcore` only on New Architecture mode? - Version 0.82: Completely remove JavaScriptCore from the core: From a758c9495569224d2014b55bb0c1b0c7d29311f0 Mon Sep 17 00:00:00 2001 From: Kudo Chien Date: Thu, 27 Feb 2025 19:03:34 +0800 Subject: [PATCH 4/4] Update 0836-lean-core-jsc.md --- proposals/0836-lean-core-jsc.md | 35 ++++++++++++++++----------------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/proposals/0836-lean-core-jsc.md b/proposals/0836-lean-core-jsc.md index ba377dae..547cdac4 100644 --- a/proposals/0836-lean-core-jsc.md +++ b/proposals/0836-lean-core-jsc.md @@ -13,13 +13,14 @@ This RFC proposes a Lean Core effort to extract JSC (JavaScriptCore) from React ## Proposed Changes and Timeline -- Version 0.77: Remove the [`jsc-android` npm dependency](https://github.com/facebook/react-native/blob/2d337efc23c662143b3f39a6c994d80fec047054/packages/react-native/package.json#L132) from React Native and instead download the artifact from Maven Central. When using Hermes, downloading the unused npm dependency is unnecessary and removing it saves about 32 MB of uncompressed build time size. -- Version 0.80: Introduce a new `react-native-javascriptcore` npm package with a newer version of JavaScriptCore for Android. In this version, we will only provide the [Intl variant](https://github.com/react-native-community/jsc-android-buildscripts/blob/9c61fece4753902a2cd6d29dfa46b7b521f0c821/README.md#international-variant), as newer JavaScriptCore versions do not support disabling Intl. The existing JSCRuntime from the core should still function with this version but will display a deprecation warning during build time. A challenge will be managing the core JSCRuntime alongside the third-party JSCRuntime from `react-native-javascriptcore`; details will be mentioned in the [Mixing `JSCRuntime` from core and third-party](#mixing-jscruntime-from-core-and-third-party) section. - - Could we support `react-native-javascriptcore` only on New Architecture mode? -- Version 0.82: Completely remove JavaScriptCore from the core: - - Eliminate `JSCRuntime` code and drop `useThirdPartyJSC` support. - - Update documentation at https://reactnative.dev/docs/hermes. - - At this point, React Native will stop JSCRuntime testing from core. All the integration testing effort should move into the `react-native-javascriptcore` repository. +- **Version 0.78**: Remove the [`jsc-android` npm dependency](https://github.com/facebook/react-native/blob/2d337efc23c662143b3f39a6c994d80fec047054/packages/react-native/package.json#L132) from React Native and instead download the artifact from Maven Central. When using Hermes, downloading the unused npm dependency is unnecessary and removing it saves about 32 MB of uncompressed build time size. +- **Version 0.79**: Introduce the community [`@react-native-community/javascriptcore`](https://github.com/react-native-community/javascriptcore) package, allowing developers to begin migrating from core JSC to the community-maintained version. Using the core JSC will trigger a build-time warning about its upcoming removal: + - React Native core will reduce its [testing support](https://github.com/reactwg/react-native-releases/blob/main/docs/guide-release-testing.md#dimensions-to-test) for JSC. + - The community JSC package will include basic end-to-end tests. +- **Version 0.80**: The `@react-native-community/javascriptcore` package will offer a newer JSC version on Android that may support modern JavaScript language features, such as [`BigInt`](https://github.com/react-native-community/jsc-android-buildscripts/pull/169). In this updated `jsc-android`, only the [`Intl` variant](https://github.com/react-native-community/jsc-android-buildscripts/blob/9c61fece4753902a2cd6d29dfa46b7b521f0c821/README.md#international-variant) will be provided because newer JavaScriptCore versions do not support disabling `Intl` The core JSC remains available in this version with a build-time warning: + - Update documentation at https://reactnative.dev/docs/hermes to recommend the community JSC. +- **Version 0.81 or 0.82**: Completely remove JSC from the core: + - Eliminate `JSCRuntime` code and drop support for `useThirdPartyJSC`. ## Motivation @@ -27,22 +28,20 @@ Since Hermes has become the dominant JavaScript engine in the React Native ecosy ## Adoption strategy -We will offer a drop-in replacement with the `react-native-javascriptcore` npm package while maintaining JSC support in the core for two additional React Native releases to ensure a smooth transition. +We will offer a drop-in replacement with the [`@react-native-community/javascriptcore`](https://github.com/react-native-community/javascriptcore) package while maintaining JSC support in the core for two additional React Native releases to ensure a smooth transition. -### Mixing `JSCRuntime` from core and third-party +> [!NOTE] +> The community JSC will only support New Architecture mode. -Originally, the `hermesEnabled` in Android's **gradle.properties** and `hermes_enabled` in iOS's **Podfile** take two responsibilities. One is to create the Hermes bytecode bundle. The other is to choose JSCRuntime over HermesRuntime. During the transition period, we will introduce a `useThirdPartyJSC` flag for **gradle.properties** and `ENV['useThirdPartyJSC']` for CocoaPods. When `useThirdPartyJSC` is enabled, React Native will not link the `JSCRuntime` from core. +### Mixing `JSCRuntime` from core and third-party -### Setup guide for `react-native-javascriptcore` +Originally, the `hermesEnabled` flag in Android's **gradle.properties** and `hermes_enabled` flag in iOS's **Podfile** served two purposes: creating the Hermes bytecode bundle and selecting JSCRuntime over HermesRuntime. During the transition period, we will introduce a `useThirdPartyJSC` flag in **gradle.properties** and `ENV['USE_THIRD_PARTY_JSC']` in CocoaPods. When `useThirdPartyJSC` is enabled, React Native will not link the core `JSCRuntime`. -A rough idea to set up `react-native-javascriptcore`: +### Setup guide for `@react-native-community/javascriptcore` -1. `yarn add react-native-javascriptcore` -2. Set `hermesEnabled=false` -3. Add `useThirdPartyJSC=true` on React Native 0.80~0.82 -4. On Android, update MainApplication to support custom JSRuntimeFactory for JSC -5. TODO: On iOS, there are some challenges since `createJSRuntimeFactory()` requires C++ integration and we now have AppDelegate.swift. We could try to abstract the `createJSRuntimeFactory()` to an Objective-C interface first, so that people can pass their own JSRuntimeFactory through Swift. I will study some approaches and update this part later. +Refer to the [README from `@react-native-community/javascriptcore for setup instructions](https://github.com/react-native-community/javascriptcore/blob/main/README.md). ## How we teach this -We will announce the upcoming changes in the version 0.80 release notes and provide guidance for developers on migrating to the new `react-native-javascriptcore` package. After version 0.82, the core will no longer support JSCRuntime and no more integration testing will be done in the core. All the integration testing effort should move into the `react-native-javascriptcore` repository. +- We will announce the upcoming changes in the version 0.79 release notes and provide guidance for developers on migrating to the new `@react-native-community/javascriptcore` package. +- A build-time warning in React Native will notify users about the upcoming lean core changes regarding JSC.