Skip to content

feat(android): support bundled JS in debug builds#350

Merged
adamTrz merged 2 commits into
mainfrom
adamTrz/android-debug-bundled-aar
May 25, 2026
Merged

feat(android): support bundled JS in debug builds#350
adamTrz merged 2 commits into
mainfrom
adamTrz/android-debug-bundled-aar

Conversation

@adamTrz
Copy link
Copy Markdown
Collaborator

@adamTrz adamTrz commented May 25, 2026

Summary

Fixes Android debug AAR packaging so a clean brownfield package:android --variant debug build embeds the JavaScript bundle instead of depending on stale outputs from a prior release build.

Root cause

Android debug packaging was not deterministic from a clean build.

The brownfield plugin correctly guarded React Native bundling so it only ran for release variants, but debug AAR assembly still expected the generated JS/assets to already exist. In practice this meant debug packaging only appeared to work when a previous release build had already left index.android.bundle behind.

What changed

  • maps debuggable variants to their sibling release bundle-producing variant
    • debug -> release
    • flavored variants like freeDebug -> freeRelease
  • updates Android source-set wiring so debug library variants read bundled assets and resources from the mapped release outputs
  • updates variant pre-build dependencies so clean debug packaging explicitly runs the mapped release JS bundle task before AAR assembly
  • keeps the existing release-only bundling rule intact instead of introducing a new Android runtime API

Validation

  • republished the local brownfield Gradle plugin snapshot with yarn brownfield:plugin:publish:local
  • ran a clean package build:
    • cd apps/RNApp/android && ./gradlew -p BrownfieldLib clean
    • cd apps/RNApp && yarn exec brownfield package:android --module-name :BrownfieldLib --variant debug
  • confirmed the clean debug run now invokes :app:createBundleReleaseJsAndAssets
  • confirmed the produced debug AAR now contains assets/index.android.bundle

Impact

Debug AARs built from a clean checkout are now self-sufficient at the packaging layer. This removes the accidental dependency on a prior release build and is the prerequisite for running Android brownfield consumers without Metro in debug packaging flows.

@adamTrz adamTrz marked this pull request as ready for review May 25, 2026 08:54
@adamTrz adamTrz requested review from artus9033 and hurali97 May 25, 2026 08:54
@adamTrz adamTrz changed the title [codex] Fix Android debug AAR bundled JS packaging feat(android): support bundled JS in debug builds May 25, 2026
Comment on lines +3 to +51
@@ -46,4 +47,22 @@ object Utils {
fun isExpoProject(project: Project): Boolean {
return project.findProject(EXPO_PROJECT_LOCATOR) != null
}

fun getBundledAssetsVariantName(variant: LibraryVariant): String {
Copy link
Copy Markdown
Member

@hurali97 hurali97 May 25, 2026

Choose a reason for hiding this comment

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

This LibraryVariant API will be removed in AGP9. We already have another PR which reduces and refactors the usages of old API here.

I suggest to use the new API com.android.build.api.variant.LibraryVariant as the work in this function can be achieved with this newer API as well.

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.

Adjusted 👌 I kept the mapping logic, but removed the new dependency on deprecated com.android.build.gradle.api.LibraryVariant.

Comment on lines +61 to +64
val bundledAssetsVariantName = Utils.getBundledAssetsVariantName(variant)
val capitalizedBundledAssetsVariantName = bundledAssetsVariantName.capitalized()

if (bundledAssetsVariantName != variant.name || capitalizedVariantName.contains("Release")) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can you explain why we need to introduce bundledAssetsVariantName ? I am thinking that maybe we can remove the if-statement and have this run for both debug and release build types. Since the scope of this PR suggests to have JS Bundle in debug build as well, we can perhaps safely remove the if-statement.

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.

Applied this simplification.

The important part is not whether the current variant is debug or release, but which variant should provide the bundled assets. For debuggable variants that is the sibling release variant; for non-debuggable variants it is the variant itself.

So VariantProcessor now always depends on the mapped createBundle...JsAndAssets task. That is simpler and also covers custom non-debuggable build types better than the previous conditional.

Comment on lines -58 to +61
"createBundle${capitalizedVariantName}JsAndAssets",
"createBundle${capitalizedBundledAssetsVariantName}JsAndAssets",
// outputs for RN >= 0.82
"react/${variant.name}",
"react/$bundledAssetsVariantName",
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I am not sure whether we need this change. See the context below

@artus9033
Copy link
Copy Markdown
Collaborator

From my end, same comments as from @hurali97

Copy link
Copy Markdown
Contributor

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 fixes non-deterministic Android debug AAR packaging in the brownfield Gradle plugin by ensuring debug (and other debuggable) library variants consume bundled JS/assets produced by their corresponding release variant, and by explicitly wiring the required bundle tasks into the debug build graph.

Changes:

  • Introduces a helper to map a debuggable variant name to the corresponding release bundle-producing variant (e.g., debug -> release, freeDebug -> freeRelease).
  • Updates library variant pre-build dependencies so debug AAR assembly runs the mapped release JS/assets bundling task (and Expo updates resources task when applicable).
  • Updates Android source set wiring so debug variants pick up generated assets/resources from the mapped release outputs (supporting both RN <= 0.81 and RN >= 0.82 output layouts).

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/utils/Utils.kt Adds variant-name mapping utility to select the correct bundle-producing variant for debuggable builds.
gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/processors/VariantProcessor.kt Makes pre<Variant>Build depend on the mapped release createBundle*JsAndAssets (and Expo resources) tasks so clean debug packaging is deterministic.
gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/plugin/RNSourceSets.kt Rewires debug variant source sets to read JS/assets/res from the mapped release-generated output directories.

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

Copy link
Copy Markdown
Collaborator

@artus9033 artus9033 left a comment

Choose a reason for hiding this comment

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

LGTM!

@artus9033 artus9033 requested a review from hurali97 May 25, 2026 10:19
@adamTrz adamTrz merged commit 9f66382 into main May 25, 2026
15 checks passed
@adamTrz adamTrz deleted the adamTrz/android-debug-bundled-aar branch May 25, 2026 11:16
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.

4 participants