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.
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.