Skip to content

Commit ef7ab0e

Browse files
committed
feat: on-demand native lib download with opt-in feature splitting
The npm tarball ships without prebuilt native binaries — they are downloaded from GitHub Releases at postinstall and extracted into third-party/, where the existing CMake / podspec configurations pick them up unchanged. Apps can opt out of features they don't need to skip both the download and the native compilation: "react-native-executorch": { "extras": ["opencv", "phonemizer", "xnnpack", "coreml", "vulkan"] } Defaults to all enabled. Each extra trims one or more artifacts and toggles a corresponding RNE_ENABLE_* CMake / podspec flag, dropping its sources from compilation and its libraries from the final link. Per-platform behavior: - opencv Android + iOS (iOS provided via opencv-rne CocoaPod) - phonemizer Android + iOS - xnnpack iOS-only as a force-loaded XnnpackBackend.xcframework; baked into libexecutorch.so on Android - coreml iOS-only as a force-loaded CoreMLBackend.xcframework - vulkan Android-only as a separately-loaded libvulkan_executorch_backend.so Vulkan ships as its own shared library (mirroring the QNN backend pattern) so its load-time backend registration runs only when the user opts in. The .so links only against vulkan_backend + vulkan_schema + executorch_core, not the CPU kernel registries, so it does not cause duplicate kernel registration when loaded alongside libexecutorch.so.
1 parent 0c64923 commit ef7ab0e

73 files changed

Lines changed: 1171 additions & 183 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.cspell-wordlist.txt

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,3 +203,26 @@ fishjam
203203
Fishjam
204204
deinitialize
205205
Deinitialize
206+
podspec
207+
libexecutorch
208+
libxnnpack
209+
libvulkan
210+
libbackend
211+
libcpuinfo
212+
flatcc
213+
Werror
214+
dlopen
215+
msluszniak
216+
DRNE
217+
libopencv
218+
Kleidi
219+
libphonemis
220+
libreact
221+
CPLUSPLUSFLAGS
222+
LDFLAGS
223+
iphoneos
224+
iphonesimulator
225+
xcframework
226+
xcframeworks
227+
EEXIST
228+
RNET

.github/workflows/build-android-llm-example.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ jobs:
1919
runs-on: ubuntu-latest
2020
env:
2121
WORKING_DIRECTORY: apps/llm
22+
# TODO: drop once v0.9.0 is cut and tarballs are attached to the matching Release.
23+
RNET_BASE_URL: https://github.com/software-mansion/react-native-executorch/releases/download/v0.9.0-libs-test
2224
concurrency:
2325
group: android-${{ github.ref }}
2426
cancel-in-progress: true

.github/workflows/build-ios-llm-example.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ jobs:
2222
concurrency:
2323
group: ios-${{ github.ref }}
2424
cancel-in-progress: true
25+
env:
26+
# TODO: drop once v0.9.0 is cut and tarballs are attached to the matching Release.
27+
RNET_BASE_URL: https://github.com/software-mansion/react-native-executorch/releases/download/v0.9.0-libs-test
2528
steps:
2629
- uses: maxim-lobanov/setup-xcode@v1
2730
with:

.github/workflows/ci.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ on:
1010
types:
1111
- checks_requested
1212
workflow_dispatch:
13+
env:
14+
# TODO: drop once v0.9.0 is cut and tarballs are attached to the matching Release.
15+
RNET_BASE_URL: https://github.com/software-mansion/react-native-executorch/releases/download/v0.9.0-libs-test
1316
jobs:
1417
lint:
1518
runs-on: ubuntu-latest

.gitignore

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,17 @@ docs/docs/06-api-reference/
9898
# integration test model assets
9999
packages/react-native-executorch/common/rnexecutorch/tests/integration/assets/models/
100100

101+
# release artifact staging dir (produced by scripts/package-release-artifacts.sh)
102+
packages/react-native-executorch/dist-artifacts/
103+
104+
# on-demand native libs (downloaded at postinstall time, not committed)
105+
packages/react-native-executorch/third-party/android/libs/
106+
packages/react-native-executorch/third-party/ios/ExecutorchLib.xcframework/
107+
packages/react-native-executorch/third-party/ios/CoreMLBackend.xcframework/
108+
packages/react-native-executorch/third-party/ios/XnnpackBackend.xcframework/
109+
packages/react-native-executorch/third-party/ios/libs/
110+
packages/react-native-executorch/rne-build-config.json
111+
101112
# custom
102113
*.tgz
103114
Makefile

docs/docs/01-fundamentals/01-getting-started.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,42 @@ Installation is pretty straightforward, use your package manager of choice to in
7676
</TabItem>
7777
</Tabs>
7878

79+
### Configuring backends and extras
80+
81+
On install, `react-native-executorch` runs a `postinstall` script that downloads prebuilt native libraries from the matching GitHub Release and unpacks them under `third-party/`. By default every optional feature is included — which keeps the app binary large. You can opt out of anything you don't need by adding an `extras` array to your app's `package.json`:
82+
83+
```json
84+
{
85+
"react-native-executorch": {
86+
"extras": ["xnnpack", "coreml", "vulkan", "opencv", "phonemizer"]
87+
}
88+
}
89+
```
90+
91+
If the `extras` key is omitted, all five features are enabled. To disable a feature, drop its name from the array.
92+
93+
| Extra | iOS | Android | What it enables |
94+
| ------------ | --------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | ------------------------------------------------------------- |
95+
| `opencv` | ✅ (via the `opencv-rne` CocoaPod) || Computer-vision models (classification, detection, OCR, etc.) |
96+
| `phonemizer` ||| Text-to-speech models |
97+
| `xnnpack` | ✅ — `XnnpackBackend.xcframework` force-loaded into the app | ✅ — separately-loaded `libxnnpack_executorch_backend.so` | XNNPACK CPU backend (required for most quantized models) |
98+
| `coreml` | ✅ — `CoreMLBackend.xcframework` force-loaded into the app | n/a (CoreML is iOS-only) | Core ML backend (Apple Neural Engine / GPU acceleration) |
99+
| `vulkan` | n/a (Vulkan is Android-only) | ✅ — separately-loaded `libvulkan_executorch_backend.so` | Vulkan GPU backend |
100+
101+
Source files and native libraries are excluded from compilation when an extra is disabled, so builds that only need LLMs can skip OpenCV and cut tens of megabytes off the final binary.
102+
103+
The postinstall step honors a few environment variables:
104+
105+
| Variable | Purpose |
106+
| ---------------------- | ------------------------------------------------------------------------- |
107+
| `RNET_SKIP_DOWNLOAD=1` | Skip the download entirely (for CI with pre-cached libraries). |
108+
| `RNET_LIBS_CACHE_DIR` | Custom cache directory (default: `~/.cache/react-native-executorch/<v>`). |
109+
| `RNET_TARGET` | Force a specific target, e.g. `android-arm64-v8a` or `ios`. |
110+
| `RNET_NO_X86_64=1` | Skip the Android x86_64 tarball (handy when only building for a device). |
111+
| `GITHUB_TOKEN` | Required to access draft releases while iterating on a new version. |
112+
113+
After changing `extras`, re-run `yarn install` (or the equivalent) so the postinstall script regenerates `rne-build-config.json` and re-extracts the right tarballs, then rebuild the native project.
114+
79115
:::warning
80116
Before using any other API, you must call `initExecutorch` with a resource fetcher adapter at the entry point of your app:
81117

0 commit comments

Comments
 (0)