Skip to content

fix: build example APK with new architecture (RN 0.84)#621

Open
gre wants to merge 7 commits intomasterfrom
fix/ci-apk-new-arch
Open

fix: build example APK with new architecture (RN 0.84)#621
gre wants to merge 7 commits intomasterfrom
fix/ci-apk-new-arch

Conversation

@gre
Copy link
Copy Markdown
Owner

@gre gre commented Apr 8, 2026

Summary

Override newArchEnabled=true for the CI APK build only, via the -P Gradle flag.

  • gradle.properties keeps newArchEnabled=false for Detox E2E compatibility (unchanged)
  • The CI APK now builds with new arch, which is required for RN 0.84

Context

PR #618 attempted this same fix in isolation but it never worked — because react-native.config.js was also broken (wrong project key instead of dependency.platforms), so the native module wasn't linked at all. That was fixed in #620. This PR adds the missing piece: the APK now builds with new arch so TurboModuleRegistry can find RNViewShot and PlatformConstants.

Test plan

  • CI APK build succeeds
  • Download APK artifact and verify all example screens work on Android

🤖 Generated with Claude Code

RN 0.84 doesn't reliably support old arch. The gradle.properties keeps
newArchEnabled=false for Detox E2E compat, so override it with
-PnewArchEnabled=true only for the CI APK artifact.

Together with the react-native.config.js fix (#620), this should resolve
the PlatformConstants TurboModuleRegistry crash on Android.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 8, 2026 15:16
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the CI workflow that builds the example Android release APK so it explicitly enables React Native’s New Architecture for that build, aligning the CI artifact with RN 0.84’s expectations while keeping local/Detox settings unchanged.

Changes:

  • Pass -PnewArchEnabled=true to the assembleRelease Gradle invocation in the APK build workflow.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

gre and others added 6 commits April 8, 2026 17:44
The package has "type": "module" in package.json, so .js files are treated
as ESM. The @react-native-community/cli uses cosmiconfigSync (require())
to load the config synchronously during Android/Gradle builds, which cannot
load ESM modules — it silently falls back to an empty config, causing
RNViewShotPackage to be excluded from autolinking entirely.

Renaming to .cjs forces CJS semantics regardless of the "type" field,
so cosmiconfigSync can load it correctly via require().

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Platform was imported but never used. This dead import forced eager
evaluation of Platform.android.js → NativePlatformConstantsAndroid.js
→ TurboModuleRegistry.getEnforcing('PlatformConstants') at module load
time, which could be problematic in some initialization contexts.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…n new arch Android

In React Native new arch on Android, class components can render on the
mqt_v_native thread. Metro's lazy require system defers module evaluation
until first access — so `<View>` in ViewShot.render() triggers the View
lazy getter on that thread, which cascades through NativePlatformConstantsAndroid
calling TurboModuleRegistry.getEnforcing('PlatformConstants'), crashing.

Accessing `void View` at module level forces the lazy require chain to run
eagerly on the main JS thread during module initialization, so by the time
render() is called on mqt_v_native, View is already fully loaded.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… crash on new arch Android"

This reverts commit c14d863.
In React Native new arch on Android, class components can trigger lazy
loading of react-native's View module on a thread where PlatformConstants
is not accessible, causing a crash: TurboModuleRegistry.getEnforcing(
'PlatformConstants') could not be found.

Functional components render on the main JS thread where TurboModules are
fully accessible. Converting ViewShot to use forwardRef + hooks avoids
the problematic lazy require chain entirely.

- Exposes capture() via useImperativeHandle (ref API unchanged)
- Preserves static ViewShot.captureRef and ViewShot.releaseCapture
- Exports ViewShotRef type for typed ref usage
- Replicates componentDidMount/Update/WillUnmount semantics with effects

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The "react-native" field was set to a Windows platform config object
instead of the source entry point string. Metro uses this field to resolve
the library's entry point for React Native bundles — with an object value
it silently fell back to "main": "lib/index.js" (the compiled output)
instead of the TypeScript source.

This caused hooks to misbehave in the release bundle (TypeError: Cannot
read property 'useRef' of null) because the compiled lib/ output interacts
differently with Metro's inline-requires optimization than the raw source.

The Windows platform config already lives in react-native.config.cjs where
it belongs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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.

2 participants