feat: agp v9 adoption - #1006
Conversation
Updated AGP v9 adoption proposal with changes for React Native core and community libraries, including Gradle upgrades and migration patterns.
|
The RFC looks great, thanks for putting it together! I've already started working on AGP9 support on the Expo side and opened a few PRs. Most things are working well, but I've hit a few unexpected issues that'll need more work. For instance, we have some custom Apollo client configuration in the dev-launcher that stopped working. I'll share more once I figure out how to fix it. |
|
One random thought: what do you guys think about creating a |
This sounds like a nice idea and could help with one part of the migration, but after thinking about it more, I’m not sure it would add enough value on its own. Even with a kotlin-android-compat plugin, library authors would still need to handle a few manual migration steps:
The custom plugin could dynamically apply kotlin-android for AGP < 9, which is useful. But it cannot really solve the case where the consuming project has already applied kotlin-android, because we can apply plugins programmatically, but we can’t safely “unapply” a plugin that was already applied by the build script. So in practice, the plugin would cover only one part of the migration: conditionally applying kotlin-android for AGP 8 and below. The removal of kotlin-android for AGP 9+, plus the other DSL/source-set migrations, would still require manual changes from library authors. Because of that, I think the value might be relatively limited. |
|
Yes, I agree it won't solve every problem - realistically, this will still require some manual changes from library maintainers. But other changes, such as using |
True that. So If I catch it correctly, the library maintainers will need to replace the For some libraries, this might be the only change that they need, for eg, I am also wondering whether to introduce a separate compat plugin OR we can add this as a fallback mechanism to RNGP? That way the library authors may not need to implement another plugin. Nicola suggested that we can also think of separating library implementations from RNGP in a separate Gradle plugin, however that is optional for now and we will start that separately than AGP 9. I am mentioning it here because if we are able to add this compat mechanism to RNGP, we can later extract it out.
Yes it should work, however there are a few catches. The kotlin-only sources can not be added to |
cortinico
left a comment
There was a problem hiding this comment.
Great RFC @hurali97 (sorry for the late review).
I've left some comments. I know that @lukmccall @Kudo have some updates on the Expo front to share also
|
|
||
| In Phase 2, we will submit compatibility pull requests to actively used and maintained libraries from the matrix above while preserving backward compatibility. Broader ecosystem coverage will require community participation. | ||
|
|
||
| As part of Phase 2, the Expo team will evaluate required changes on their side, including ecosystem impact. |
There was a problem hiding this comment.
Was there an update on this front? @lukmccall @Kudo ?
There was a problem hiding this comment.
On our side, we're ready. All Expo code should work with AGP 9 and be compatible with build-in Kotlin. There might be some leftovers that I missed. I'll retest everything whenever RN officially starts supporting AGP 9.
There was a problem hiding this comment.
On our side, we're ready
How is expo going to handle the removal of the opt-out?
There was a problem hiding this comment.
From the module's perspective, the Expo Gradle plugin handles all 3 cases: AGP 8, AGP 9 with built-in Kotlin opted out, and AGP 9 with built-in Kotlin support.
For users who use CNG, we'll apply the changes in the app template automatically. For the rest, they'll have to adjust their apps themselves (we can't do anything more here).
There was a problem hiding this comment.
@lukmccall My question was more related to the 3p libraries that have imports of kotlin-android which will break the build (once we remove the opt-out)
There was a problem hiding this comment.
Yeah exactly. Can we expand the RFC with the kotlin-android-compat plugin and how we're planning to distribute it? cc @hurali97
There was a problem hiding this comment.
We can expand the RFC, but we’ll need details on how Expo plans to publish and handle the usage of this plugin. cc: @lukmccall
Additionally, I think this plugin should remain optional, especially for non Expo projects. If library maintainers have already added backward compatibility for AGP v9 or simply prefer to manage it manually, they should be free to do so.
We should also highlight this in the upcoming React Native blog post section on AGP v9 adoption: developers can either use the compatibility plugin or handle backward compatibility themselves.
There was a problem hiding this comment.
We can expand the RFC, but we’ll need details on how Expo plans to publish and handle the usage of this plugin
Hmm, I think we should publish that plugin to Maven under the React Foundation - similar to how React Native is published. Publishing it under Expo seems weird, as in our case we don't need it at all. However, if you think that would be easier, we can handle it on our side.
Additionally, I think this plugin should remain optional, especially for non Expo projects. If library maintainers have already added backward compatibility for AGP v9 or simply prefer to manage it manually, they should be free to do so.
I agree that the plugin should remain optional
There was a problem hiding this comment.
Hmm, I think we should publish that plugin to Maven under the React Foundation - similar to how React Native is published. Publishing it under Expo seems weird, as in our case we don't need it at all. However, if you think that would be easier, we can handle it on our side.
If we're planning to land a separate library plugin anyway, we could bundle the kotlin-android-compat logic directly into it rather than publishing a separate plugin. Since tomorrow's draft PR for separate library plugin will likely need a few iterations. Publishing the standalone kotlin-android-compat plugin first might be the faster route. However, if we're flexible with the timeline, encapsulating that logic inside library plugin and have only this applied by the consumers. cc: @cortinico
There was a problem hiding this comment.
If we're planning to land a separate library plugin anyway, we could bundle the kotlin-android-compat logic directly into it rather than publishing a separate plugin
Yes ideally that's the preferred outcome.
|
|
||
| As described above, AGP v9 adoption is rolled out in three phases. Phase 1 is complete and should ship with React Native v0.87.x. Newly created apps do not need changes because template opt-outs are enabled by default. Existing apps upgrading to v0.87.x should apply a few manual updates described in the next section. At this stage, we expect no breakages with actively maintained community libraries. | ||
|
|
||
| In Phase 2, we will submit compatibility pull requests to actively used and maintained libraries from the matrix above while preserving backward compatibility. Broader ecosystem coverage will require community participation. |
There was a problem hiding this comment.
while preserving backward compatibility
This is the key of the whole proposal. I'm wondering how can we update libraries to don't apply kotlin-android while still retaining backward compat.
In the past we talked about a com.facebook.react.library Gradle Plugin that is versioned outside the react/react-native repo. Is this something we're still interested in driving?
If so let's add it in this RFC. cc @lukmccall @Kudo
There was a problem hiding this comment.
We can apply kotlin-android conditionally using our own Gradle plugin - it would look like this: https://github.com/expo/expo/blob/7d1359bd667168ca9ae64afc17058e558df23163/packages/expo-modules-core/expo-module-gradle-plugin/src/main/kotlin/expo/modules/plugin/ProjectConfiguration.kt#L23-L33. Not sure if we should combine this RFC with the RN turbomodules Gradle plugin. Maybe it would be better to publish kotlin-android-compat first to only address the AGP migration, as proposed above: #1006 (comment)
There was a problem hiding this comment.
On our end, as part of a POC, we've separated the Gradle setup into RNGP for app consumption and com.facebook.react.library for library consumption. This separation currently lives in RN Core, but it can be extracted. I need a bit of time to finalize the implementation and open a draft PR, after which we can align on the exact structure.
A few key points on this approach:
Backward Compatibility: I’ve kept this backward compatible for now, meaning libraries can still apply RNGP. Though whether we maintain this fallback is open for debate.
Plugin Integration: A clear benefit is that we can directly apply the kotlin-android-compat plugin inside com.facebook.react.library for libraries to use.
One caveat for AGP 9 compatibility: even with the compat plugin, library maintainers will still need to manually remove the kotlin-android plugin.
|
|
||
| As part of Phase 2, the Expo team will evaluate required changes on their side, including ecosystem impact. | ||
|
|
||
| Phase 2 needs sufficient time, especially for community adoption. One possible support mechanism is adding an "AGP v9 compatible" filter in `react-native-community/directory` to track progress. |
There was a problem hiding this comment.
If possible I would avoid the extra filter in the directory (that should be doable if we implement this in being fully backward compat).
## Description <!-- Description and motivation for this PR. Include 'Fixes #<number>' if this is fixing some issue. --> This PR is rasied following the second phase of the RFC around AGP v9 adoption: RFC: react-native-community/discussions-and-proposals#1006 The gist of this PR is to make Gesture Handler AGP v9 compliant with backward compatibility. The main scope of changes is the `react-native-gesture-handler/android/build.gradle`. The rest of the changes can be considered temporary. The rest changes include: - Making Basic Example App AGP9 compliant - Upgrade `Gradle` to `v9.4.1` - Use `proguard-android-optimize` proguard file - Enable opt outs in the `gradle.properties` Ideally, we should not enable the opt outs and leverage the AGP 9 built-in kotlin and newDSL. However, if we do not do it, then other libraries which are not yet AGP v9 compliant starts to fail. Hence, we need to keep the opt outs enabled for a while. For the context, react-native starting from 0.87.x will ship with AGP v9 and opt outs enabled by default for the new apps, which is the first phase of AGP v9 adoption. With the second phase when the libraries starts adoption AGP v9, we can eventually remove the opt outs from Basic Example. ## Test plan <!-- Describe how did you test this change here. --> To test this PR, we need to do a few steps: - Set the `agp` version to `9.2.1` and `kotlin` to `2.2.0` in `react-native-gradle-plugin` ```diff --- a/node_modules/@react-native/gradle-plugin/gradle/libs.versions.toml +++ b/node_modules/@react-native/gradle-plugin/gradle/libs.versions.toml @@ -1,10 +1,10 @@ [versions] -agp = "8.12.0" +agp = "9.2.1" gson = "2.8.9" -kotlin = "2.1.20" +kotlin = "2.2.0" assertj = "3.25.1" ``` - Comment out the following functions in `react-native-gradle-plugin` ```diff --- a/node_modules/@react-native/gradle-plugin/react-native-gradle-plugin/ReactPlugin.kt +++ b/node_modules/@react-native/gradle-plugin/react-native-gradle-plugin/ReactPlugin.kt @@ -1,10 +1,10 @@ configureBuildTypesForApp(project) } // Library Only Configuration - configureBuildConfigFieldsForLibraries(project) - configureNamespaceForLibraries(project) + // configureBuildConfigFieldsForLibraries(project) + // configureNamespaceForLibraries(project) project.pluginManager.withPlugin("com.android.library") { ``` This step is only required because we have RN version on 0.85.2 and `AGP` + `kotlin` bump will be shipped with 0.87.x. <details> <summary>Verified by locally patching Reanimated and Worklet, making those AGP v9 compliant and removing the opt outs to test the changes in the PR </summary> https://github.com/user-attachments/assets/7f4f571a-6bef-4694-9b32-330571c0c734 </details> <details> <summary>Verified these changes work with AGP 8 </summary> https://github.com/user-attachments/assets/116a0b2e-23f5-499c-8a64-b99f927165c4 </details> --------- Co-authored-by: Michał <michal.bert@swmansion.com>
Proposal: Android Gradle Plugin v9 Adoption
View the rendered RFC