mattn/go-tflite: a cgo binding that puts TensorFlow Lite models inside Go binaries
Go binding for TensorFlow Lite
At a glance
- What is it?
- go-tflite wraps the TensorFlow Lite C API for Go through cgo, with no pure-Go fallback. It suits Go services that already ship C libraries and want local inference; it is the wrong tool if you need a single static binary or a cross-compile without a C toolchain.
- Who is it for?
- Adopt go-tflite if your Go service already links C libraries, you can install libtensorflowlite_c.so and set CGO_CFLAGS and CGO_LDFLAGS, and you want inference in-process rather than over HTTP. Do not adopt it if you need a pure-Go build, a single static binary, or cross-compilation without a C toolchain, because the module requires cgo and the C API.
- 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 10 days ago.
- What is it written in?
- Mainly Jupyter Notebook, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The gap go-tflite fills between Go services and .tflite files
Go has no official TensorFlow Lite binding. Running a .tflite model from a Go program therefore means either shelling out to a Python process, standing up a separate inference server, or writing cgo yourself against the C API. go-tflite is the third option already written: a Go package that exposes the TensorFlow Lite C API as Go types, so a model can be loaded and invoked inside the same process that handles your requests.
The audience is narrow and specific. You are writing a Go service, daemon or CLI that needs local inference on a small model, you are willing to link a C library, and you do not want a network hop to a Python runtime. The README's own framing is minimal: it calls the project a Go binding for TensorFlow Lite and points at the _example directory for more than the single sine-wave snippet it shows. Anyone expecting a high-level model zoo, preprocessing helpers or a training loop will not find one here. This is the plumbing layer.
How the cgo layer maps tensors and interpreters
The usage snippet in the README is the whole architecture in miniature. You create a model, create interpreter options, create an interpreter from the model and the options, allocate tensors, write into an input tensor, call Invoke, and read from an output tensor. Each of those objects has a matching Delete method, and the README defers all of them. That is not decoration: the Go values are handles over C memory, and the deferred calls are what release it.
Tensor access goes through typed accessors. The example writes input.Float32s()[0] = float32(v) and reads interpreter.GetOutputTensor(0).Float32s()[0]. The Float32s() method returns a slice backed by the tensor's buffer, so writing into it writes into the tensor. The repository also carries tflite_type.go and type_string.go, which suggests the binding models tensor element types as Go values rather than leaving them as raw pointers. Options are a separate object you construct and delete, which is where you would expect delegate and thread configuration to live.
The pieces at the top level tell you where the surface area is: delegates/ for delegate implementations, ops/ for operator-related code, callback.go for callbacks, and tflite_experimental.go for API that is not yet stable. If you plan to depend on anything under the experimental file, treat it as moving.
Installing the C library and running the sine example
go-tflite links against libtensorflowlite_c.so only, so the README states there is no need to build the full TensorFlow library. The build command it gives assumes the TensorFlow source is checked out and uses bazel with the monolithic config.
cd /source/directory/tensorflow
bazel build --config opt --config monolithic //tensorflow/lite/c:libtensorflowlite_c.soAfter that, cgo needs to find the headers and the linker needs the shared library. The README sets both through environment variables, and notes that if the libraries are not in a standard location you must pass the path explicitly.
export CGO_CFLAGS=-I/source/directory/tensorflow
export CGO_LDFLAGS=-L/path/to/tensorflow/libariesThe README also offers an escape hatch for people who do not want bazel: copy Makefile.tflite into tensorflow/lite/c as Makefile and run make. It states plainly that this has not been tested for Linux or Mac, so treat it as a fallback rather than the recommended path. With the environment set, the README says to run go build on some of the examples. The first real use is the snippet from the Usage section: load sin_model.tflite, allocate tensors, write one float into the input tensor, invoke, and read one float back.
model := tflite.NewModelFromFile("sin_model.tflite")
if model == nil {
log.Fatal("cannot load model")
}
defer model.Delete()If NewModelFromFile returns nil, the README's own handling is to fail immediately, which is the behaviour to copy: a nil model means the file was not found or was not a valid model, and every later call would be built on nothing.
Edge TPU support and what it costs you
The Edge TPU delegate is documented, and the instructions are more involved than the base install. You need the libraries from google-coral/edgetpu, which the README points to on GitHub, and it mentions a deb package from the Coral accelerator get-started page as an alternative. The libraries should land in a system-wide path such as /usr/local/lib, and the include files somewhere reachable from your CGO include path.
The x86 recipe is a single chained shell command that clones the repository, copies libedgetpu.so.1.0 into /usr/local/lib, creates the two symlinks, creates /usr/local/include/libedgetpu, copies edgetpu.h and edgetpu_c.h, and removes the clone. The README gives that command for x86 and does not give an equivalent for other architectures in the text shown. If you are deploying to an ARM board, plan to work out the library path yourself.
The cost is that the delegate adds a second native dependency on top of libtensorflowlite_c.so, and it is a runtime dependency, not a build-time one. A binary that works on your workstation will fail to start on a machine without libedgetpu.so.1.0. That is a deployment constraint, not a bug, but it belongs in your container image and your release checklist.
Where go-tflite is the wrong choice
The binding requires cgo. That single fact rules out a set of environments: CGO_ENABLED=0 builds, scratch containers with no dynamic loader, and cross-compilation from one platform to another without a matching C toolchain and C library for the target. If your deployment story depends on a single static Go binary, this package does not fit it, and no amount of wrapping will change that.
The second limitation is version coupling. The README states that this release requires TensorFlow Lite 2.2.0-rc3. The C API is not a stable ABI across releases in the way a Go module is, so the version of libtensorflowlite_c.so you build against is part of your dependency set, even though it never appears in go.mod. The module's own go.mod is tiny: Go 1.13 and github.com/mattn/go-pointer v0.0.1. Everything else lives outside the module graph.
Third, error handling is thin. The README's example checks for a nil model and otherwise carries on. There is no documented error type, no documented way to get a TensorFlow Lite error message back from a failed Invoke, and no documented rollback or recovery path. If you need structured failure reporting from inference, you will be building it yourself on top of what the C API returns.
Alternatives and the real difference in approach
The most direct alternative is calling the TensorFlow Lite C API yourself from cgo. That removes a dependency and gives you control over exactly which C functions you expose, at the cost of writing and maintaining the handle management, tensor accessors and type mapping that go-tflite already provides. For a project that uses two or three C functions, hand-rolling is reasonable. For anything broader, you are reimplementing this package.
A second alternative is to keep inference out of the Go process entirely: run a Python or C++ service that owns the model and have your Go code call it over HTTP or gRPC. The difference is architectural rather than syntactic. You trade an in-process C dependency for a network hop, a second deployable, and serialization on every request, but you gain the ability to update the model without rebuilding the Go binary and to use the full TensorFlow Lite tooling on the serving side. If your model changes weekly and your Go service changes monthly, that trade is worth considering.
A third option is a different runtime. The RELATED searches show people comparing LiteRT and TFLite, and the naming has shifted in Google's own documentation. That comparison is about which runtime you target, not about the Go binding, and go-tflite's README does not address it. What the README does address is Flutter only by absence: there is no Flutter or mobile story here, and the Android-related search traffic for this project is not matched by anything in the documentation.
Maintenance, licence and the upgrade path
The repository is not archived, and the last push was on 2026-08-19. Two releases landed in August 2026: v1.0.6 on 2026-08-17 and v1.0.7 on 2026-08-18. Before that, v1.0.5 is tagged buildkit-20240529 and dates to 2024-05-30, so there is a gap of roughly two years between v1.0.5 and the v1.0.6 line. That pattern matters more than the release count: work arrives in bursts, and you should not assume a fix for a problem you hit will land on a predictable schedule.
The licence is MIT, stated in the README and present as a LICENSE file at the repository root. MIT is permissive, so the usual obligations apply: keep the copyright notice and the licence text with copies or substantial portions of the software. That is a description of what the licence says, not legal advice, and it says nothing about the licences of TensorFlow Lite itself or of libedgetpu.so.1.0, which are separate dependencies you are also distributing.
The upgrade cost is concentrated in the C library, not in the Go module. Bumping go-tflite in go.mod is cheap. Rebuilding libtensorflowlite_c.so against a new TensorFlow Lite version, re-running the bazel target, and re-testing every model's tensor types is the expensive part. Pin the TensorFlow Lite version you build against and treat that pin as part of your release, because go.mod will not record it for you. The docker/gophernotes image referenced in the README, published as ghcr.io/mattn/go-tflite/gophernotes, is one documented way to get a working environment without repeating the C build by hand.
Editorial conclusion
Adopt go-tflite if your Go service already links C libraries, you can install libtensorflowlite_c.so and set CGO_CFLAGS and CGO_LDFLAGS, and you want inference in-process rather than over HTTP. Do not adopt it if you need a pure-Go build, a single static binary, or cross-compilation without a C toolchain, because the module requires cgo and the C API. Before writing code, confirm three things: the pinned TensorFlow Lite version (the README says this release requires 2.2.0-rc3), the location of the built shared library, and whether your target board needs the Edge TPU delegate, which pulls in libedgetpu.so.1.0 from google-coral/edgetpu. The repository's own examples directory is the fastest way to check that your model's input and output tensor types line up with the binding.
Frequently asked questions
What is TensorFlow Lite used for, and where does go-tflite fit?
TensorFlow Lite runs machine learning models on devices rather than on a server, and go-tflite exposes its C API to Go programs. The README's example loads a .tflite model, writes a value into an input tensor, invokes the interpreter and reads the output tensor, all inside the Go process.
Is TensorFlow Lite free?
The go-tflite repository itself is MIT licensed, with a LICENSE file at the root and the licence stated in the README. The licence terms for TensorFlow Lite and for the Edge TPU libraries are separate from this project and are not covered in the README.
What is LiteRT used for, and how does it relate to go-tflite?
The README does not mention LiteRT at all, so there is nothing in the documentation to confirm how the two relate. What the README does state is that go-tflite is a Go binding for TensorFlow Lite and that this release requires TensorFlow Lite 2.2.0-rc3.
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/mattn-go-tflite)