# ixgo: a Go interpreter where the fastest path needs a patched compiler

> A tree-walking interpreter for the whole Go language, generics included, that runs on four platforms including WebAssembly. The interesting part is the optional acceleration: it works by tagging values in the runtime's interface table, which needs a patched standard library, and an unpatched compiler accepts the build tag anyway and then traps on interface method calls.

**goplus/ixgo** — The Go/XGo Interpreter

- Repository: https://github.com/goplus/ixgo
- Stars: 142 · Forks: 21
- Language: Go
- License: Apache-2.0
- Published: 2026-08-21 · Updated: 2026-08-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/goplus-ixgo

## Two ABIs, six architectures, and a register convention still in proposal

The compatibility table is more informative than the headline claim.

Go versions 1.25 through 1.27 are supported. Two compilers are named: the standard gc toolchain, and LLGo. Four platforms are listed, macOS, Linux, Windows and WebAssembly.

The ABI section is the part that shows what kind of work this is. The interpreter targets the stack-based ABI0, and also targets ABIInternal, which is described as a register-based Go calling convention proposal rather than as a shipped feature. Under that second entry sit six architectures: amd64, arm64, ppc64 and its little-endian variant, riscv64 and loong64.

Those are the architectures where a register-based calling convention has been prototyped, and the interpreter handles both conventions because a program compiled with one cannot be called correctly by a runtime expecting the other. The LoongArch and PowerPC entries are the ones that tell you this is not a project that only targets the two architectures most laptops have.

On the language side, the claim is that all Go language features work, including type parameters, generic type aliases, and generic methods. The generic methods entry carries a version marker, so the last of the three is tied to the newest supported toolchain rather than to all of them.

## The optional tag makes interface calls trap on a stock compiler

This is the sharpest edge in the project and it is documented in detail, which is more than most projects manage.

The feature is an alternative to the interface-call stubs provided by the reflection helper. The mechanism is described at the level of runtime internals. Methods share a single function stub. The helper stores an untagged pointer in a slot and sets a flag bit in a type flag word. A patched runtime tags the function pointer in the interface table with a low bit set, so an interface call unwraps that pointer instead of calling the stub.

The cost is that you need a patched Go toolchain, one of the 1.25, 1.26 or 1.27 lines, rebuilt from source, and you need the build tag enabled. Four architectures are supported: wasm, arm64, amd64 and 386.

The failure mode is the reason this section is worth reading twice. A patched compiler with the tag turned off behaves exactly like the official one. An unpatched compiler still accepts the tag, and then interface method calls trap. Nothing rejects the build. The configuration is accepted, the program compiles, and the crash arrives at the first interface method call.

The tag can be set globally through the build flags environment variable, or prefixed onto a single command, which is the safer form when you are experimenting.

## Go and XGo in the same REPL, with a switch to turn XGo off

The project name is the Go and XGo interpreter, and the distinction shows up in how you run it.

With no arguments you get a read-eval-print loop that accepts both languages. The repl subcommand does the same explicitly, and a flag on it disables the XGo syntax so the session accepts only Go.

That flag is the one to know about if you are evaluating untrusted source. XGo adds syntax that Go does not have, so a REPL configured for both will accept a program that is not valid Go, and code coming from a source that claims to be Go will parse under one configuration and not the other.

The other subcommands cover the expected ground:

```
ixgo             # ixgo repl mode
ixgo run         # run a Go/XGo package
ixgo build       # compile a Go/XGo package
ixgo test        # test a package
ixgo version     # print version
ixgo export      # export Go package to ixgo builtin package
```

The export command is installed as a separate binary, so exporting a package is a build step you run deliberately rather than something the interpreter does implicitly.

The run mode exposes a small set of flags. Garbage collection support is available and marked experimental. Module download mode is selectable. There are switches to print the static SSA form, to trace the execution of that form by the interpreter, to pass build tags, and the two familiar verbose flags for printing package names and commands.

## Fuzzing and coverage are the two things it will not do

There is a short section titled unsupported test features, and it lists exactly two: fuzzing and coverage.

