Xo is experimental. The source is now public on GitHub, or try Xo in your browser.

What's new in Xo 0.34: edits build faster than go build

2026-10-29

Every number below comes from a committed results file in the xo repository, linked where it appears. The release notes list every change.

Edits build in a third of the time

The headline of 0.34: xo build and xo run compile your program separately from the standard library, on darwin and linux, arm64 and amd64, and on windows/amd64 (75468ed91, checked on the Windows CI runner, run 40819530873). std is compiled once per xo into a store and a set of facts in the backend cache; an edit compiles and links only your code.

edit, median0.33.00.34go buildsource
llvm-fib, darwin/arm64230.8 ms70.2 ms87.7 mssepcomp-edit-final-2026-10-29.md, line 7
HTTP service, darwin/arm64570.5 ms156.0 ms245.5 mssepcomp-edit-final-2026-10-29.md, line 8
llvm-fib, linux/arm64350.0 ms (whole program)196.5 mssepcomp-edit-linux-2026-10-28.md, line 7
HTTP service, linux/arm64804.0 ms (whole program)453.5 mssepcomp-edit-linux-2026-10-28.md, line 8
llvm-fib, windows/amd64295 ms (whole program)143 ms0388-separate-std-compilation.md, line 563
HTTP service, windows/amd64619 ms (whole program)280 ms0388-separate-std-compilation.md, line 563 to 564

On darwin/arm64 an edit now builds faster than go build of the same edit. The linux rows are Docker on the Mac and the windows rows an earlier measurement, both before the check’s record below was on by default.

The programs it builds run as fast as before: every release-vs-go workload is within noise or better against a whole-program build (sepcomp-runtime-2026-10-28.md, line 33 to 54), and so are the HTTP server’s throughput and CPU per request (sepcomp-runtime-2026-10-28.md, line 64 to 65). How we cut the edit loop covers how.

The check. A separately compiled build checks the program against a record of std’s declarations instead of parsing std (102 std files parsed to 9 for fib, sepcomp-edit-stage2-2026-10-28.md, line 29 to 30). At the cut, fib’s check is 17.4 ms against 0.33.0’s 30.5, the HTTP service’s 25.1 against 54.9 (sepcomp-edit-final-2026-10-29.md, line 16).

Faster starts

A separately compiled program first started 6 percent slower than a whole one (sepcomp-runtime-2026-10-28.md, line 24): dyld bound the imports of std functions the link had stripped, and each weak symbol libSystem lacks costs a lookup at every launch (sepcomp-runtime-2026-10-28.md, line 27). Binding only what kept code calls fixed it, and dropping the sanitizer imports a non-race build never uses made every program start faster: an empty program binds 53 symbols at launch, where a separately compiled one bound 123 and a whole one 64 (47b1867e2).

The runtime and the compiler

Code generation

Standard library

  • SHA-3 and SHAKE use the arm64 SHA3 instructions on Apple CPUs (a port of Go’s keccakF1600NEON): SHA3-256 of 1 MiB in 0.948 of Go’s time, from 1.66 (crypto.md, line 3). ML-KEM’s hashing takes the same path.
  • regexp compiles in 1.21 times Go’s time, from 1.68 (regexp.md, line 39).
  • compress and archive: inflate copies back-references in bulk and builds its Huffman tables in place; unzip runs at 1.04 times Go’s time (compress.md, line 9).
  • template parses in 0.948 of its time (template.md, line 3), and Fs.copy clones files on macOS (APFS clonefile, prelude.md, line 36).
  • Breaking: a uuid.Uuid is its 128 bits as two Ints instead of its text (decision 0387, deprecated in 0.33): u.0 becomes u.display(), uuid.Uuid(s) becomes uuid.parse(s)?, and the checker names the replacement.

Tooling, platforms, and the testers’ reports

  • First builds for a brand-new user: fib in 954 ms and the HTTP service in 2.62 s from empty caches, against go build’s 1482 ms and 3.05 s (first-build-2026-10-28.md, line 10 to 11, first-build-2026-10-28.md, line 18 to 19).
  • The 0.33 testers’ use go reports are fixed: a newer installed Go no longer breaks every binding (decision 0393), one Xo type stands for a Go type two bound packages share (decision 0392), == on Go values handed out by value compares by value, modules with a patch-level go line build, and on Windows use go finds xo-gobind.exe, works from PowerShell and cmd, and xo mod tidy no longer doubles C:/ paths.
  • x86-64 Linux with GNU as: a build that assembles through cc (XO_NOLIBC=0) no longer fails on arm64-only directives (f12984f7d).
  • xo bench --ab counts a round as loaded relative to the machine’s load before the run, so a busy machine no longer drops every round.

Upgrading

Nothing to do: the first build after installing 0.34 builds your program whole and std’s variants in the background; the next edit builds separately. XO_SEPCOMP_DEFAULT=0 turns separate compilation off.