onnx2tf pins every dependency exactly, ships a Python 3.8 badge, and tells you to use another tool
A tool for converting ONNX files to LiteRT/TFLite/TensorFlow, PyTorch native code (nn.Module), TorchScript (.pt), state_dict (.pt), Exported Program (.pt2), and Dynamo ONNX. It also supports direct conversion from LiteRT to PyTorch.
At a glance
- What is it?
- A converter from ONNX graphs to LiteRT, TFLite and TensorFlow, plus reverse conversion, with a two status operator table, exact version pins down to pytest, and a container image that installs into the system Python on purpose.
- Who is it for?
- onnx2tf suits someone with a pinned, reproducible ONNX to LiteRT conversion who reads the source rather than a tutorial: the operator table is honest about partial support and the packaging is unusually strict. Three things to check before trusting it.
- Can I use it commercially?
- Yes. MIT 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 20 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 2, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The readme's most prominent instruction is to use a different repository
The opening of the project description names the targets, ONNX to LiteRT, TFLite or TensorFlow, plus PyTorch native code, TorchScript, state_dict, Exported Program and Dynamo ONNX, and adds that direct conversion from LiteRT back to PyTorch is supported. Two sentences later comes the line that shapes everything else: you should use LiteRT Torch rather than onnx2tf, followed by links to google-ai-edge/litert-torch and google-ai-edge/ai-edge-quantizer.
So the author points users at a first party replacement while maintaining this converter. That is a defensible position for a tool with a large installed base, and it is also the first thing a newcomer reads.
What the rest of the opening text contains is the badge row and the operator table, not a walkthrough. No command with arguments appears in it, so the usage story has to come from the package's own entry points, the docs directory, or the container image.
A Python 3.8 badge sits above a declared floor of 3.12
The badge row advertises Python 3.8. The packaging metadata says `requires-python = ">=3.12"` and the classifiers name only Python 3.12 and 3.13. The badge is therefore wrong rather than conservative, and anyone reading only the rendered header would pick an interpreter that the package refuses.
The operating system classifiers narrow the field just as much: POSIX Linux and Unix, nothing else. The container image agrees, starting `FROM ubuntu:24.04` with `ARG BUILD_ARCH="linux/amd64"`. No Windows or macOS classifier is declared, even though a TFLite conversion story often starts on a desktop.
The version story is otherwise tidy. The project version is 2.6.9, the newest release is 2.6.9 published on 2026-09-14, and the default branch was last pushed on 2026-09-14. Note the tag form: releases are cut as 2.6.9 rather than with a v prefix, so tooling that assumes a v prefix will not match these tags.
Every dependency is pinned with equals, and pytest is one of them
The dependency list uses exact pins throughout, and a selected run of it looks like this:
dependencies = [
"numpy==2.2.6",
"onnx==1.20.1",
"onnxruntime==1.26.0",
"ai-edge-litert==2.1.2",
"sne4onnx==2.0.1",
"sng4onnx==2.0.1",
"protobuf==7.35.1",
"flatbuffers==25.12.19",
"pytest==9.0.2",
]Two details in that list are worth pausing on. `pytest==9.0.2` is a runtime dependency rather than a development extra, so every installation pulls in the test framework. `setuptools==81.0.0` is pinned the same way, which constrains the environment of anyone who needs a different setuptools for their own build.
The two targets that are not installed by default sit behind extras. `ai-edge-litert==2.1.2` is core, so the LiteRT path needs nothing extra, while the `tensorflow` extra brings `tensorflow==2.21.0`, `tf-keras==2.21.0` and `keras==3.15.0`, and a separate `torch` extra brings `torch==2.11.0`. Since the description advertises TensorFlow output, that difference is easy to miss until an import fails.
The container installs into the system Python with the safety flag off
The image builds from `ubuntu:24.04` and sets up pip for slow or flaky networks:
ARG BUILD_ARCH="linux/amd64"
ARG ONNX2TF_REF="main"
ENV PIP_DISABLE_PIP_VERSION_CHECK=1 \
PIP_DEFAULT_TIMEOUT=180 \
PIP_RETRIES=10 \
PIP_PROGRESS_BAR=offThe dependency install then passes `--break-system-packages`, which tells pip to write into the interpreter Ubuntu manages rather than refuse under PEP 668. That is deliberate in a disposable image and worth knowing before reusing the pattern on a machine you care about. The same step sits in a loop that tries three times and sleeps ten seconds between attempts before failing the build, which is the sort of belt and braces an exact pin list needs when one wheel disappears from an index.
Two build arguments carry the reproducibility story. `ONNX2TF_REF` defaults to `main`, so the image follows the moving default branch even though the package version is pinned at 2.6.9. A second stage installs torch from `https://download.pytorch.org/whl/cpu`, which means the image ships a CPU build of torch rather than a CUDA one.
One smaller oddity: the image installs the `python3-mock` distribution package and then uncomments line numbering in `/etc/nanorc`.
Two license files sit at the root and neither the badge row nor the table explains them
The project metadata declares MIT, and the repository root holds a LICENSE file. Beside it is a second file named LICENSE_onnx-tensorflow, which points at the upstream converter whose lineage this code follows. Nothing in the project's own description states which terms apply to which part of the tree.
The honest summary is that MIT is the declared license and a second license file exists beside it, with no stated boundary between them. Anyone redistributing a converted artifact rather than the code should read both files directly instead of assuming the declaration covers everything.
A parallel pattern shows up with flatbuffers. `flatbuffers==25.12.19` is a core dependency and a file named FLATBUFFER_DIRECT_MIGRATION_GUIDE.md sits at the root, so the buffer format upgrade was handled as a documented migration rather than a silent bump. The same root also carries SECURITY.md, CONTRIBUTING.md, CODE_OF_CONDUCT.md and CITATION.cff, a more complete administrative set than the two paragraph readme would suggest.
Partial support is marked, and nine operators carry that mark
The operator table is the substance of the readme. Two statuses are defined: a filled mark for supported and an empty mark for partial support, followed by an invitation to send pull requests for the gaps. The table is alphabetical, one row per operator, against the ONNX operator list.
In the portion visible here, nine operators carry the partial mark: BlackmanWindow, Col2Im, ConvInteger, DeformConv, DFT, GridSample, HammingWindow, HannWindow and ImageDecoder. DeformConv, GridSample and DFT are the ones most likely to matter in a real graph, and the window functions are grouped together, which suggests a shared unimplemented path rather than nine independent gaps.
Everything around them is marked supported, including the operators people expect to be difficult: Attention, RotaryEmbedding, Loop, Scan, If, the sequence operators, the quantization family and the QLinear family. Read the mark on the specific operator you need rather than assuming a green column, because a supported status covers shape and dtype handling, not numerical agreement with the original framework.
Benchmarks and a low-memory script live in the root, with no documented procedure
Measurement is committed rather than described. `benchmark_saved_model.py` and `benchmark_tflite.py` sit at the top level next to `lowmem_test_infer.py`, and a `pytest.ini` sits with a `tests/` directory. Two further directories, `test_cind/` and `make_test_op/`, hold test material under names that do not match the pytest convention, alongside `json_samples/` for input fixtures.
That layout tells you the project measures converted models and inference memory directly, which is more than most converters offer, and it tells you there are three separate places to look when a conversion misbehaves.
It also tells you what is missing. No command, no expected output and no threshold accompany those scripts, so reproducing a number means reading each file to work out its arguments. The root additionally carries three loose files that are neither package code nor documentation, `replace.json`, `demo.yml` and `AUTO_JSON_FEATURE_SUMMARY.md`, none of which the readme explains.
The project directory itself is `onnx2tf/`, the build backend is uv_build with a matching `uv.lock`, and there is both a Dockerfile and a `.devcontainer/`, so two container workflows exist side by side.
Editorial conclusion
onnx2tf suits someone with a pinned, reproducible ONNX to LiteRT conversion who reads the source rather than a tutorial: the operator table is honest about partial support and the packaging is unusually strict. Three things to check before trusting it. The declared floor is Python 3.12 while the badge advertises 3.8, the readme recommends a different repository, and TensorFlow output needs an extra that is not installed by default. For a fresh project, evaluate that recommendation first.
Frequently asked questions
how to use onnx2tf
The readme does not walk through a conversion. Its opening text says you should use LiteRT Torch rather than onnx2tf, then points at google-ai-edge/litert-torch and google-ai-edge/ai-edge-quantizer. What the package itself installs is a console script named onnx2tf plus a second entry point, onnx2tf-tflite2sm-bulk, whose target sits under onnx2tf.utils.tflite.
How can I convert an ONNX model to TFLite?
That is the main job of this project, which converts ONNX files to LiteRT, TFLite and TensorFlow. ai-edge-litert is a core dependency pinned at 2.1.2, so the LiteRT path needs no extra, while TensorFlow output sits behind an extra that pins tensorflow 2.21.0, tf-keras 2.21.0 and keras 3.15.0. Check the operator table first, since nine visible operators are marked as only partial support.
Which Python versions does onnx2tf support?
The packaging metadata requires Python 3.12 or newer and its classifiers name only 3.12 and 3.13. The badge row in the readme advertises Python 3.8, which contradicts both, so treat the declared floor as authoritative. The only operating system classifiers are POSIX Linux and Unix, and the container image builds from ubuntu:24.04 with a linux/amd64 default.
Which ONNX operators does onnx2tf only partially support?
In the visible part of the operator table, nine rows carry the partial support mark rather than the supported one: BlackmanWindow, Col2Im, ConvInteger, DeformConv, DFT, GridSample, HammingWindow, HannWindow and ImageDecoder. The table defines an empty mark as partial support and invites pull requests for those gaps.
What license is onnx2tf released under?
The project metadata declares MIT. The repository root also contains a second file named LICENSE_onnx-tensorflow alongside the main LICENSE, and the project's own description does not state how the two relate or which one covers which files. Read both files if you intend to redistribute artifacts.
Does onnx2tf install PyTorch and TensorFlow for me?
No. The core dependency list pins ai-edge-litert at 2.1.2 and does not include either framework. PyTorch comes from an optional extra pinned at torch 2.11.0, and TensorFlow comes from a separate extra pinning tensorflow 2.21.0 with tf-keras 2.21.0 and keras 3.15.0. TensorFlow is also installed by the container image, which builds it directly with pip.
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/pinto0309-onnx2tf)