Open-source project
goplus/ixgo avatar
goplus/ixgo

goplus/ixgo: a Go interpreter that runs Go 1.25 to 1.27 source, generics included

The Go/XGo Interpreter

142 stars21 forksGoApache-2.0

At a glance

What is it?
iXGo executes Go and XGo source without a build step, covering generics and generic methods across ABI0 and register-based ABIs. It is aimed at embedders who need to run Go code inside a Go process, and it is not a drop-in replacement for the gc toolchain.
Who is it for?
Adopt iXGo when you need to execute Go or XGo source inside a running Go program, for a playground, a plugin surface, or a REPL, and you can live with the supported Go version window and the missing test flags. Do not adopt it as a replacement for the gc toolchain in production builds, and do not expect the full go test surface: the README lists test -fuzz and test -cover as unsupported.
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 10 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What iXGo runs that the gc toolchain will not run at runtime

The Go toolchain compiles ahead of time. If you want to execute a Go snippet that arrives while your program is already running, you need either a subprocess, a plugin built against an exact toolchain version, or an interpreter. iXGo is the third option: a Go interpreter written in Go, published as the module github.com/goplus/ixgo under Apache-2.0.

The README states the scope precisely. It supports all Go language features, including generics and generic methods, and it targets Go 1.25 through 1.27. The audience is therefore narrow and specific: people building playgrounds, REPLs, plugin hosts, and teaching tools where Go source has to be evaluated in-process. The two demos linked from the README, the XGo Playground and the XGo REPL Playground, are both WebAssembly builds, which tells you the project is comfortable running in a browser as well as on a server.

It is not a compiler replacement. Nothing in the README claims it produces standalone binaries for deployment, and the ixgo build subcommand is described as compiling a Go/XGo package, not as emitting a native executable.

The interpreter pipeline: importer, SSA, and two calling conventions

The repository layout shows the shape of the machine. importer.go and package.go handle loading, transform/ holds the transformation stage, and the interpreter core is spread across interp.go, opblock.go, ops.go, opcvt.go, binop.go, unop.go and their generated counterparts (binop_gen.go, opcvt_gen.go, and so on). Generated files for operators suggest the dispatch table is produced rather than hand-written, which is the usual way to keep an interpreter loop fast in Go.

Two calling conventions are named in the README: ABI0, the stack-based convention, and ABIInternal, the register-based convention from the Go register calling convention proposal. The register-based path is listed for amd64, arm64, ppc64/ppc64le, riscv64 and loong64. That list is the practical portability boundary. On an architecture outside it, you fall back to the stack-based path.

Compilation is not limited to gc. The README names two compilers, Go (gc) and LLGo, and the tree contains runtime_func.go alongside runtime_func_llgo.go, a build-tagged variant for the LLGo runtime. There is also a linkname mode, documented as a separate install, which the README says uses runtime linkname for faster performance of iter.Pull and iter.Pull2. That is an explicit trade: speed for a build that disables the linkname check.

Install the ixgo CLI and run a first package

The README gives a single install command for the command line tool. It installs the ixgo binary from the cmd/ixgo package at the latest version.

bash
go install github.com/goplus/ixgo/cmd/ixgo@latest

There is a second command line tool for exporting Go packages into iXGo builtin packages. It lives in cmd/qexp.

bash
go install github.com/goplus/ixgo/cmd/qexp@latest

With the binary on your PATH, the README lists the available subcommands: ixgo on its own starts REPL mode, and run, build, test, version and export are the named verbs. Run mode takes build flags plus a package and arguments.

bash
ixgo run [build flags] [package] [arguments...]

The README documents the flags for run mode: -exp-gc for experimental runtime.GC support, -mod with values readonly, vendor or mod, -ssa to print SSA instruction code, -ssa-trace to trace SSA interpreter code, -tags for build tags, -v to print package names as they are compiled, and -x to print the commands. If you want to see what the interpreter is doing rather than what the program prints, -ssa-trace is the flag to reach for.

The REPL defaults to XGo syntax. To get plain Go syntax, the README gives this form.

bash
ixgo repl -go

Embedding is a library call rather than a CLI invocation. The README's Go demo imports the interpreter and a builtin package for fmt, defines the source as a string, and calls ixgo.RunFile with the filename, the source, a nil argument, and a zero flag value.

go
package main

import (
	"github.com/goplus/ixgo"
	_ "github.com/goplus/ixgo/pkg/fmt"
)

var source = `
package main

import "fmt"

func main() {
	fmt.Println("Hello, World")
}
`

func main() {
	_, err := ixgo.RunFile("main.go", source, nil, 0)
	if err != nil {
		panic(err)
	}
}

Note the blank import. Without a builtin package registered for fmt, the interpreted source has nothing to resolve its import against. The README's XGo demo follows the same pattern with the xgobuild package instead.

Where iXGo is the wrong tool

The test surface is the clearest limitation. The README has a section titled test unsupported features, and it lists exactly two entries: test -fuzz and test -cover. If your workflow depends on coverage reporting or fuzzing through the interpreter, iXGo cannot supply it. You would run those against the gc toolchain instead, which defeats the reason you reached for an interpreter.

