An experimental, reproducible build of the ONNX Python package for Pyodide,
plus an end-to-end browser proof using scikit-learn, skl2onnx, and
ONNX Runtime Web.
Created by Gholamreza Rashidi Ardestani from the browser-local ONNX export work used in MLDeck.
Run the live browser proof · Try MLDeck · Contact MLDeck
The project was originally published to advance
pyodide/pyodide-recipes#216.
That issue was closed after maintainers confirmed that ONNX now builds and
publishes its own Pyodide wheels. Follow-up work therefore moved to the official
ONNX repository. On July 14, 2026,
onnx/onnx#8192 was accepted and merged
into the official project, adding the tested Python 3.14 /
pyemscripten_2026_0_wasm32 build configuration. The official merge commit is
67c35e5.
- The original browser proof and ONNX 1.15 recipe remain reproducible records of the MLDeck-derived work.
- The separate Pyodide recipe proposal was closed because upstream ONNX now owns wheel publication; it was not closed because the recipe tests failed.
- The official ONNX follow-up successfully produced and runtime-tested a 2026 ABI wheel using ONNX's own Pyodide build workflow.
- That follow-up was approved by an ONNX maintainer and merged into ONNX's official repository on July 14, 2026.
- A stable public browser distribution for the Python 3.14 Pyodide environment is not available yet, so that follow-up is currently validated with the official Pyodide Node runtime test. The stable Python 3.13 browser proof on this repository remains available above.
The browser demo performs the complete path:
- train a
scikit-learnmodel in Pyodide; - convert the fitted model with
skl2onnx; - validate and serialize the graph with the ONNX Python package;
- execute the generated bytes with ONNX Runtime Web; and
- make the generated
.onnxfile available for download.
onnx and onnxruntime-web are different projects. The former provides graph
construction, checking, serialization, and transformation utilities. The latter
executes an already-created model in the browser.
| Component | Version |
|---|---|
| Pyodide | 0.29.4 |
| Python | 3.13 |
| pyodide-build | 0.34.4 |
| ONNX | 1.15.0 |
| protoc | 22.3 |
| skl2onnx | 1.19.1 |
| ONNX Runtime Web | 1.22.0 |
This first public version intentionally targets the version set already proven in a production browser workflow. Updating ONNX is separate work because its CMake and Protobuf integration changes between releases.
Requirements:
- macOS or Linux;
- Python 3.13;
curlandunzip; and- enough disk space for the Pyodide cross-build environment.
python3.13 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements-build.txt
./scripts/build.shThe build script downloads the matching host-native protoc binary when the
PROTOC environment variable is not supplied. Pyodide downloads its matching
cross-build environment and Emscripten toolchain on the first build.
The wheel is written under packages/onnx/dist/.
The latest local verification record is in
docs/verification.md.
python tests/test_wheel_structure.py packages/onnx/dist/*.whlThe check confirms that the CPython extension is WebAssembly, exports the expected module initializer, excludes the upstream backend test corpus, and contains no MLDeck domain lock.
./scripts/serve-demo.shOpen http://localhost:8000/demo/ and select Run end-to-end proof.
The published proof is available at https://metalmancode.github.io/onnx-pyodide/demo/.
The first run downloads Pyodide, scientific Python dependencies, and ONNX Runtime Web. Raw training data used by the proof stays in the browser.
ONNX builds Protobuf as part of its CMake project. A target protoc compiled
for WebAssembly cannot be executed by the build host to generate C++ sources.
The first patch makes ONNX use a host-native protoc supplied through the
PROTOC environment variable while the Protobuf runtime is compiled for Wasm.
ONNX's setup script initially supplies host Python headers. The recipe appends
the target path provided by Pyodide as PYTHONINCLUDE, so CMake sees the
Python 3.13 headers from the cross-build environment.
ONNX applies the ELF-specific --exclude-libs option on non-Apple Unix builds.
wasm-ld does not support this option, so the second patch removes it.
The recipe defines GOOGLE_PROTOBUF_NO_THREAD_SAFETY for the standard
single-threaded Pyodide side-module environment.
This community repository contains only the generic build recipe, public patches, tests, and demonstration. It does not contain MLDeck application code, private AutoML workflows, customer data, service configuration, product packaging, or domain-locking logic.
The version set was developed and validated while building MLDeck, a browser-local AutoML product. The generic port is published separately so it can be reviewed and improved by the Pyodide and ONNX communities.
This port and reproducible browser proof were created by Gholamreza Rashidi Ardestani (@metalmancode).
For browser-ML integration, custom Pyodide/Wasm package work, or collaboration, contact contact@mldeck.com.
If you use or discuss this repository's build recipe, patches, verification
work, or browser proof, please credit Gholamreza Rashidi Ardestani and link
to this repository. Machine-readable citation metadata is provided in
CITATION.cff, and contributor details are recorded in
AUTHORS.md.
An earlier public proof for ONNX 1.13 and Python 3.10 was created by
Joseph Rocca. This repository
acknowledges that prior work and focuses on a newer Pyodide/Python version set,
recipe-based reproducibility, and an explicit skl2onnx conversion proof.
The repository's ONNX 1.15 recipe and browser proof are experimental. Do not rely on a generated model in production without parity, schema, preprocessing, and runtime validation. Packaging work for current ONNX releases is now tracked upstream in onnx/onnx#8192.
See docs/publication-plan.md for the recommended
public/private boundary and release sequence.
Repository-authored scripts, patches, tests, and documentation are licensed under Apache License 2.0. ONNX, Pyodide, scikit-learn, skl2onnx, Protobuf, and ONNX Runtime retain their own licenses and copyrights.