
Tarek Ziadé, Mozilla
Thursday Dec 18
webnn-native is stalled (2 years) and lacks modern
backend support.flowchart TD
RustNN["RustNN"]
WebNNGraph["WebNN Graph"]
Executors["Executors"]
Converter["Converter"]
ONNXRuntime["onnx runtime"]
CoreMLExec["CoreML"]
TensorRT["TensorRT"]
ONNXGraph["ONNX Graph"]
CoreMLGraph["CoreML Graph"]
RustNN --> WebNNGraph
RustNN --> Executors
WebNNGraph --> Converter
Converter --> ONNXGraph
Converter --> CoreMLGraph
Executors --> ONNXRuntime
Executors --> CoreMLExec
Executors --> TensorRT
src/graph.rs — core graph structures and immutability
guaranteessrc/validator.rs — WebNN spec validation rulessrc/shape_inference.rs — static shape computationsrc/converters/ — lowering to ONNX / CoreML graphsrc/executors/ — backend execution adapters (ONNX
Runtime, CoreML, TensorRT)import webnn
import numpy as np
# Create ML context with device hints
ml = webnn.ML()
context = ml.create_context(accelerated=False) # CPU execution
builder = context.create_graph_builder()
# Build a simple graph: output = relu(x + y)
x = builder.input("x", [2, 3], "float32")
y = builder.input("y", [2, 3], "float32")
z = builder.add(x, y)
output = builder.relu(z)
# Compile the graph
graph = builder.build({"output": output})
# Execute with real data
x_data = np.array([[1, -2, 3], [4, -5, 6]], dtype=np.float32)
y_data = np.array([[-1, 2, -3], [-4, 5, -6]], dtype=np.float32)
results = context.compute(graph, {"x": x_data, "y": y_data})
print(results["output"])
build()
time.compute() time.use rustnn::graph::GraphBuilder;
use rustnn::types::{TensorDesc, DataType};
use rustnn::context::Context;
fn main() -> anyhow::Result<()> {
// execution context (backend selection happens later)
let ctx = Context::default();
let mut builder = GraphBuilder::new(&ctx);
// input tensor description
let x = builder.input(
"x",
TensorDesc::new(DataType::Float32, vec![1, 3]),
)?;
// y = relu(x)
let y = builder.relu(&x)?;
// build immutable graph
let graph = builder.build(vec![("y", y)])?;
// execute (backend chosen internally)
let result = graph.compute(vec![("x", vec![1.0f32, -2.0, 3.0])])?;
println!("{:?}", result["y"]);
Ok(())
}
flowchart TB
WebAPI["WebNN WebIDL JS API"]
Gecko["Gecko WebNN C++"]
FFI["FFI bridge"]
Core["third_party/rust/rustnn"]
WebAPI --> Gecko
Gecko --> FFI
FFI --> Core
85 WebNN operations implemented (~89% of current spec).
All implemented ops support:
Remaining gaps are tracked.
RNN family (lstm, gru,
rnn) — deferred
A small number of ops partially implemented where backend support diverges.
CoreML partially implemented (Float16 😫).
Firefox patch POC quality (IPC layer missing).