The Go version window is the second constraint. The README states Go 1.25 through 1.27. Generic methods are marked as a Go 1.27 feature, and the tree contains typeparam_go127_test.go next to typeparam_test.go, so the generics support is version-gated rather than uniform. Code that relies on newer language changes outside that window is not covered by the stated support.

The third constraint is the builtin package model. Interpreted code does not automatically see the standard library the way compiled code does. Each package you want available must be exported, which is what the qexp tool is for. That is a real setup cost for any embedder whose interpreted code imports widely, and the README does not describe an automatic fallback for unexported packages.

Finally, the linkname mode is opt-in for a reason. The documented install disables the linkname check with -checklinkname=0 and requires the linknamefix build tag. That is a deliberate loosening of a safety check to gain speed on iter.Pull and iter.Pull2. Treat it as an advanced configuration, not the default.

How iXGo differs from Yaegi and from go run

The obvious comparison is go run. That is not an interpreter at all: it invokes the compiler and linker, so the cost is a full build, and the executed code is a real binary. go run gives you the entire standard library, the complete test tooling, and every architecture the toolchain supports. What it cannot do is evaluate source that your process receives at runtime without spawning something.

Within the interpreter category, the closest well-known project is Yaegi, the Go interpreter from Traefik. The architectural difference matters more than any feature list. Yaegi evaluates Go source directly against the reflect package, wrapping values in reflect.Value and calling methods through reflection, which is why it historically tracks the language more slowly and why generics were a long-running gap. iXGo instead compiles through SSA and interprets the resulting instruction blocks, with generated operator dispatch tables in binop_gen.go, opcvt_gen.go and the other _gen files. That design is what lets the README claim generics, generic type aliases, and generic methods rather than listing them as future work.

The second difference is XGo. iXGo is not only a Go interpreter; it also runs XGo, the language from the same organisation, and the REPL defaults to XGo syntax with a -go flag to turn it off. If you only ever want Go, that default is a small annoyance. If you want XGo, no Go-only interpreter will do it.

Maintenance, licensing, and what an upgrade costs

The repository is not archived. The last push was on 2026-08-25, and the most recent release, v1.1.6, carries the same timestamp. Two earlier releases, v1.1.5 and v1.1.4, landed on 2026-08-19 and 2026-08-11, so the release cadence in the weeks before that date was roughly weekly. That is the evidence available; the README makes no stability or support commitment.

The licence is Apache-2.0, which permits commercial and closed-source use and includes an explicit patent grant. That is the standard permissive arrangement and needs no special handling for most teams. This is not legal advice; if you redistribute a modified interpreter, read the NOTICE and attribution requirements in the licence text itself.

Upgrade cost is dominated by the Go version window. The module requires go 1.25.0, and the README supports Go 1.25 to 1.27. When your own toolchain moves past that window, you are waiting on iXGo rather than on the Go team. The go.mod also pins a long dependency list, including goplus/gogen, goplus/mod, goplus/reflectx, goplus/xgo, visualfc/funcval, visualfc/gid, visualfc/goembed and visualfc/xtype, plus golang.org/x/mod and golang.org/x/tools. Those are not incidental: reflectx and xtype are the reflection layer, and gogen is the code generator. Expect the interpreter's behaviour on reflection-heavy code to move with those libraries, not only with iXGo's own releases.

Editorial conclusion

Adopt iXGo when you need to execute Go or XGo source inside a running Go program, for a playground, a plugin surface, or a REPL, and you can live with the supported Go version window and the missing test flags. Do not adopt it as a replacement for the gc toolchain in production builds, and do not expect the full go test surface: the README lists test -fuzz and test -cover as unsupported. Before committing, verify two things yourself: that your target platform and GOARCH are covered by the ABI list in the README (amd64, arm64, ppc64/ppc64le, riscv64, loong64 for the register-based ABI), and that the packages your code imports have been exported into an iXGo builtin package, since the demo imports a side-effect package such as github.com/goplus/ixgo/pkg/fmt to make fmt available.

Frequently asked questions

Which Go versions does goplus/ixgo support?

The README states Go 1.25 through 1.27. Generic methods are marked as a Go 1.27 feature, and the repository contains a separate typeparam_go127_test.go, so generics support is version-gated rather than uniform across that range.

How do I install the ixgo command line tool?

The README gives go install github.com/goplus/ixgo/cmd/ixgo@latest. There is a second tool, github.com/goplus/ixgo/cmd/qexp, for exporting Go packages into iXGo builtin packages.

Does goplus/ixgo support go test with coverage or fuzzing?

No. The README has a section on unsupported test features and lists test -fuzz and test -cover as the two entries. Other test functionality is exposed through the ixgo test subcommand.

Which platforms and architectures can run goplus/ixgo?

The README lists macOS, Linux, Windows and WebAssembly as platforms. For the register-based ABIInternal calling convention it names amd64, arm64, ppc64/ppc64le, riscv64 and loong64; the stack-based ABI0 convention is the other supported path.

Official sources

  1. Official README
  2. Project repository
  3. Release notes
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/goplus-ixgo.svg)](https://hysenlabs.com/projects/goplus-ixgo)