That is a narrower gap than it sounds for an interpreter, because coverage in particular is the thing you would want from a tool that runs code rather than compiling it, and an interpreter is in principle the easiest possible place to instrument. So the omission is a real limitation rather than an inherent one.

What it does support is running a package's ordinary tests, and the tree shows a dedicated test directory alongside test data and a set of focused test files at the root. Several of those test files are named after the feature they cover rather than the package, including files for direct calls, race conditions, tuples, typed callbacks, embedded files, aliasing, and field address caching. The presence of a race test is worth noting for an interpreter, since interpreter bugs frequently show up as data races on the host.

The build layout also tells you how much of this is version- and compiler-specific. Several root files carry a suffix for the toolchain they apply to, and there are pairs for the two compilers: a runtime function file for the standard toolchain and a separate one for LLGo, and a test file for the newest type parameter support alongside a general one.

## A linkname build that switches off a compiler safety check

There is a second optional build, and it trades a safety check for speed.

The tag is enabled at install time together with a linker flag that turns off a check on the use of the runtime internals linkage mechanism. With it on, the interpreter uses the runtime linkage directly, which the documentation gives as a way to get faster performance on two specific iterator functions.

That is worth pausing on. The check exists because a language which reaches into another package's internals is a language whose internals can change under you, and a project built on that assumption is coupled to the toolchain version in a way most projects are not. Turning the check off is a deliberate acceptance of that coupling in exchange for two functions.

So there are two optional builds with two different characters. One needs a patched toolchain and a build tag, and gets a faster interface call path. The other needs no patch but disables a compiler check, and gets a faster iterator path. Neither is the default, which is the right call for both.

The rest of the installation is a single command per binary, and the module targets Go 1.25 with a small set of dependencies from the same organisation plus the standard tooling modules. The licence is Apache-2.0, and the project is published as tagged releases rather than only as a moving branch.

## Conclusion

ixgo fits someone who needs to evaluate Go code at runtime rather than compile it, such as a REPL, a playground, or a tool that has to run code it did not build, and it is the option described here for that on the supported platforms. Leave it if you need fuzzing or coverage from the test command, since both are listed as unsupported, and leave it if you cannot rebuild the standard library. Verify first whether the optional tag is set in your environment, because a patched compiler with the tag disabled matches the official compiler exactly, and a stock compiler with the tag enabled still builds and then traps on interface calls.

## FAQ

### What is the ixgo interpreter and what does it support?

A fast interpreter for Go and XGo that supports all Go language features, including type parameters, generic type aliases and generic methods. It runs on macOS, Linux, Windows and WebAssembly, against the standard Go compiler or LLGo.

### How do I install the ixgo command?

Run go install github.com/goplus/ixgo/cmd/ixgo@latest for the interpreter itself. A second command, the export tool, is installed separately with go install github.com/goplus/ixgo/cmd/qexp@latest, and is used to export a Go package into the interpreter's builtin package.

### Which Go versions and architectures does ixgo support?

Go 1.25 through 1.27. For the register-based internal ABI it covers amd64, arm64, ppc64 and ppc64le, riscv64 and loong64, in addition to the stack-based ABI.

### What happens if I enable the goplus.ifacefuncval build tag on a stock Go compiler?

The build succeeds and interface method calls then trap. The tag is only meaningful with a patched toolchain, where a patched compiler with the tag disabled matches the official compiler exactly. Rebuild the standard library with the patch tool first.

### Does ixgo support fuzzing or code coverage?

No. Fuzzing and coverage are the two features listed as unsupported in the test command. Ordinary package tests do run, and the repository includes dedicated tests for direct calls, race conditions, tuples and typed callbacks.

### Can I run ixgo in a browser?

WebAssembly is a listed platform. There is a playground and a separate REPL playground, both running as WebAssembly builds, and the optional interface-call build tag supports the wasm architecture among others.

## Sources

- [Official README](https://github.com/goplus/ixgo#readme)
- [Project repository](https://github.com/goplus/ixgo)
- [Release notes](https://github.com/goplus/ixgo/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/goplus-ixgo
