The short version: moving from Android Gradle plugin 9.4 to 9.5.0 (October 2026) changes almost nothing in your build files. The compatibility table is the same in both releases: Gradle 9.6.0 minimum, JDK 17, SDK Build Tools 36.0.0, NDK 28.2.13676358 by default, and API level 37 as the highest supported. If you are already on AGP 9.4 with Gradle 9.6, the hop is a one-line version change plus a check for the Configuration.setVisible deprecation. If you come from older pins, such as React Native 0.88.1’s AGP 9.2.1 with Gradle 9.4.1, the Gradle wrapper has to move first.
Checked on 8 Nov 2026 against the AGP 9.5.0 and AGP 9.4.0 release notes, the Gradle 9.6.0 release notes and the Android Dev Summit tools post of 28 Oct. We also read the build files inside the react-native 0.88.1 and 0.89.0-rc.0 npm packages, their community templates and @react-native/gradle-plugin 0.88.1, and Google’s android/nowinandroid at commit 2982e63.
Why we did this: BMDB on Android TV, Peepal and Shopkeeper are Kotlin projects on AGP 9.x, and our React Native banking app inherits the React Native template’s Gradle setup. The upgrade order is the same for all four, so we wrote it down once.
One correction before you start
Our own radar ticket for this post assumed AGP 9.5 raised the minimum Gradle version to 9.6.0. It didn’t. The 9.4.0 notes already list Gradle 9.6.0 as the minimum and default, with JDK 17, Build Tools 36.0.0 and NDK 28.2.13676358. Both pages say: “The maximum API level that Android Gradle plugin 9.x supports is API level 37.”
So if your project builds on 9.4 today, it already meets every 9.5 floor.
What the builds we checked pin today

We read these from the npm tarballs and a shallow clone, not from a build:
- React Native 0.88.1 and 0.89.0-rc.0 both pin
agp = "9.2.1"ingradle/libs.versions.toml. 0.89.0-rc.0 movestargetSdkfrom 36 to 37 and the NDK from 27.1.12297006 to 28.2.13676358. @react-native/gradle-plugin0.88.1 also pinsagp = "9.2.1". The template’sbuild.gradleasks forcom.android.tools.build:gradlewith no version, so the plugin’s pin is what an app gets.- The 0.88.1 template’s wrapper is Gradle 9.4.1, and the 0.89.0-rc.0 template’s wrapper is still 9.4.1. Both are below the 9.6.0 that AGP 9.4 and 9.5 require. The 0.88.1 template’s
gradle.propertiesalso setsandroid.newDsl=falseandandroid.builtInKotlin=false. - nowinandroid pins AGP 9.3.2 with Gradle 9.7.1,
compileSdk = 37andtargetSdk = 36.
For a React Native app, this means AGP 9.5 is an override you choose, not something React Native ships. If you set it, the Gradle wrapper must go to 9.6.0 or later in the same commit.
Upgrade steps

