Skip to content

fix(android): detect newArchEnabled at subproject scope#1037

Open
jmalmo wants to merge 1 commit into
mrousavy:mainfrom
jmalmo:fix/android-newarch-subproject-scope
Open

fix(android): detect newArchEnabled at subproject scope#1037
jmalmo wants to merge 1 commit into
mrousavy:mainfrom
jmalmo:fix/android-newarch-subproject-scope

Conversation

@jmalmo
Copy link
Copy Markdown

@jmalmo jmalmo commented May 4, 2026

What I changed

I switched isNewArchitectureEnabled() in packages/react-native-mmkv/android/build.gradle from rootProject.hasProperty(...) to project.hasProperty(...). One-line diff.

Why

Same root cause as mrousavy/nitro#1314, which I opened earlier today. react-native-mmkv carries its own copy of the gate (line 18) — it was copied from Nitrogen's packages/template/android/build.gradle at bootstrap time, not regenerated by Nitrogen on each build, so the nitro PR's fix to the template doesn't reach already-published consumers of mmkv. This PR closes the gap on mmkv specifically.

I hit this on a fresh React Native 0.83 / Expo SDK 55 dev-client app with react-native-mmkv@^4 and react-native-nitro-modules installed. bun android failed at :app:configureCMakeDebug[arm64-v8a]:

CMake Error at .../Android-autolinking.cmake:
  add_subdirectory given source
  ".../node_modules/react-native-mmkv/android/build/generated/source/codegen/jni/"
  which is not an existing directory.

After digging in: on RN >= 0.82 the new architecture is mandatory and newArchEnabled is no longer required to live in gradle.properties. React Native's ReactRootProjectPlugin instead sets the property on each subproject's extraProperties. The current rootProject-scoped check misses that path — the lib silently skips apply plugin: "com.facebook.react", no codegen tasks register, and the consumer build dies during CMake configure. The same trap fires after a stale, non---clean Expo prebuild where gradle.properties stays put and never picks up the new template's content.

project.hasProperty(...) covers both paths without dropping legacy-arch support:

  • RN >= 0.82 — finds the property via ReactRootProjectPlugin's subproject extraProperties.
  • Legacy RN with explicit opt-ingradle.properties values propagate to every project, so project.hasProperty(...) still returns true.
  • Legacy RN without opt-in — neither scope carries the property and the gate stays closed (consistent with prior behavior).

Test plan

I considered pinning the regression by removing newArchEnabled=true from example/android/gradle.properties (the same approach I used in mrousavy/nitro#1314). However, react-native-mmkv depends on react-native-nitro-modules@0.35.6 from npm, which still carries the un-fixed legacy gate at the same line. Without the property in gradle.properties, the example app fails at :app:configureCMakeDebug because of nitro's missing codegen, not mmkv's — verified locally:

> Task :react-native-mmkv:generateCodegenArtifactsFromSchema  ← my fix lets this run
...
> Task :app:configureCMakeDebug[arm64-v8a] FAILED
add_subdirectory given source ".../react-native-nitro-modules/android/build/generated/source/codegen/jni/" which is not an existing directory.

So the regression-pin test will only become viable once nitro PR #1314 ships in a tagged release and mmkv bumps the dep. I'd be happy to send a follow-up PR removing the property at that point.

What I did verify locally with the property restored (i.e. the current PR state):

cd example/android
./gradlew assembleDebug --no-daemon --build-cache

Result: BUILD SUCCESSFUL in 44s. :react-native-mmkv:generateCodegenArtifactsFromSchema ran, :react-native-mmkv:configureCMakeDebug[arm64-v8a] succeeded, and the example app built end-to-end. The fix doesn't regress the green path.

Other checks:

  • bun install — green.
  • bun typecheck — green.
  • bun lint — green.
  • bun run test — 4 / 4 Jest specs pass.
  • No nitrogen regen needed (gradle-only change; run-nitrogen.yml doesn't trigger on **/*.gradle* paths).

Notes

  • Targets main. No nitrogen output changes, no spec/test removals, no unrelated edits.
  • Coordinated with mrousavy/nitro#1314 — both PRs together close the user-visible repro on RN 0.83 / Expo SDK 55. Either one alone is a partial fix.

`isNewArchitectureEnabled()` reads `rootProject.hasProperty("newArchEnabled")`.
On RN >= 0.82 with Expo SDK 55 the new architecture is mandatory and the
property is no longer required to live in `android/gradle.properties`;
React Native's `ReactRootProjectPlugin` instead sets `newArchEnabled=true`
on each subproject's `extraProperties`. The rootProject-scoped check
therefore returns false in that scenario, the library skips
`apply plugin: "com.facebook.react"`, no codegen tasks register, and the
consumer build fails at `:app:configureCMakeDebug` referencing the
missing `node_modules/react-native-mmkv/android/build/generated/source/codegen/jni/`.

Switch the helper to `project.hasProperty("newArchEnabled")`. That
covers both the RN >= 0.82 path (subproject extraProperties) and the
legacy explicit-opt-in path (`gradle.properties` values propagate to
every project), without dropping legacy-arch support.

Same fix and rationale as mrousavy/nitro#1314, applied to mmkv's own
build.gradle which carries an independent copy of the gate from
Nitrogen's `packages/template` at bootstrap time.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant