TensorFlow.js: what the monorepo actually ships, and how to pick a backend
A WebGL accelerated JavaScript library for training and deploying ML models.
At a glance
- What is it?
- TensorFlow.js is a hardware-accelerated JavaScript library for training and running models in the browser, in Node.js, and in React Native. The real decision is not whether to use it but which of its many backends and packages you install.
- Who is it for?
- Adopt TensorFlow.js when the model has to run where the JavaScript already runs, on a user's device, in a page, or inside a React Native app, and when you can accept the backend's numerical and performance limits. Do not adopt it as a substitute for a Python training pipeline on large models, and do not pick it for Node.js inference before checking whether the native @tensorflow/tfjs-node binding has a prebuilt binary for your platform.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 99 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 28, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The problem TensorFlow.js solves: inference where the JavaScript already runs
Most machine learning tooling assumes Python and a server. TensorFlow.js starts from the opposite assumption: the code that needs the model is already running in a browser tab, in a Node.js process, or inside a React Native app. The README frames this in four ways: develop ML in the browser, develop ML in Node.js, run existing models, and retrain existing models on client-side data. The fourth is the one that is hard to replicate elsewhere. Retraining a model on sensor data that never leaves the device is a privacy argument as much as a performance one, and it is the case where a server round trip is not merely slower but architecturally wrong.
The audience is therefore front-end and full-stack JavaScript engineers, not research teams. If your team already writes TypeScript and ships to browsers, the cost of adding a model is a package install rather than a second language runtime. If your team trains large models in Python on GPUs, TensorFlow.js is a deployment target, not a replacement.
One repository, many packages: how the monorepo is laid out
The README states plainly that the repository contains the logic and scripts that combine several packages, and the top-level directories confirm it. The API surface is split into tfjs-core (low-level linear algebra and neural network primitives), tfjs-layers (a high-level API the README describes as implementing functionality similar to Keras), tfjs-data (loading and preparation, analogous to tf.data), tfjs-converter (importing a TensorFlow SavedModel), tfjs-vis (in-browser visualization), and tfjs-automl.
Underneath sit the backends, and this is where the real architecture lives. tfjs-backend-cpu is a pure-JS backend for Node.js and the browser. tfjs-backend-webgl is the WebGL backend for the browser. tfjs-backend-wasm is a WebAssembly backend for the browser. tfjs-backend-webgpu is the WebGPU backend for the browser. tfjs-node runs native TensorFlow through a C++ adapter, with tfjs-node-gpu as a sibling directory. tfjs-react-native goes through an expo-gl adapter.
That directory list is also the answer to a common complaint about bundle size. The README says that if you care about bundle size, you can import those packages individually. The aggregate @tensorflow/tfjs package pulls in the CPU and WebGL backends together; importing @tensorflow/tfjs-core plus a single backend is the smaller path.
Installing TensorFlow.js and running a first linear regression
There are two documented routes. The script tag route needs no build tooling at all: the README shows loading tf.min.js from jsDelivr and then writing code in a second script tag, with no import statement because tf is already global.
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs/dist/tf.min.js"> </script>
<script>
const model = tf.sequential();
model.add(tf.layers.dense({units: 1, inputShape: [1]}));
model.compile({loss: 'meanSquaredError', optimizer: 'sgd'});
</script>Open that file in a browser and the code runs. The README's own example then builds tensors with tf.tensor2d, calls model.fit, and prints a prediction for the input 5. The expected output appears in the browser devtools console, not on the page.
The npm route is the one most projects take. The README notes that the ES2017 syntax used here assumes a modern browser or a bundler that transpiles down, and points at the examples repository for how Parcel is used. A yarn or npm install followed by an import gives you the same API:
import * as tf from '@tensorflow/tfjs';
const model = tf.sequential();
model.add(tf.layers.dense({units: 1, inputShape: [1]}));
model.compile({loss: 'meanSquaredError', optimizer: 'sgd'});
const xs = tf.tensor2d([1, 2, 3, 4], [4, 1]);
const ys = tf.tensor2d([1, 3, 5, 7], [4, 1]);
model.fit(xs, ys).then(() => {
model.predict(tf.tensor2d([5], [1, 1])).print();
});For Node.js the README redirects to the tfjs-node directory rather than repeating install steps, so the exact package name and platform requirements should be read there. If you only need inference and not training, tfjs-inference and tfjs-tflite exist as separate directories, which suggests the maintainers expect the training and inference footprints to be chosen independently.
Choosing a backend is the actual engineering decision
The backend list is not a menu of equivalents. WebGL is the browser default and works widely, but it routes computation through graphics APIs that were designed for pixels, and its numerical precision and kernel coverage differ from native TensorFlow. WASM trades some of the GPU speed for a more predictable execution model. WebGPU is the newest of the three browser backends and, as the directory name suggests, depends on WebGPU being available in the browser.
The README does not rank them, and it should not be read as doing so. It ships a local benchmark tool at tfjs-benchmarks.web.app that collects speed and memory metrics for TensorFlow.js models and kernels on your own device across the CPU, WebGL and WASM backends, and a separate multi-device tool that does the same across a set of remote devices. That is the honest answer to "which backend is faster": measure on the hardware you ship to, because the ranking is device-dependent. The README also notes you can benchmark custom models by following the local-benchmark guide in the e2e directory.
In Node.js the trade-off is different in kind. tfjs-node uses a native TensorFlow C++ adapter, so it is closer to the Python runtime in behaviour, at the cost of a native dependency. The pure-JS CPU backend has no such dependency and will run anywhere Node runs.
Where TensorFlow.js is the wrong tool
The clearest boundary is training scale. The library is built for training in the browser and in Node.js, and the README's framing of retraining existing models with sensor data describes a small-model, on-device workflow. Nothing in the README suggests it is meant to replace a Python training pipeline for large models on GPUs. If your workflow is train big in Python, serve small at the edge, TensorFlow.js is the second half of that sentence.
The second boundary is the converter. Running a pre-existing TensorFlow model depends on tfjs-converter importing a SavedModel or a Keras model. The README lists both as supported, but the existence of a dedicated converter package and a CONTRIBUTING_MISSING_OP.md file at the repository root is a signal worth reading: operator coverage is an ongoing concern, and a model that uses ops the converter does not handle will not port cleanly. Check your specific model before you commit to the approach.
The third is numerical fidelity. A model ported to a WebGL backend is not guaranteed to produce bit-identical outputs to the same model in Python. For classification with a comfortable margin this rarely matters. For anything where the output is a precise quantity, it does.
Alternatives and how they differ
The alternative people most often weigh is ONNX Runtime Web. The difference in approach is the model format and the conversion path rather than the runtime target: ONNX Runtime Web consumes ONNX graphs, while TensorFlow.js consumes TensorFlow SavedModel and Keras files through tfjs-converter. If your models already live in ONNX, the TensorFlow.js converter is an extra hop; if they live in TensorFlow, the reverse is true.
Within the TensorFlow family, the choice is between TensorFlow.js and TensorFlow Serving behind an HTTP API. Serving keeps the model on infrastructure you control and lets the client stay thin, at the cost of a network round trip per inference and of sending the input off the device. TensorFlow.js removes that round trip and keeps the data local, at the cost of shipping model weights to the client and accepting the backend's performance ceiling. For a model that is large, or that changes often, or that must not be distributed, the server route is the better fit.
The third comparison is tfjs-node against a Python service. tfjs-node exists so the same TensorFlow.js API runs under Node.js with native TensorFlow underneath. If your serving layer is already Node.js, that avoids running two runtimes; if it is Python, it adds one.
Maintenance, releases and the Apache-2.0 licence
The repository is not archived, and the last push was on 2026-06-23. The most recent release listed is tfjs-v4.22.0 from 2024-10-21, following tfjs-v4.21.0 in September 2024 and tfjs-v4.20.0 in June 2024. The gap between the last push and the last tagged release is worth noting when you plan an upgrade cadence: commit activity and npm releases are not the same clock, so pinning a version in package.json is the practical approach.
The build system is a cost of contributing rather than of consuming. The root package.json lists Bazel tooling (@bazel/bazelisk, @bazel/buildifier, @bazel/concatjs, @bazel/typescript and others), alongside karma for browser testing and rollup plugins. There is a BAZEL_MIGRATION.md at the root, and the repository carries cloudbuild.yml and cloudbuild-release.yml, so releases go through Google Cloud Build. If you plan to patch a backend locally, expect to work inside that toolchain rather than a plain tsc build.
The licence is Apache-2.0, which is permissive and includes an explicit patent grant. That matters for a library you embed in a shipped product. It is not legal advice: if you redistribute modified sources or bundle the library into a commercial binary, have counsel read the NOTICE and patent-termination clauses rather than taking this paragraph as clearance.
Editorial conclusion
Adopt TensorFlow.js when the model has to run where the JavaScript already runs, on a user's device, in a page, or inside a React Native app, and when you can accept the backend's numerical and performance limits. Do not adopt it as a substitute for a Python training pipeline on large models, and do not pick it for Node.js inference before checking whether the native @tensorflow/tfjs-node binding has a prebuilt binary for your platform. Verify first: run the local benchmark tool on your target devices with the backends you plan to ship, and confirm the converter can import your SavedModel or Keras file before committing to a port.
Frequently asked questions
What is TensorFlow.js used for?
The README describes four uses: building models from scratch in the browser with the core or layers API, running the same API under Node.js with native TensorFlow, running pre-existing TensorFlow models in the browser through the converter, and retraining existing models on client-side data such as sensor input.
How do you install TensorFlow.js for Node.js?
The README does not repeat the Node.js install steps in the main file; it redirects to the tfjs-node directory, and there is a separate tfjs-node-gpu directory for the GPU variant. Read the install instructions in that directory rather than assuming the browser package applies.
Is TensorFlow.js the same as TensorFlow in Python?
No. TensorFlow.js is a JavaScript library with its own core, layers and data packages, and it can run pre-existing TensorFlow SavedModel or Keras models through tfjs-converter. Under Node.js, tfjs-node executes native TensorFlow through a C++ adapter, but the browser backends are WebGL, WASM, WebGPU and pure-JS CPU.
Which TensorFlow.js backend should you use?
The README lists CPU, WebGL, WASM and WebGPU backends for the browser plus the Node.js and React Native platforms, without ranking them. It provides a local benchmark tool that measures speed and memory on your own device across the CPU, WebGL and WASM backends, which is the documented way to decide.
Can TensorFlow.js run a model trained in Python?
The README states that TensorFlow.js Converter imports a TensorFlow SavedModel, and that porting pre-trained models from TensorFlow SavedModel and Keras is supported. Operator coverage is a separate matter, which is why the repository carries a CONTRIBUTING_MISSING_OP.md file.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/tensorflow-tfjs)
Community notes