Skip to content

feat: on-demand native lib download and optional feature splitting#1039

Draft
msluszniak wants to merge 2 commits intomainfrom
feat/on-demand-native-libs
Draft

feat: on-demand native lib download and optional feature splitting#1039
msluszniak wants to merge 2 commits intomainfrom
feat/on-demand-native-libs

Conversation

@msluszniak
Copy link
Copy Markdown
Member

Summary

  • Removes bundled native binaries from the npm package — libs are now downloaded at postinstall time from GitHub Releases, significantly reducing npm install size
  • Adds optional feature splitting: users can opt out of OpenCV and/or Phonemizer via their package.json, skipping both the download and the native compilation of those dependencies
  • CMake and podspec conditionally compile and link based on a rne-build-config.json file written by the postinstall script

How it works

User configuration (in the app's package.json):

"react-native-executorch": {
  "extras": ["opencv", "phonemizer"]
}

Omitting an extra skips its download and excludes it from the native build.

Artifacts (hosted on GitHub Releases, one tarball per dependency per platform/ABI):

core-android-arm64-v8a.tar.gz   core-ios.tar.gz
core-android-x86_64.tar.gz      phonemizer-ios.tar.gz
opencv-android-arm64-v8a.tar.gz
opencv-android-x86_64.tar.gz
phonemizer-android-arm64-v8a.tar.gz
phonemizer-android-x86_64.tar.gz

Note: iOS OpenCV comes from CocoaPods (opencv-rne), no tarball needed.

Release flow (Phase 1 — manual upload):

cd packages/react-native-executorch
./scripts/package-release-artifacts.sh
gh release upload v<version> dist-artifacts/* --repo software-mansion/react-native-executorch

Test plan

A test pre-release v0.9.0-libs-test has been published at https://github.com/software-mansion/react-native-executorch/releases/tag/v0.9.0-libs-test with all artifacts uploaded. To verify the full download flow:

cd packages/react-native-executorch
rm -rf third-party/android/libs third-party/ios/ExecutorchLib.xcframework third-party/ios/libs
rm -rf ~/.cache/react-native-executorch/0.9.0
RNET_BASE_URL=https://github.com/software-mansion/react-native-executorch/releases/download/v0.9.0-libs-test \
INIT_CWD=<repo-root> \
node scripts/download-libs.js

Expected: all 8 artifacts download, checksum-verify, and extract into the correct third-party/ paths.

  • Verify Android build compiles with RNE_ENABLE_OPENCV=OFF
  • Verify Android build compiles with RNE_ENABLE_PHONEMIZER=OFF
  • Verify iOS build compiles without phonemizer
  • Transitive header audit — confirm no core C++ file pulls in OpenCV transitively

What's not in this PR (follow-up)

  • GitHub Actions workflow to build and publish artifacts automatically on release (Phase 2)
  • JS subpath exports (react-native-executorch/cv, /llm) for ergonomic tree-shaking

🤖 Generated with Claude Code

Removes bundled native binaries from the npm package. Libraries are now
downloaded at postinstall time from GitHub Releases, reducing npm install
size and enabling users to opt out of unused dependencies (OpenCV, Phonemizer).

- postinstall script downloads only needed artifacts based on user config
  ("react-native-executorch": { "extras": [...] } in app's package.json)
- artifacts cached at ~/.cache/react-native-executorch/<version>/ with SHA256 verification
- CMake and podspec conditionally compile/link OpenCV and Phonemizer based
  on rne-build-config.json written by the postinstall script
- GlobalThreadPool.h guards cv::setNumThreads(0) with #ifdef RNE_ENABLE_OPENCV
- index.ts startup check validates only core globals; optional feature
  globals are allowed absent when those features are disabled
- scripts/package-release-artifacts.sh packages libs into split tarballs
  ready for manual upload to GitHub Releases (Phase 1 release flow)
- package.json excludes third-party lib dirs from npm bundle
- .gitignore excludes downloaded lib dirs and rne-build-config.json

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@msluszniak msluszniak self-assigned this Mar 31, 2026
@msluszniak msluszniak added refactoring feature PRs that implement a new feature labels Mar 31, 2026
@msluszniak msluszniak marked this pull request as draft March 31, 2026 20:10
@msluszniak msluszniak marked this pull request as draft March 31, 2026 20:10
Fixes build failures when RNE_ENABLE_OPENCV=OFF or RNE_ENABLE_PHONEMIZER=OFF:

- RnExecutorchInstaller.cpp: guard CV model includes and JSI registrations
  with #ifdef RNE_ENABLE_OPENCV, phonemizer registration with
  #ifdef RNE_ENABLE_PHONEMIZER
- LLM.cpp: guard VisionEncoder and MultimodalRunner (VLM support) with
  #ifdef RNE_ENABLE_OPENCV — text-only LLM still works without OpenCV
- CMakeLists.txt: add runner/encoders/vision_encoder.cpp,
  runner/multimodal_prefiller.cpp and runner/multimodal_runner.cpp to
  OPENCV_CPP_SOURCES so they are excluded when OpenCV is disabled

Verified: Android build succeeds with enableOpencv=false, enablePhonemizer=false.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@msluszniak
Copy link
Copy Markdown
Member Author

TODO: separate xnnpack and coreml backends to separate libs, so they can be opt-out the same way as opencv etc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature PRs that implement a new feature refactoring

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant