# Wa: a WebAssembly language whose compiler does not borrow anyone else's backend

> Wa is a statically typed language aimed at WebAssembly, with a Chinese name that is pronounced the same way and a self-developed code generator that does not depend on LLVM or GCC. The architecture is a dual frontend, Chinese and English syntax, feeding a unified IR, with a native assembler backend that targets x64, LoongArch, RISC-V and ARM64, and it is currently in the engineering trial stage under AGPL-3.0.

**wa-lang/wa** — 凹语言, The Wa Programming Language

- Repository: https://github.com/wa-lang/wa
- Website: https://wa-lang.org
- Stars: 1,771 · Forks: 65
- Language: Go
- License: AGPL-3.0
- Published: 2026-10-16 · Updated: 2026-10-16 · Language: en
- Canonical page: https://hysenlabs.com/projects/wa-lang-wa

## A language with two spellings of the same program

Wa is described as a general-purpose programming language designed for WebAssembly, with the goal of providing a simple, reliable, easy-to-use, statically typed language for high-performance web applications.

The distinctive structural choice is the dual frontend. The architecture section says Wa is designed with a dual-frontend system supporting both Chinese and English syntax that interfaces with a unified Intermediate Representation, and the diagram spells out the shape: the English source file and the Chinese source file each produce their own AST, and both ASTs feed the same Wa-IR.

Two syntaxes for one language is not a localisation feature. The Chinese form is a different surface syntax with its own keywords and its own conventions, and the compiler parses it into the same AST shape that the English one produces. The two example programs in the README show what that means. The Chinese hello world imports a standard library module and calls a function through a namespaced name, while the English version imports fmt, declares a global, and calls a plain function.

What the design buys is a language that reads naturally in more than one community, without the compiler having to carry two backends. What it costs is that every language feature, every standard library binding and every piece of documentation has to exist in both forms, and the toolchain has to keep two parsers in step with the same semantics.

The project is written in Go, the module is wa-lang.org/wa, the homepage is wa-lang.org, and the licence of the compiler source is AGPL-3.0 while the standard library is MIT. The releases are v1.8.0 from 2026-03-02, v1.7.0 from 2026-02-16 and v1.6.0 from 2025-12-31, and the last push was on 2026-04-30.

## The compiler writes WebAssembly and native code without GCC or LLVM

The claim in the README is that the code generator and runtime are fully independently developed, not dependent on external projects such as LLVM, and the architecture section repeats it as a fully self-developed toolchain without external dependencies such as GCC or LLVM.

The diagram shows the three backends the IR feeds. From the Wa-IR there is an edge to WASM, an edge to the Wa Native Assembler, and an edge to C/C++.

The WebAssembly path is the one the language was designed for, and the README notes something that sounds like a confession about the current state of the design: the Wa-lang IR is currently being refined, and WebAssembly is presently utilized as the intermediate IR. In other words, Wasm is not only a target, it is currently standing in for the IR itself. That is a pragmatic way to get a backend early, and it also means the IR is the piece most likely to change.

The native path goes through the Wa Native Assembler, and the assembler is described as proprietary, with Chinese and English front ends feeding the same assembler. The four architectures it targets are listed in the diagram, X64, LoongArch, RISCV and ARM64.

The self-developed toolchain is a real engineering decision with a real cost. Writing your own compiler backend means you can target exactly the instructions you need and you are not bound by another project's roadmap, and you also take on the whole burden of instruction selection, register allocation, calling convention and optimisation for four architectures. It also means the project has to be trusted with correctness on every one of those targets, and the README is honest about where that trust is thinner: the RISC-V platform has not yet undergone hardware testing due to the lack of a physical environment.

The C/C++ backend is the third option, and it is the one that would make Wa useful in a native toolchain, since the project describes the design as achieving a fully self-developed toolchain with no external dependency.

## The examples are games, and the playground is the fastest way to see the language

The README dedicates more space to running programs than to the language specification, and that is a reasonable choice for a language in its engineering trial stage.

There is a playground at wa-lang.org/playground, a snake game playable in the browser with its source in the examples directory of the waroot tree, and two WASM4 games, snake and 2048, each with an English and a Chinese source tree. There is an NES emulator hosted from a separate repository, a WebGPU demo also in a separate repository, and two entries under a smalltalk path, a P5 creative coding example and an Arduino Nano 33.

Two of those are worth a second look. The WASM4 games are the strongest evidence for the language's stated purpose, since WASM4 is a fantasy console that runs WebAssembly cartridges, so a game written in Wa and running in WASM4 is a direct demonstration that the language does what it claims. The NES emulator and the WebGPU demo are hosted from separate repositories, which is a common arrangement for keeping example projects out of the compiler's own tree, and it means the compiler repository carries the w4-snake and w4-2048 examples directly while the larger demos live elsewhere.

The English hello world shows the surface syntax:

```wa
import "fmt"

global year: i32 = 2023

func main {
	println("hello, Wa!")
	println(add(40, 2), year)

	fmt.Println(1+1)
}

func add(a: i32, b: i32) => i32 {
	return a+b
}
```

A few things are visible in those fifteen lines. The type is written after the name with a colon, the numeric types are spelled i32, the function body uses braces rather than indentation, and there are two return syntaxes, a block body with an explicit return and a => form for a single expression. A global is declared with the global keyword and an explicit type. The println builtin is available unqualified while fmt.Println comes from the imported module.

Running it is a single command, wa run hello.wa, and the output shown in the README is the greeting, then 42 2023 from the add call and the global, then 2 from the fmt call.

## The licence split is deliberate, and the README explains the reasoning

The licensing note in the README is one of the more carefully worded things in the project, and it is worth reading in full because it makes a distinction that most language projects do not.

The Wa compiler source files are distributed under AGPL-v3. The Wa standard library is licensed under MIT. The programs you develop using the Wa language can be safely used commercially without open source. And if you want to integrate the Wa compiler code into your own project but do not want to be restricted by the infectiousness of AGPL-v3, you can contact the authors to customize the licence agreement.

That is a three-way structure with a clear purpose. The compiler is the part the project wants to keep open, and the AGPL is the tool for that, because it covers the case where someone ships the compiler as part of a hosted service. The standard library is separate and MIT, so ordinary programs do not inherit any obligation. The third clause is the interesting one, because it recognises that the AGPL is a barrier to some legitimate uses and offers a commercial licence instead.

The repository reflects this split in its files. There is a LICENSE and a LICENSE-mit.txt at the root, which is the physical counterpart of the compiler and standard library licences respectively.

The project is in the engineering trial stage, and the contribution section says the project is still in the prototype stage, pointing at wca/readme_en.md for co-construction or PR needs. Two conditions are attached to contributing. Pull requests to third-party libraries are no longer accepted, which is a signal that the standard library's dependencies are frozen. And submitting a pull request counts as acceptance of the Wa Contributor Agreement, with the note that pull requests will not be reviewed or accepted until the WCA is actually signed. The canonical repository is at gitcode.com/wa-lang/wa, with the GitHub repository as a mirror.

For anyone planning to build on the language, that WCA requirement is the thing to check first, because it applies before any code is written.

## The Go build is a Makefile with a dozen targets and two wasm flavours

The compiler is a Go program, and the Makefile at the repository root is the entry point for everything.

The default goal is install, and the wa target is the plain build:

```make
GOBIN = ./build/bin/wa

wa:
	go build -o $(GOBIN)
	@echo "Done building."
```

There is a hello target that installs the tool and runs hello.wa from the waroot directory, and a prime target that runs the prime example. The dev target compiles to WebAssembly text format for x64 targeting Windows, which is a quick way to look at generated output.

The two WebAssembly build targets are the interesting pair, and the difference between them is a real design decision rather than a copy and paste. wasm-js builds with GOOS=js GOARCH=wasm and drops the result into docs/wa-js with a zip alongside it, while wasm-wasip1 uses GOOS=wasip1 GOARCH=wasm and writes into docs/wa-wasip1. The js target is the browser embedding, where the wasm module is loaded by a JavaScript host, and the wasip1 target is the standard WebAssembly system interface for command line programs, which is a different execution model with a different syscall story.

The ci-test-all target is where the test strategy is visible. It runs go install, then go test ./... for the Go code itself, then a standard library test through the compiler with go run main.go test std, then the hello programs, then a recursive ci-test-all in the examples tree, then a nil check test on a specific file, and finally wa -v to print the version. The nil check test naming a single path in the waroot tests directory suggests a targeted regression suite for the failure modes that are hardest to get right.

The Docker path runs through a builder directory, with a build-docker target that runs go run ./builder and then docker build, and a docker-run target that mounts the working directory. The Dockerfile itself is a minimal Ubuntu 22.04 image with git installed and the built binary copied to /usr/local/wa.

## Where Wa is the wrong tool

The limits are stated by the project itself, and they are the ordinary limits of a language that is still being designed.

The first is the maturity statement. The README says Wa is in the engineering trial stage, and the contribution section says the project is still in the prototype stage. A language whose own documentation calls it a prototype should be evaluated as a language to watch and to learn from rather than as a language to bet a production service on. The version numbers look reassuring, v1.8.0 with three minor releases in the last few months, but a 1.x number in a project that also calls itself a prototype does not mean a stable language.

The second is the IR. The README says the Wa-lang IR is currently being refined and that WebAssembly is presently utilized as the intermediate IR. A language whose IR is expected to change is a language whose compiled output and whose tooling are both in flux, and the native assembler, which is described as proprietary and feeds four architectures, is the part most exposed to that churn.

The third is the untested target. RISC-V has not undergone hardware testing because there was no physical environment available, and RISC-V is one of the four architectures the assembler targets, alongside x64, LoongArch and ARM64. A target that has never been run on hardware is a target whose correctness you cannot assume, and the fact that the project says so is a point in its favour.

The fourth is the dual frontend's maintenance cost, which lands on the community rather than on the compiler. Every library binding, every example and every documentation page has to exist in both the Chinese and the English form, and the README's own example tree shows both, w4-snake and w4-snake-wz. Contributors are told that pull requests modifying third-party libraries are no longer accepted, which means the standard library's external dependencies are frozen, and that is a way of avoiding a maintenance burden that has already been judged too large.

The fifth is the compiler licence for anyone embedding the tool. The compiler is AGPL-3.0, and integrating the compiler code into a proprietary product means either complying with the AGPL or asking for a customised licence, which the README says you can do by contacting the authors. A team that wanted to build a product around the Wa compiler needs to start that conversation early, because the answer shapes the architecture.

The sixth is the ecosystem. The CNCF Landscape badge under WebAssembly languages places the project in a field where it is one name among many, and the documentation makes no claim of a standard library or package ecosystem of any size.

## Conclusion

Wa is worth reading for a WebAssembly developer who wants to see what a language looks like when the compiler is not a thin layer over LLVM, because the dual frontend and the hand-written assembler make the trade-offs visible, and the standard library being MIT licensed means programs written in it carry no licence obligation. It is the wrong tool for production work, since the project itself says Wa is in the engineering trial stage, and it is the wrong tool for a team that needs a compiler with a stable release cadence or a large existing ecosystem. Before trying it, read the wca/readme_en.md contribution guide, note that the canonical repository is on gitcode.com with GitHub as a mirror, and expect the RISC-V target to be untested on hardware.

## FAQ

### What is the Wa programming language?

Wa is a general-purpose statically typed language designed for WebAssembly, with the goal of a simple, reliable and easy to use language for high performance web applications. The code generator and runtime are developed independently and do not depend on projects such as LLVM.

### Does Wa support both Chinese and English syntax?

Yes. The compiler uses a dual frontend system in which the English and Chinese source files each produce their own AST, and both feed the same Wa-IR. The repository carries parallel example trees for the WASM4 games, one in English and one in Chinese.

### What licenses apply to the Wa compiler and to programs written in it?

The compiler source files are distributed under AGPL-v3 and the standard library under MIT, so programs you develop with the language can be used commercially without open source. If you want to integrate the compiler into your own project without the AGPL obligations, the README says you can contact the authors to customise the licence.

### How do I build the Wa compiler and run a program?

The Makefile has a wa target that runs go build, and a hello target that installs the tool and runs hello.wa from the waroot directory. A program is then run with wa run hello.wa, and the README shows the expected output.

### Which platforms does Wa target?

The native assembler backend targets X64, LoongArch, RISCV and ARM64, and WebAssembly is a target as well. The README notes that the RISC-V platform has not yet undergone hardware testing because of the lack of a physical environment.

## Sources

- [License: AGPL-3.0](https://github.com/wa-lang/wa/blob/master/LICENSE)
- [Project website](https://wa-lang.org)
- [README](https://github.com/wa-lang/wa/blob/master/README.md)
- [Releases](https://github.com/wa-lang/wa/releases)
- [wa-lang/wa on GitHub](https://github.com/wa-lang/wa)

---

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