microsoft / microsoft/onnxruntime

[Feature Request] [Web] Add Dynamic linking

Open
#32,450 0 comments 0 reactions 0 assignees View on GitHub
ep:WebGPU ep:WebNN ep:Xnnpack feature request platform:web
Dominant language
C++
Stars
21.9k
Forks
4.2k
Avg merge
4d 11h
Merged PRs (30d)
184

Description

### Describe the feature request

Every provider combination is currently a separate full build for web. Uncompressed, XNNPACK only is 19.7 MB, adding WebGPU is 39.1 MB, adding WebNN is 42.5 MB. A library that ships the choice ships three copies of the runtime, and a consumer picks accelerators at build time by choosing which artifact to serve.

Native already has the other model. OrtEpFactory and RegisterExecutionProviderLibrary load a provider at run time, and plugin EPs are built as separate libraries. Emscripten supports the same shape through MAIN_MODULE and SIDE_MODULE.

If the WebAssembly build had it, one runtime plus side modules would replace the build matrix. onnxruntime-extensions could be loaded rather than needing --use_extensions baked into yet another variant. And ONNX Runtime GenAI would have a path to the web at all, since it resolves OrtGetApiBase by name rather than linking against it, which is the same dynamic loading problem.

Is this a direction you would consider, or is compiling in deliberate?

The loading code already exists and needs no change. The WebAssembly build uses the posix platform layer, and Env::LoadDynamicLibrary in onnxruntime/core/platform/posix/env.cc is a plain dlopen with no __EMSCRIPTEN__ guard and no stub. Emscripten provides dlopen, and it resolves once the main module is built with MAIN_MODULE. So this looks like link configuration rather than C++ changes.

### Describe scenario use case

Feature parity with native and also loading of EPs at runtime not requiring swapping the whole runtime.

ALso, for loading onnxruntime-extensions. It already builds for Emscripten, just static only: cmake/ext_wasm.cmake takes the static path and CMakeLists.txt sets _ORTX_SHARED_BUILD_SUPPORTED OFF there. So --use_extensions produces a working wasm runtime and RegisterCustomOpsLibrary is the only part that cannot work. There is also no published wasm artifact with the operators compiled in, so today it needs a source build either way.
The same may later apply for GenAI.

Contributor guide

Open the contributing guide

Research direction

Start with onnxruntime/core/platform/posix/env.cc, cmake/ext_wasm.cmake, and the relevant CMakeLists.txt settings for Emscripten. Review how MAIN_MODULE and SIDE_MODULE interact with the existing dynamic-loading entry points, then compare the static extensions path with the requested runtime and side-module layout. Done means a WebAssembly build can use one runtime and load a provider or extensions side module at runtime.

Written by the indexing model from the issue text.

Assessment

Tech stack
cmake, cpp, wasm
Domain
build-system, web-dev
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.