- Confirm JDK 17 or later for Gradle and Android Studio. The floor did not change. The 9.5 notes fix a warning in
generateReleaseRFile“when using JDK 25” (issue 553121473), so JDK 25 is in use out there. - Move the Gradle wrapper to 9.6.0 (or later). Code below.
- Bump AGP in your version catalog, or in the root
buildscriptfor a React Native app. Code below. - Keep
compileSdkat 37 or below. That is the ceiling for both 9.4 and 9.5. - Sync, build, then fix deprecation warnings (next section).
- Run the R8 Configuration Analyzer on the release variant.
Steps 2 and 3 in code
The wrapper command from the Gradle 9.6 notes:
./gradlew :wrapper --gradle-version=9.6.0 && ./gradlew :wrapper
# Before: gradle/wrapper/gradle-wrapper.properties (RN 0.88.1 template)
distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.1-bin.zip
# After
distributionUrl=https\://services.gradle.org/distributions/gradle-9.6.0-bin.zip
A plain Kotlin project with a version catalog:
# Before: gradle/libs.versions.toml
[versions]
agp = "9.4.1"
# After
[versions]
agp = "9.5.0"
A React Native app, where the root build.gradle takes AGP’s version from the RN Gradle plugin:
// android/build.gradle (React Native app)
dependencies {
classpath("com.android.tools.build:gradle:9.5.0") // was unversioned: RN pins 9.2.1
classpath("com.facebook.react:react-native-gradle-plugin")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin")
}
What changed in AGP 9.5
The 9.5.0 notes list no removed or renamed DSL entries and no changed gradle.properties defaults. What they do list:
Configuration.setVisible is deprecated
From the fixed issues (560282299): “The Configuration.setVisible(boolean) method has been deprecated”. Issue 565740572 adds that “Gradle 9.8.0 reports Configuration.setVisible() deprecations with AGP 9.4.1”. If a convention plugin or build.gradle.kts sets visibility on a configuration, delete the call:
// Before: build-logic convention plugin
configurations.create("lintChecksBundle") {
isVisible = false
isCanBeConsumed = false
}
// After: drop isVisible; keep the role flags
configurations.create("lintChecksBundle") {
isCanBeConsumed = false
}
We grepped @react-native/gradle-plugin 0.88.1 and nowinandroid’s build-logic for isVisible = and setVisible(. There were no hits in either.
Fixes worth knowing about
- 556343682: AGP 9.3.0’s
optimization { enable = true }DSL “does not set isMinifyEnabled in the ApplicationVariant object”. This is fixed in 9.5. If you adopted the new DSL in 9.3 or 9.4 and have a plugin that readsisMinifyEnabled, recheck it after upgrading. - 532206373:
l8DexDesugarLibrewrote the obfuscation mapping as a 25-byte stub. This is fixed in 9.5. If you ship core library desugaring with R8, compare your uploadedmapping.txtsizes before and after. - 550220873: a 9.2.0 regression where
LibraryExtension.getSourceSets()caused aClassCastException. This is fixed in 9.5.
Experimental: backup and restore tests
9.5 adds a testOptions.backupTests block behind two flags:
# gradle.properties
android.experimental.testSuiteSupport=true
android.experimental.enableBackupTest=true
Carried over from 9.4: two things that become mandatory in AGP 10
The 9.4.0 notes give advance warning of two AGP 10 changes:
- “Starting with AGP 10, the new Variant API is mandatory for all projects.” For now, a module can opt out with
android.newDsl.optOut=:module-nameingradle.properties. The React Native 0.88.1 template setsandroid.newDsl=falseproject-wide, so RN apps are the ones to watch when AGP 10 lands. - Dynamic feature modules must match the app’s variants 1:1. In 9.4 this is a warning, and
android.enforceDynamicFeatureVariantMatching=truemakes it an error. “From AGP 10.0 onwards, strict 1:1 variant parity will become enforced by default.” Turning the flag on now shows you the mismatches early.
Gradle 9.6: the parent-project lookup warning
Gradle 9.6.0 (released 18 June 2026) deprecates implicit property and method lookup in parent projects. Its notes say it “now emits a warning and will be removed in Gradle 10”. The warning also covers findProperty(), property() and hasProperty() when the value is resolved from a parent project. To fail early instead, enable the NO_IMPLICIT_LOOKUP_IN_PARENT_PROJECTS feature preview in settings.gradle(.kts).
This matters for React Native. In @react-native/gradle-plugin 0.88.1 we counted 29 calls to hasProperty(, findProperty( or .property(" in the Kotlin sources. Four of them read from project.rootProject explicitly, and the rest read from the module project, for flags like newArchEnabled, hermesEnabled and reactNativeArchitectures. Whether those produce the new warning depends on where your app defines the property. We have not run a build to see. This is an inference from the two pages, not a result.
The R8 Configuration Analyzer
The Android Dev Summit tools post says the analyzer is “now built into AGP 9.3”. It “scores your R8 configuration and ranks your keep rules by how much they cost you”. Run it with:
./gradlew :app:analyzeReleaseR8Config
The 9.4 and 9.5 notes don’t mention it, so on 9.5 it behaves as described for 9.3. The blog gives no report format, and we have not run it on our apps yet.
How we checked, and what is not run
- Release notes: AGP 9.5.0 and 9.4.0, Gradle 9.6.0, and the Android Dev Summit tools post, read on 8 Nov 2026. The Gradle 9.x upgrade guide blocks automated fetches, so its breaking-change list is not covered here.
- Sources:
npm packof react-native 0.87.1, 0.88.1 and 0.89.0-rc.0,@react-native-community/template0.88.1 and 0.89.0-rc.0-4f3db58, and@react-native/gradle-plugin0.88.1. We diffedgradle/libs.versions.toml, the template’sbuild.gradle,gradle.propertiesand wrapper. We also ran a shallowgit cloneofandroid/nowinandroid(2982e63, 20 Oct 2026). All of this was in a Linux container. - Not run: no Gradle build, sync or R8 analysis, on our projects or anyone else’s. Running steps 2 to 6 on Peepal and on the RN banking app is our next step, and we will add build times and the analyzer’s findings here when we have them.



