On July 9, 2026, Google officially announced LiteRT.js, a new runtime for running machine learning models inside the browser. It uses WebGPU for GPU execution, and for the CPU path runs WebAssembly (Wasm) with XNNPACK built in. Looking ahead, the plan is to also connect to dedicated hardware such as NPUs via WebNN. But the real change goes deeper than the speed numbers suggest. It's an attempt to bring .tflite models—long used for Android and iOS—to the Web as well, unifying a pipeline that had otherwise been fragmented from training framework all the way to deployment target.
In-browser inference has the advantage of being able to process camera footage or audio without sending it to a server. It keeps working even when the network connection drops, and there's no need to pay for cloud GPU usage on every inference call. On the other hand, the model itself gets distributed to the user's device. This makes it unsuitable for services that need to keep their weights confidential, or for huge models that won't fit in a device's memory.
Ending the Era Where the Web Alone Needed a Separate Format
To understand LiteRT.js, we need to go back to September 2024, when Google renamed TensorFlow Lite to "LiteRT." At the time, this was mainly a rebranding—the .tflite extension and the FlatBuffer format were both kept as-is. The goal was to move away from the identity of "a lightweight version of TensorFlow" and expand into a runtime connecting multiple training frameworks, including PyTorch and JAX, with Android, iOS, and embedded devices.
LiteRT.js fills in the Web-side piece that had been missing from that vision. Until now, according to Google's explanation, deploying a PyTorch model via TensorFlow.js required a chain of conversions: PyTorch to ONNX, then to TensorFlow, then to TensorFlow.js. With LiteRT.js, you can convert directly from PyTorch to LiteRT and load the resulting .tflite file in the browser. Because the same model artifact can also be carried over to mobile and desktop, developers no longer need to maintain a separate Web-only export and validation pipeline.
This doesn't mean the end of TensorFlow.js. Google made clear even at the time of the 2024 renaming that TensorFlow.js would continue to exist independently. LiteRT.js simply adds a new option alongside it. Developers who want to consolidate on the .tflite format no longer have to treat the browser as a special case.
A Three-Layer Structure: Wasm, WebGPU, and WebNN

