Skip to content

[Mobile] unimodule.json makes Expo exclude onnxruntime-react-native from autolinking — NativeModules.Onnxruntime is null ("Cannot read property 'install' of null") #29004

@danielweinmann

Description

@danielweinmann

Describe the issue

In Expo projects, importing onnxruntime-react-native crashes the app at startup:

[runtime not ready]: TypeError: Cannot read property 'install' of null

The Android build succeeds, but OnnxruntimePackage is never registered, so NativeModules.Onnxruntime is null when dist/commonjs/binding.js calls Module.install() at import time.

Root cause: the package ships a unimodule.json (added in #11556, May 2022). expo-modules-autolinking treats the presence of that file as "this dependency is an Expo module" and therefore excludes it from React Native community autolinking (expo-modules-autolinking react-native-config). Since it isn't actually an Expo module, nothing registers it on the Expo side either. The chain:

  1. node_modules/onnxruntime-react-native/unimodule.json exists
  2. npx expo-modules-autolinking react-native-config --json omits the package
  3. → the generated PackageList.java has no OnnxruntimePackage entry (the Gradle project still builds, so there is no build-time signal)
  4. NativeModules.Onnxruntime === null → import-time Module.install() throws

Ironically, the package already ships a correct react-native.config.js with packageImportPath / packageInstance — React Native community autolinking knows exactly how to register it. The unimodule.json classification is the only thing preventing that from happening in Expo apps.

Fix (verified): delete unimodule.json. After removing it (via a pnpm patch) and re-running npx expo prebuild:

  • expo-modules-autolinking react-native-config reports the package with packageInstance: new OnnxruntimePackage()
  • the generated PackageList.java contains new ai.onnxruntime.reactnative.OnnxruntimePackage()
  • the app boots and on-device inference works (66M-parameter model through the JSI binding) — verified on Expo SDK 56 / React Native 0.85 / onnxruntime-react-native 1.24.3 on Android, without the app.plugin.js config plugin

This appears to be the root cause behind several issues that were closed without a fix (#19510, #26925, #26796). It is also the reason the Expo config plugin has to manually inject OnnxruntimePackage into MainApplication, which is its own recurring source of breakage (#28657, #28672) — with unimodule.json removed, standard autolinking registers the package and the plugin's MainApplication patching becomes unnecessary on Android.

Historical note: when #11556 added the file, it presumably helped Expo's then-current tooling discover the package. Today's expo-modules-autolinking instead interprets it as an Expo-module marker and hides the package from React Native autolinking — the opposite of the original intent.

One migration consideration: apps currently working around this via app.plugin.js or a manual react-native.config.js entry would register the package twice once autolinking starts working, so the config plugin likely wants to drop its MainApplication modification in the same release.

To reproduce

  1. Create an Expo app, add onnxruntime-react-native 1.24.3, and import it
  2. npx expo prebuild -p android && npx expo run:android
  3. The app crashes at startup with the error above
  4. Inspect: npx expo-modules-autolinking react-native-config --json | grep -i onnx → no output; the generated PackageList.java has no OnnxruntimePackage
  5. rm node_modules/onnxruntime-react-native/unimodule.json, re-run prebuild → the package is registered and the app boots

The crash has been reported across Expo SDK versions (50 through 55 in the issues linked above); I verified the chain end-to-end on SDK 56. On SDK 56 / Gradle 9 you will also hit the VersionNumber build failure — already fixed on main by #27385 but not present in any release yet.

Urgency

There is a workaround (patch the package to delete the file), but the failure is at runtime with no build-time signal, and duplicates of this keep being filed and auto-closed by the stale bot.

Platform

Android

OS Version

Any (the issue is in autolinking classification, not OS-specific; iOS is likely affected the same way since the classification is platform-independent)

ONNX Runtime Installation

Released Package

ONNX Runtime Version or Commit ID

1.24.3 (the file is still present on current main)

ONNX Runtime API

JavaScript

Architecture

ARM64

Execution Provider

Default CPU

Metadata

Metadata

Assignees

No one assigned

    Labels

    api:Javaissues related to the Java APIapi:Javascriptissues related to the Javascript APIplatform:mobileissues related to ONNX Runtime mobile; typically submitted using templateplatform:webissues related to ONNX Runtime web; typically submitted using template

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions