Skip to content

fix(react-native): remove import cycles that crash under Metro's import transform and fix autolinking builds - #397

Merged
KishanPRao merged 4 commits into
mainfrom
bugfix/react-native-import-cycles-and-autolinking
Sep 29, 2026
Merged

KishanPRao merged 4 commits into
mainfrom
bugfix/react-native-import-cycles-and-autolinking

Conversation

@melekr

@melekr melekr commented Sep 25, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Fixes two issues reported on @backtrace/react-native 0.2.2.

  • Breadcrumbs crash: TypeError: Cannot read property 'prototype' of undefined under Metro's experimentalImportSupport without inline requires. Cause: circular imports (storage → package barrel, client ↔ builder). Metro's static import transform snapshots bindings of modules that are still evaluating.
  • Autolinking compile failures on Expo Android, React Native 0.82+, and iOS with dynamic frameworks. Cause: Gradle namespace not matching the Java package, New Architecture property read from the root project, missing static_framework in the podspec.

Changes

react-native: remove circular imports that break under Metro's import/export transform

  • FileBreadcrumbsStorage.ts: import BacktraceFileAttachment directly instead of from the package barrel.
  • BacktraceClient.ts: BacktraceClientBuilder moved into this module. The two classes construct each other, one module removes the cycle.
  • builder/BacktraceClientBuilder.ts: re-export only. Import path and index export unchanged.
  • handlers/ExceptionHandler.ts, handlers/UnhandledExceptionHandler.ts, handlers/android/AndroidUnhandledExceptionHandler.ts: import type for BacktraceClient, used as a type only.
  • .eslintrc.json: new, package-level import/no-cycle. Fails on the old sources (9 errors), passes on the new tree, enforced by the root npm run lint in CI.
  • tests/clientInitializationTests.spec.ts: new, initializes through the package entry point and the builder, asserts breadcrumb files are exposed as file attachments.

react-native: make Android autolinking compile under Expo and React Native 0.82+

  • android/build.gradle: namespace backtraceio.library, matching the Java package of ReactNativePackage. Expo autolinking derives the PackageList.java import from the namespace.
  • android/build.gradle: isNewArchitectureEnabled() reads newArchEnabled / react.newArchEnabled from the subproject. React Native 0.82+ sets the property on subprojects only.
  • android/gradle.properties: comment. A project-level newArchEnabled would override the app's setting.

react-native: support use_frameworks! with dynamic linkage

  • backtrace-react-native.podspec: s.static_framework = true. PLCrashReporter is a static xcframework, pod install rejected dynamic use_frameworks! without it. No-op for static and non-framework setups.

ref: BT-7787, BT-7788

…/export transform

With breadcrumbs enabled the client crashed with "Cannot read property 'prototype' of undefined" in apps whose Metro config enables experimentalImportSupport without inline requires:
FileBreadcrumbsStorage imported BacktraceFileAttachment through the package barrel and the builder imported the client while the client imported the builder, and Metro's static import transform captures those bindings while the barrel is still evaluating.
The storage now imports the attachment directly, the builder is defined next to the client, the exception handlers import the client as a type only, and import/no-cycle guards the package.
…ative 0.82+

Expo's autolinking derives the PackageList import from the Gradle namespace, which named a package that does not exist, so the generated PackageList.java failed to compile; the namespace now matches the Java package of ReactNativePackage.
The New Architecture check also read newArchEnabled from the root project, which React Native 0.82+ no longer sets, so the library skipped codegen while the app's C++ autolinking still expected its output.
od install rejected apps using dynamic frameworks because PLCrashReporter is a static xcframework, the pod now declares itself a static framework, which is a no-op for static and non-framework setups.
@melekr melekr self-assigned this Sep 25, 2026
@melekr
melekr requested a review from KishanPRao September 25, 2026 22:52
@melekr melekr changed the title Bugfix/react native import cycles and autolinking fix(react-native): remove import cycles that crash under Metro's import transform and fix autolinking builds Sep 25, 2026
}
}
// `BacktraceClientBuilder` lives next to `BacktraceClient` (see the note there); this module keeps the import path.
export { BacktraceClientBuilder } from '../BacktraceClient';

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

safe to delete.

…nking

# Conflicts:
#	packages/react-native/src/builder/BacktraceClientBuilder.ts
#	packages/react-native/src/handlers/UnhandledExceptionHandler.ts
@KishanPRao
KishanPRao merged commit aec4b3c into main Sep 29, 2026
12 of 24 checks passed
@KishanPRao
KishanPRao deleted the bugfix/react-native-import-cycles-and-autolinking branch September 29, 2026 14:09
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