LiteRT.js switches its execution target depending on the computation APIs the browser exposes. On the CPU path, it runs XNNPACK—a fast neural network operation library—on top of Wasm. On the GPU path, it uses WebGPU, which abstracts native APIs such as Direct3D 12, Metal, and Vulkan. And WebNN is a dedicated API for reaching CPUs, GPUs, and NPUs through the OS's machine learning infrastructure.
| Path | Primary Target | Current Role | Key Requirements / Constraints |
|---|---|---|---|
| Wasm + XNNPACK | CPU | Baseline path providing the broadest compatibility | Large models can hit Wasm's memory limits |
| WebGPU + ML Drift | Integrated/discrete GPU | Runs compute-heavy models in parallel | Results vary by browser, GPU, and operator coverage |
| WebNN | CPU, GPU, NPU | Connects to the OS's ML capabilities and dedicated hardware | Not yet generally available; requires experimental browser flags |
Google's current guide lists Chrome and Edge 113+ and Safari 17.4+ as the baseline for WebGPU support, with Firefox 121+ offering partial support. WebNN is even earlier-stage: it requires enabling an experimental feature on Chromium-based browsers 121 and later, and Google states that no browser has shipped it as generally available yet. On Windows it also requires a DirectX 12 environment with DirectML support, on macOS Apple Silicon, and on Linux an OpenVINO configuration.
The WebNN specification itself, as of the June 26, 2026 revision, sits at the W3C Candidate Recommendation Draft stage. While the spec has progressed toward abstract device selection that includes NPUs, it hasn't reached the stage of guaranteeing a finalized recommendation or interoperability across multiple browsers. The fact that LiteRT.js has prepared an NPU path should be kept separate from the question of whether ordinary Web apps can reliably use an NPU starting today.
This is where JSPI (JavaScript Promise Integration) comes into play. It's a mechanism that bridges synchronous processing inside Wasm with asynchronous device operations like WebNN, and LiteRT.js requires a JSPI-enabled build when using WebNN. The performance race in browser-based AI is no longer just about how fast GPU kernels run—it's shifting toward how seamlessly you can cross the boundaries between different execution systems without waiting.
Keeping TensorFlow.js While Swapping Out Only the Inference Engine
Rewriting an existing Web app all at once—from preprocessing through to screen rendering—isn't realistic. Google provides @litertjs/tfjs-interop, along with runWithTfjsTensors, which passes TensorFlow.js tensors into LiteRT.js. This lets you keep image resizing, normalization, and post-inference top-class extraction in TensorFlow.js, while swapping out only the model loading and execution to LiteRT.js.
However, the connection point isn't free. If the two runtimes use different WebGPU devices, tensor conversion and memory copying increase. The official instructions call for sharing the same GPU device, and warn against using TensorFlow.js's synchronous readback function dataSync when using WebGPU. Even if the GPU itself is fast, if you keep sending input from the CPU and waiting for results to come back to the CPU every time, the overall latency of the app won't shrink.
ONNX Runtime Web, a competing option, already supports Wasm, WebGPU, and WebNN. It also has I/O binding, which keeps input and output in GPU buffers, and graph capture, which bundles calls to a static graph. So WebGPU support alone doesn't settle which one is superior. The real difference comes down to deployment design: how close your existing model is to .tflite versus ONNX, how much of the converted graph's operators are actually supported, and whether you want to share the same artifact between mobile and Web.
LiteRT.js resonates most strongly with teams already using LiteRT on Android or iOS, or teams that want to feed PyTorch directly into Google's edge-oriented stack. Conversely, for products that have made ONNX the center of their deployment pipeline and have already built up WebGPU-specific optimizations, simply switching runtimes doesn't guarantee a benefit. The unit of comparison shouldn't be the library name—it should be the entire pipeline, from converting your own model to returning results to the screen.
How to Read the "Up to 3x" Claim
In announcing LiteRT.js, Google claimed up to 3x the performance of existing Web runtimes. The comparison chart uses ONNX Runtime as the baseline of 1, measured in a "controlled browser environment" on a 2024 MacBook Pro with an M4 chip. However, the browser name and version aren't disclosed. Nor are the results uniform.
| Model | LiteRT.js CPU / ONNX Runtime CPU | LiteRT.js WebGPU / ONNX Runtime WebGPU |
|---|---|---|
| efficientnet | 1.7x | 3.15x |
| inception_v3 | 3.33x | 1.11x |
| resnet-50 | 1.33x | 1.23x |
| whisper_base | 1.12x | 1.53x |
| YOLO26n | 1.55x | 1.57x |
The highest value in the chart was 3.33x for inception_v3 on CPU, and 3.15x for efficientnet on WebGPU. Meanwhile, the WebGPU gap for inception_v3 was just 1.11x, and the CPU gap for whisper_base was just 1.12x. Google's "up to 3x" phrasing in the body text is a rounded figure—the chart actually contains values slightly above 3x. Swapping runtimes doesn't always produce the same gap.
Another chart compares Efficientnet for image classification against Yolo11n for object detection. For audio, it compares Deepspeech for ASR against Whisper Base as a text encoder, and Isnet for image segmentation. Google's text states that WebGPU or WebNN achieved 5 to 60x over CPU, but the chart lists Whisper Base on WebNN at 67.2x. Here too, the body text is rounding down.
Furthermore, the chart's Efficientnet row lists CPU at 23.86ms, WebGPU at 3.96ms, and WebNN at 3.07ms, yet reports speedups of 7.9x and 7.1x. These don't match what you get from simply dividing the displayed latency figures. The measurement conditions don't specify browser name or OS. The number of iterations, warmup, and input shape are all unknown, and quantization precision isn't disclosed either. WebNN is said to go through Apple CoreML, but the chart alone doesn't confirm it actually ran on Apple's NPU.
The average 1.4x figure for LiteRT GPU that Google presented in January 2026 was a comparison against the old TensorFlow Lite GPU delegate. This, too, is not the same as a LiteRT.js vs. ONNX Runtime Web number. The "up to 3x," "5 to 60x over CPU," and "average 1.4x" figures each involve different target models and different baselines for comparison, so they can't be mixed together into a single representative performance number.
In browser inference, measuring only the computation time of the model itself doesn't tell you the user's actual wait time. The first run includes loading Wasm, downloading the model, compiling the graph, and preparing GPU shaders. During execution, preprocessing, transfers between CPU and GPU, and postprocessing all follow. For short models, fixed costs dominate; for heavy convolutions or matrix operations, GPU parallelism tends to pay off more.
This is why Google recommends @litertjs/model-tester. This tool uses random input to check whether a model runs to completion on WebNN, WebGPU, and CPU, and runs a specified number of benchmark iterations. Before adopting a runtime, you should at minimum measure, on each target device, the initial startup latency, the post-warmup latency, peak memory usage, and whether any fallback to CPU occurs.
LiteRT.js tensors must be explicitly released by the developer. Moving results back to the Wasm side to read as a JavaScript array also involves a transfer. If you forget to delete tensors inside an inference loop, a short benchmark may look fast while memory keeps growing during long-running operation. Evaluating speed matters just as much through stability after running a camera for several minutes as it does through a few dozen inference measurements.
Four Boundaries Standing in the Way of Production Deployment
The first boundary is model conversion. Google's PyTorch instructions assume the model can be exported via torch.export.export, i.e., through TorchDynamo. Python conditional branching that depends on runtime tensor values can't be used, and the current guide doesn't support dynamic dimensions in input/output tensors, including batch size. Simply placing a trained model into the browser as-is won't necessarily work—the model may need to be rewritten.
The second is operator coverage, and here Google's own published information is inconsistent. The Get Started guide, updated June 12, 2026, states that partial delegation is not supported, while the Overview explains that operators unsupported by WebGPU or WebNN are automatically fallen back to CPU. The core README on the GitHub main branch goes into even more detail, stating that on JSPI-supporting browsers, WebGPU-unsupported operators are split off to Wasm on a per-operator basis, while on browsers without JSPI support, the entire model falls back to Wasm.
Given this discrepancy, the behavior of the stable release 2.5.x can't be pinned down from documentation alone. You need to fix the npm version you're using, distinguish between the presence and absence of JSPI, and check via the model tester and your actual application's logs where fallback is actually occurring. Whether only part of the operators move to CPU or the entire model falls back to CPU makes a huge difference in what the latency numbers actually mean.
The third is data format and memory. The current guide only supports int32 and float32 for model input/output. Because of Wasm's memory limits and buffer layout, large models can fail to load. Even if quantizing weights shrinks the file size, separate constraints remain on the computation type and the input/output types.
The fourth comes down to the maturity of Web standards. WebGPU has entered practical use, but WebNN remains experimental. For enterprises deploying Web apps to a broad range of unspecified devices, the practical baseline for now is Wasm and WebGPU, with WebNN serving as an upside path on supported machines. What Google has actually completed with LiteRT.js isn't NPU performance itself—it's the entry point for carrying the same model from CPU to GPU and, eventually, to NPUs.
Whether to adopt LiteRT.js can't be decided by marketing multipliers. The deciding factors are clear: does the value of being able to deploy the same .tflite file to both Web and mobile outweigh the conversion cost; does the operator graph run to completion on WebGPU in your target browsers; and do actual measurements, including first-run startup, beat your existing runtime? Once all three conditions are met, the browser stops being an exceptional deployment target for LiteRT.