Skip to content

Conversation

@hans00
Copy link
Contributor

@hans00 hans00 commented Aug 16, 2025

Description

close #16031

Motivation and Context

Make React Native fully zero copy.

@hans00 hans00 marked this pull request as ready for review August 16, 2025 11:07
@hans00 hans00 changed the title WIP: [js/rn] Migrate to JSI implementation [js/rn] Migrate to JSI implementation Aug 16, 2025
@fs-eire fs-eire requested a review from Copilot August 18, 2025 06:46
Copy link
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 migrates the React Native ONNX Runtime implementation from a bridge-based architecture to a JSI (JavaScript Interface) implementation to achieve zero-copy data transfer. This eliminates the need for serializing tensors through the React Native bridge and removes the dependency on blob storage for tensor data.

Key changes include:

  • Complete rewrite using JSI for direct JavaScript-native communication
  • Removal of blob-based tensor data transfer mechanism
  • New C++ JSI binding layer with async operation support
  • Simplified native module interfaces for both iOS and Android

Reviewed Changes

Copilot reviewed 33 out of 34 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
js/react_native/package.json Updates package dependencies, removes buffer dependency, adds cpp source files
js/react_native/lib/*.ts Rewrites TypeScript bindings to use JSI API instead of bridge calls
js/react_native/cpp/*.{h,cpp} New C++ JSI implementation with tensor utilities, session management, and async workers
js/react_native/ios/*.{h,mm} Simplifies iOS module to only install JSI bindings
js/react_native/android/src/main/java/* Removes Java tensor helpers and bridge methods, adds JSI installation
js/react_native/android/CMakeLists.txt Updates build configuration for JSI compilation
Files not reviewed (1)
  • js/react_native/package-lock.json: Language not supported
Comments suppressed due to low confidence (1)

js/react_native/lib/backend.ts:98

  • The initialization logic should handle the case where OrtApi.initOrtOnce has already been called. Consider checking if initialization has already occurred to avoid potential reinitialization issues.
      OnnxruntimeSessionHandler.#initialized = true;

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

for (size_t i = 0; i < size; ++i) {
auto item = array.getValueAtIndex(runtime, i);
static_cast<char**>(data)[i] =
strdup(item.toString(runtime).utf8(runtime).c_str());
Copy link

Copilot AI Aug 18, 2025

Choose a reason for hiding this comment

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

The strdup call allocates memory that is never freed, causing a memory leak. Consider using a RAII approach or ensuring proper cleanup of allocated string memory.

Suggested change
strdup(item.toString(runtime).utf8(runtime).c_str());
try {
for (size_t i = 0; i < size; ++i) {
auto item = array.getValueAtIndex(runtime, i);
static_cast<char**>(data)[i] =
strdup(item.toString(runtime).utf8(runtime).c_str());
if (static_cast<char**>(data)[i] == nullptr) {
// Free previously allocated strings
for (size_t j = 0; j < i; ++j) {
free(static_cast<char**>(data)[j]);
}
delete[] static_cast<char**>(data);
throw std::bad_alloc();
}
}
} catch (...) {
// Free any allocated strings if an exception occurs
for (size_t j = 0; j < size; ++j) {
if (static_cast<char**>(data)[j]) {
free(static_cast<char**>(data)[j]);
}
}
delete[] static_cast<char**>(data);
throw;

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

@hans00 hans00 Aug 20, 2025

Choose a reason for hiding this comment

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

This might FP.
After tensor create, the string pointer is controlled by Tensor and toString should no exception.

@fs-eire fs-eire requested review from carzh and edgchen1 August 18, 2025 22:16
@fs-eire
Copy link
Contributor

fs-eire commented Oct 22, 2025

@hans00 could you please update the branch to latest main?

@fs-eire
Copy link
Contributor

fs-eire commented Oct 22, 2025

/azp run Linux QNN CI Pipeline, Win_TRT_Minimal_CUDA_Test_CI, Windows ARM64 QNN CI Pipeline, Windows GPU Doc Gen CI Pipeline

@azure-pipelines
Copy link

Azure Pipelines successfully started running 4 pipeline(s).

@fs-eire
Copy link
Contributor

fs-eire commented Oct 22, 2025

need to fix the lint/format issues:

lintrunner

>>> Lint for js/react_native/cpp/JsiHelper.h:

  Warning (CLANGFORMAT) format
    See https://clang.llvm.org/docs/ClangFormat.html.
    Run `lintrunner -a` to apply this patch.

    You can run `lintrunner -a` to apply this patch.

    33  33 |   }
    34  34 | 
    35  35 | #define GETTER_INFO(cls, name) \
    35     |-  { #name, BIND_THIS_GETTER(cls, name) }
        36 |+  {#name, BIND_THIS_GETTER(cls, name)}
    37  37 | 
    38  38 | #define DEFINE_METHOD(name)                                     \
    39  39 |   Value name##_method(Runtime& runtime, const Value& thisValue, \

ESLint

Run npm run lint

> lint
> eslint .


/home/runner/work/onnxruntime/onnxruntime/js/react_native/lib/backend.ts
Error:    54:21  error  This assertion is unnecessary since it does not change the type of the expression  @typescript-eslint/no-unnecessary-type-assertion
Error:    56:22  error  This assertion is unnecessary since it does not change the type of the expression  @typescript-eslint/no-unnecessary-type-assertion
Error:   172:12  error  Redundant use of `await` on a return value                                         no-return-await
Error:   185:12  error  Redundant use of `await` on a return value                                         no-return-await

/home/runner/work/onnxruntime/onnxruntime/js/react_native/lib/binding.ts
Error:   10:3  error  Unexpected var, use let or const instead  no-var

✖ 5 problems (5 errors, 0 warnings)
  2 errors and 0 warnings potentially fixable with the `--fix` option.

@fs-eire
Copy link
Contributor

fs-eire commented Oct 22, 2025

The RN build error seems related:

  CMake Error at CMakeLists.txt:72 (add_library):
    Target "onnxruntimejsi" links to target "ReactAndroid::reactnative" but the
    target was not found.  Perhaps a find_package() call is missing for an
    IMPORTED target, or an ALIAS target is missing?
  

@hans00
Copy link
Contributor Author

hans00 commented Oct 27, 2025

The RN build error seems related:

Error are fixed. And manually tested E2E are works fine.

@fs-eire
Copy link
Contributor

fs-eire commented Oct 28, 2025

There are still build errors in React Native CI pipeline.

android
FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:mergeReleaseNativeLibs'.
> A failure occurred while executing com.android.build.gradle.internal.tasks.MergeNativeLibsTask$MergeNativeLibsTaskWorkAction
   > 2 files found with path 'lib/x86_64/libonnxruntime.so' from inputs:
      - /mnt/vss/_work/onnxruntime/onnxruntime/js/react_native/e2e/node_modules/onnxruntime-react-native/android/build/intermediates/library_jni/release/jni/x86_64/libonnxruntime.so
      - /home/cloudtest/.gradle/caches/transforms-3/3f7c8c64230befbe5be6473aeb8b24d3/transformed/jetified-onnxruntime-android-1.24.0/jni/x86_64/libonnxruntime.so
     If you are using jniLibs and CMake IMPORTED targets, see
     https://developer.android.com/r/tools/jniLibs-vs-imported-targets
iOS E2E tests
2025-10-27T19:57:42.3567680Z /Users/runner/work/onnxruntime/onnxruntime/js/react_native/ios/OnnxruntimeModule.mm:5:10: fatal error: 'JsiMain.h' file not found
2025-10-27T19:57:42.3568170Z #include "JsiMain.h"
2025-10-27T19:57:42.3568420Z          ^~~~~~~~~~~
2025-10-27T19:57:42.3568700Z 1 error generated.
2025-10-27T19:57:42.3568810Z 
2025-10-27T19:57:42.3570790Z WriteAuxiliaryFile /Users/runner/Library/Developer/Xcode/DerivedData/OnnxruntimeModule-giesqlqsfofuwhdtlqlvunkjmgyn/Build/Intermediates.noindex/OnnxruntimeModule.build/Debug-iphonesimulator/OnnxruntimeModuleTest.build/OnnxruntimeModuleTest-all-target-headers.hmap (in target 'OnnxruntimeModuleTest' from project 'OnnxruntimeModule')
2025-10-27T19:57:42.3579460Z     cd /Users/runner/work/onnxruntime/onnxruntime/js/react_native/ios
2025-10-27T19:57:42.3580710Z     write-file /Users/runner/Library/Developer/Xcode/DerivedData/OnnxruntimeModule-giesqlqsfofuwhdtlqlvunkjmgyn/Build/Intermediates.noindex/OnnxruntimeModule.build/Debug-iphonesimulator/OnnxruntimeModuleTest.build/OnnxruntimeModuleTest-all-target-headers.hmap
2025-10-27T19:57:42.3581550Z 
2025-10-27T19:57:42.3583050Z WriteAuxiliaryFile /Users/runner/Library/Developer/Xcode/DerivedData/OnnxruntimeModule-giesqlqsfofuwhdtlqlvunkjmgyn/Build/Intermediates.noindex/OnnxruntimeModule.build/Debug-iphonesimulator/OnnxruntimeModuleTest.build/OnnxruntimeModuleTest-all-non-framework-target-headers.hmap (in target 'OnnxruntimeModuleTest' from project 'OnnxruntimeModule')
2025-10-27T19:57:42.3584350Z     cd /Users/runner/work/onnxruntime/onnxruntime/js/react_native/ios
2025-10-27T19:57:42.3585550Z     write-file /Users/runner/Library/Developer/Xcode/DerivedData/OnnxruntimeModule-giesqlqsfofuwhdtlqlvunkjmgyn/Build/Intermediates.noindex/OnnxruntimeModule.build/Debug-iphonesimulator/OnnxruntimeModuleTest.build/OnnxruntimeModuleTest-all-non-framework-target-headers.hmap
2025-10-27T19:57:42.3586430Z 
2025-10-27T19:57:42.3587900Z warning: Run script build phase '[CP-User] [Hermes] Replace Hermes for the right configuration, if needed' will be run during every build because it does not specify any outputs. To address this warning, either add output dependencies to the script phase, or configure it to run in every build by unchecking "Based on dependency analysis" in the script phase. (in target 'hermes-engine' from project 'Pods')
2025-10-27T19:57:42.3590130Z warning: Run script build phase 'Create Symlinks to Header Folders' will be run during every build because it does not specify any outputs. To address this warning, either add output dependencies to the script phase, or configure it to run in every build by unchecking "Based on dependency analysis" in the script phase. (in target 'fmt' from project 'Pods')
2025-10-27T19:57:42.3592270Z warning: Run script build phase 'Create Symlinks to Header Folders' will be run during every build because it does not specify any outputs. To address this warning, either add output dependencies to the script phase, or configure it to run in every build by unchecking "Based on dependency analysis" in the script phase. (in target 'Yoga' from project 'Pods')
2025-10-27T19:57:42.3594900Z warning: Run script build phase 'Create Symlinks to Header Folders' will be run during every build because it does not specify any outputs. To address this warning, either add output dependencies to the script phase, or configure it to run in every build by unchecking "Based on dependency analysis" in the script phase. (in target 'ReactCommon' from project 'Pods')
2025-10-27T19:57:42.3597080Z warning: Run script build phase 'Create Symlinks to Header Folders' will be run during every build because it does not specify any outputs. To address this warning, either add output dependencies to the script phase, or configure it to run in every build by unchecking "Based on dependency analysis" in the script phase. (in target 'React-utils' from project 'Pods')
2025-10-27T19:57:42.3599330Z warning: Run script build phase 'Create Symlinks to Header Folders' will be run during every build because it does not specify any outputs. To address this warning, either add output dependencies to the script phase, or configure it to run in every build by unchecking "Based on dependency analysis" in the script phase. (in target 'React-runtimescheduler' from project 'Pods')
2025-10-27T19:57:42.3601870Z warning: Run script build phase 'Create Symlinks to Header Folders' will be run during every build because it does not specify any outputs. To address this warning, either add output dependencies to the script phase, or configure it to run in every build by unchecking "Based on dependency analysis" in the script phase. (in target 'React-rendererdebug' from project 'Pods')
2025-10-27T19:57:42.3604050Z warning: Run script build phase 'Create Symlinks to Header Folders' will be run during every build because it does not specify any outputs. To address this warning, either add output dependencies to the script phase, or configure it to run in every build by unchecking "Based on dependency analysis" in the script phase. (in target 'React-nativeconfig' from project 'Pods')
2025-10-27T19:57:42.3606420Z warning: Run script build phase 'Create Symlinks to Header Folders' will be run during every build because it does not specify any outputs. To address this warning, either add output dependencies to the script phase, or configure it to run in every build by unchecking "Based on dependency analysis" in the script phase. (in target 'React-jserrorhandler' from project 'Pods')
2025-10-27T19:57:42.3608590Z warning: Run script build phase 'Create Symlinks to Header Folders' will be run during every build because it does not specify any outputs. To address this warning, either add output dependencies to the script phase, or configure it to run in every build by unchecking "Based on dependency analysis" in the script phase. (in target 'React-graphics' from project 'Pods')
2025-10-27T19:57:42.3610790Z warning: Run script build phase 'Create Symlinks to Header Folders' will be run during every build because it does not specify any outputs. To address this warning, either add output dependencies to the script phase, or configure it to run in every build by unchecking "Based on dependency analysis" in the script phase. (in target 'React-debug' from project 'Pods')
2025-10-27T19:57:42.3613570Z warning: Run script build phase 'Create Symlinks to Header Folders' will be run during every build because it does not specify any outputs. To address this warning, either add output dependencies to the script phase, or configure it to run in every build by unchecking "Based on dependency analysis" in the script phase. (in target 'React-NativeModulesApple' from project 'Pods')
2025-10-27T19:57:42.3615830Z warning: Run script build phase 'Create Symlinks to Header Folders' will be run during every build because it does not specify any outputs. To address this warning, either add output dependencies to the script phase, or configure it to run in every build by unchecking "Based on dependency analysis" in the script phase. (in target 'React-Mapbuffer' from project 'Pods')
2025-10-27T19:57:42.3618040Z warning: Run script build phase 'Create Symlinks to Header Folders' will be run during every build because it does not specify any outputs. To address this warning, either add output dependencies to the script phase, or configure it to run in every build by unchecking "Based on dependency analysis" in the script phase. (in target 'React-ImageManager' from project 'Pods')
2025-10-27T19:57:42.3620590Z warning: Run script build phase 'Create Symlinks to Header Folders' will be run during every build because it does not specify any outputs. To address this warning, either add output dependencies to the script phase, or configure it to run in every build by unchecking "Based on dependency analysis" in the script phase. (in target 'React-FabricImage' from project 'Pods')
2025-10-27T19:57:42.3622730Z warning: Run script build phase 'Create Symlinks to Header Folders' will be run during every build because it does not specify any outputs. To address this warning, either add output dependencies to the script phase, or configure it to run in every build by unchecking "Based on dependency analysis" in the script phase. (in target 'React-Fabric' from project 'Pods')
2025-10-27T19:57:42.3625260Z warning: Run script build phase 'Create Symlinks to Header Folders' will be run during every build because it does not specify any outputs. To address this warning, either add output dependencies to the script phase, or configure it to run in every build by unchecking "Based on dependency analysis" in the script phase. (in target 'React-Codegen' from project 'Pods')
2025-10-27T19:57:42.3627400Z warning: Run script build phase 'Create Symlinks to Header Folders' will be run during every build because it does not specify any outputs. To address this warning, either add output dependencies to the script phase, or configure it to run in every build by unchecking "Based on dependency analysis" in the script phase. (in target 'RCT-Folly' from project 'Pods')
2025-10-27T19:57:43.5825140Z Testing failed:
2025-10-27T19:57:43.5825380Z 
2025-10-27T19:57:43.5843750Z 	'JsiMain.h' file not found
2025-10-27T19:57:43.5925490Z Test session results, code coverage, and logs:
2025-10-27T19:57:43.5931380Z 	Testing cancelled because the build failed.
2025-10-27T19:57:43.6032080Z 	/Users/runner/Library/Developer/Xcode/DerivedData/OnnxruntimeModule-giesqlqsfofuwhdtlqlvunkjmgyn/Logs/Test/Test-OnnxruntimeModuleTest-2025.10.27_19-51-36-+0000.xcresult
2025-10-27T19:57:43.6034170Z 
2025-10-27T19:57:43.6229440Z 
2025-10-27T19:57:43.6230780Z ** TEST FAILED **
iOS E2E tests
  $ /Users/runner/hostedtoolcache/node/22.20.0/arm64/bin/node -p require.resolve(     "react-native/scripts/react_native_pods.rb",     {paths: [process.argv[1]]},   ) /Users/runner/work/onnxruntime/onnxruntime/js/react_native/e2e/ios
  /Users/runner/work/onnxruntime/onnxruntime/js/react_native/e2e/node_modules/react-native/scripts/react_native_pods.rb
  $ /Users/runner/hostedtoolcache/node/22.20.0/arm64/bin/node -p require.resolve(     "@react-native-community/cli-platform-ios/native_modules.rb",     {paths: [process.argv[1]]},   ) /Users/runner/work/onnxruntime/onnxruntime/js/react_native/e2e/node_modules/react-native/scripts
  /Users/runner/work/onnxruntime/onnxruntime/js/react_native/e2e/node_modules/@react-native-community/cli-platform-ios/native_modules.rb
  $ /Users/runner/hostedtoolcache/node/22.20.0/arm64/bin/node -e try {console.log(require('@react-native-community/cli').bin);} catch (e) {console.log(require('react-native/cli').bin);}
  /Users/runner/work/onnxruntime/onnxruntime/js/react_native/e2e/node_modules/@react-native-community/cli/build/bin.js

[!] Invalid `Podfile` file: 
[!] Invalid `onnxruntime-react-native.podspec` file: undefined local variable or method `s' for module Pod.

 #  from /Users/runner/work/onnxruntime/onnxruntime/js/react_native/e2e/node_modules/onnxruntime-react-native/onnxruntime-react-native.podspec:29
 #  -------------------------------------------
 #    if respond_to?(:install_modules_dependencies, true)
 >      install_modules_dependencies(s)
 #    else
 #  -------------------------------------------
.

 #  from /Users/runner/work/onnxruntime/onnxruntime/js/react_native/e2e/ios/Podfile:17
 #  -------------------------------------------
 #  target 'OnnxruntimeModuleExample' do
 >    config = use_native_modules!
 #  
 #  -------------------------------------------

/opt/homebrew/lib/ruby/gems/3.3.0/gems/cocoapods-core-1.16.2/lib/cocoapods-core/podfile.rb:335:in `rescue in block in from_ruby'
/opt/homebrew/lib/ruby/gems/3.3.0/gems/cocoapods-core-1.16.2/lib/cocoapods-core/podfile.rb:329:in `block in from_ruby'
/opt/homebrew/lib/ruby/gems/3.3.0/gems/cocoapods-core-1.16.2/lib/cocoapods-core/podfile.rb:50:in `instance_eval'
/opt/homebrew/lib/ruby/gems/3.3.0/gems/cocoapods-core-1.16.2/lib/cocoapods-core/podfile.rb:50:in `initialize'
/opt/homebrew/lib/ruby/gems/3.3.0/gems/cocoapods-core-1.16.2/lib/cocoapods-core/podfile.rb:327:in `new'
/opt/homebrew/lib/ruby/gems/3.3.0/gems/cocoapods-core-1.16.2/lib/cocoapods-core/podfile.rb:327:in `from_ruby'
/opt/homebrew/lib/ruby/gems/3.3.0/gems/cocoapods-core-1.16.2/lib/cocoapods-core/podfile.rb:293:in `from_file'
/opt/homebrew/lib/ruby/gems/3.3.0/gems/cocoapods-1.16.2/lib/cocoapods/config.rb:206:in `podfile'
/opt/homebrew/lib/ruby/gems/3.3.0/gems/cocoapods-1.16.2/lib/cocoapods/command.rb:160:in `verify_podfile_exists!'
/opt/homebrew/lib/ruby/gems/3.3.0/gems/cocoapods-1.16.2/lib/cocoapods/command/install.rb:46:in `run'
/opt/homebrew/lib/ruby/gems/3.3.0/gems/claide-1.1.0/lib/claide/command.rb:334:in `run'
/opt/homebrew/lib/ruby/gems/3.3.0/gems/cocoapods-1.16.2/lib/cocoapods/command.rb:52:in `run'
/opt/homebrew/lib/ruby/gems/3.3.0/gems/cocoapods-1.16.2/bin/pod:55:in `<top (required)>'
/opt/homebrew/lib/ruby/site_ruby/3.3.0/rubygems.rb:319:in `load'
/opt/homebrew/lib/ruby/site_ruby/3.3.0/rubygems.rb:319:in `activate_and_load_bin_path'
/opt/homebrew/lib/ruby/gems/3.3.0/bin/pod:25:in `<main>'
Error: Process completed with exit code 1.

@hans00
Copy link
Contributor Author

hans00 commented Oct 31, 2025

There are still build errors in React Native CI pipeline.

Oh, I missed unit test files.
JSI seems cannot to do unit test, so I move these to E2E test.

@hans00
Copy link
Contributor Author

hans00 commented Nov 6, 2025

@fs-eire Errors might be fixed. I have fully manually tested the CI E2E workflow.

@fs-eire
Copy link
Contributor

fs-eire commented Nov 12, 2025

need fix this format precheck:

Error: Following source files are not formatted: (did you run "npm run format"?)
js/react_native/e2e/test/OnnxruntimeModuleExample.test.js

@fs-eire
Copy link
Contributor

fs-eire commented Nov 14, 2025

The React Native CI failure seems to indicate that libpulse is not installed for Android test job. (iOS is passing)

/usr/local/lib/android/sdk/emulator/qemu/linux-x86_64/qemu-system-x86_64: error while loading shared libraries: libpulse.so.0: cannot open shared object file: No such file or directory

The Windows CPU CI - it's not related. Sync up to latest main branch should fix it.

@hans00
Copy link
Contributor Author

hans00 commented Nov 15, 2025

/usr/local/lib/android/sdk/emulator/qemu/linux-x86_64/qemu-system-x86_64: error while loading shared libraries: libpulse.so.0: cannot open shared object file: No such file or directory

This is not root cause.

android-test-results artifacts can see. I missed .onnx assets for android.

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.

[Feature Request] Migrate to JSI for React Native

2 participants