feat: allow extending the list of libs kept out of the AAR - #442
Merged
hurali97 merged 2 commits intoAug 7, 2026
Merged
Conversation
The plugin embeds .so files from the app's dependencies into the AAR, and separately declares those same dependencies in the published module metadata. When a host App resolves one of them from Maven it ends up with two copies of the library and mergeNativeLibs fails on the duplicate. IGNORE_EMBEDDED_LIBS already covers this for React Native's own libraries, but it is a fixed list, so any other dependency in that position has no way out. Add reactBrownfield.ignoreEmbeddedLibs so a project can extend it.
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a new Gradle extension option to let consumers exclude additional native .so files from being embedded into the produced AAR, avoiding duplicate-native-lib packaging failures when those dependencies are also declared in published module metadata.
Changes:
- Introduces
reactBrownfield.ignoreEmbeddedLibson the plugin extension (default empty). - Wires the new option into
ProcessAndCopyJniLibsTaskand applies it alongside the existingIGNORE_EMBEDDED_LIBSfilter. - Adds a changeset entry documenting the patch release.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/utils/Extension.kt | Adds ignoreEmbeddedLibs extension property with KDoc explaining the duplicate .so issue. |
| gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/processors/JNILibsProcessor.kt | Adds a task input for extra ignored libs and uses it when filtering embedded .so files. |
| .changeset/tidy-moons-shave.md | Documents the new option as a patch changeset. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Contributor
Author
|
Good catch on the KDoc link — |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The plugin embeds
.sofiles from the app's dependencies into the AAR, and separately declares those same dependencies in the published Gradle module metadata. When the host App resolves one of them from Maven it ends up with the library twice — once inside the AAR, once from the Maven artifact — and packaging fails:IGNORE_EMBEDDED_LIBSalready exists for exactly this situation, and its comment describes it well — libs "provided by the Gradle when AAR is consumed by the host App". But it is a fixed list covering React Native's own libraries, so a project that hits this with any other dependency has no way out of it.In our app three libraries are in that position:
libdatadog-ndk.so,libopentok.soandlibzstd-kmp.so— each bundled in the AAR and declared in its metadata. Datadog just happens to fail first.Solution
Add
reactBrownfield.ignoreEmbeddedLibs, appended to the built-in list:reactBrownfield { ignoreEmbeddedLibs = listOf("libdatadog-ndk.so", "libopentok.so", "libzstd-kmp.so") }Default is empty, so behaviour is unchanged for everyone else.
A host can work around this today with
packaging { jniLibs { pickFirsts += ... } }, but that still ships the duplicate into the AAR and just picks one at packaging time, and it has to be repeated by every integrator. Excluding at the source keeps the AAR correct.Test plan
Verified against a real brownfield SDK build (Expo SDK 57 / RN 0.86, New Architecture):
.soper ABI including the three above; host app failed atmergeReleaseNativeLibsonlibdatadog-ndk.so.ignoreEmbeddedLibs: AAR contains 14.soper ABI, the three are absent, and the host app'smergeReleaseNativeLibssucceeds with nopickFirstsworkaround.