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

Xo 0.33 release notes

released 2026-10-27 · tag v0.33.0 · all releases

Downloads: Xo 0.33.0 on GitHub, with archives for macOS (Apple silicon and Intel, signed and notarized), Linux (arm64 and x86-64), and Windows (x86-64, Authenticode signed), and a SHA256SUMS file.

This release makes rebuilding after an edit faster, brings the amd64 targets (Intel Macs, Linux and Windows on x86) to the arm64 targets’ edit speed, and brings AES-GCM and ChaCha20-Poly1305 on x86 to within about 1.3x of Go. Two small language changes: a newtype may derive Ord, and xo build skips inline test blocks.

Faster edit rebuilds

A one-function body edit with a warm cache, darwin/arm64, against 0.32.0 (20 interleaved runs):

Program0.32.00.33.0
a small program (fib)333.5 ms244.5 ms27% faster
the HTTP CRUD server767.0 ms574.5 ms25% faster
  • std/testing is loaded only when the program has test blocks; a program that imports nothing now checks about half as many std files.
  • The network runtime is built only into programs that use the network.
  • Cache keys are chained from the front end’s entries (decision 0382), so an unchanged function skips more of the middle passes.
  • The link’s cache key is computed from the objects’ cache keys, and the runtime’s hash is computed once.
  • xo build and xo run skip inline test blocks (decision 0389), as they already skip _test.xo files; xo check and xo test still check them.

amd64: Intel Macs, Linux and Windows on x86

  • The per-function and per-part back-end cache now works on darwin/amd64, linux/amd64 and windows/amd64. An amd64 edit rebuild is within 15% of arm64’s on the same machine; an HTTP server edit on darwin/amd64 went from about 1.2 s to 0.64 s.
  • The first edit after a cold build reuses cached parts (before, it reused none).
  • Windows: compiled objects are cached and assembled in parallel. A native Windows HTTP server edit went from about 2.8 s to about 1.2 s. An edit built through the cache is byte for byte the same as a build with the cache off, checked on a native Windows Server host.

Crypto on x86

  • AES-GCM processes eight blocks per round with AES-NI and PCLMULQDQ, after Go’s design.
  • ChaCha20-Poly1305 has fused AVX2 and SSE kernels, with ChaCha20 and Poly1305 in one loop.
  • Every SIMD path checks the CPU at run time and falls back to portable code; x86-64’s baseline is SSE2.
  • Against Go 1.26.1 on an Intel Xeon Platinum 8488C (Xo time / Go time): AES-GCM seal and open 1.19 to 1.29, ChaCha20-Poly1305 seal 1.24 and open 1.27 (2.0 without AVX2), ChaCha20 alone 0.66.
  • A differential test of 188 cases against Go, anchored to RFC 8439’s vectors, passes on the AVX2, SSE and portable paths.

Memory

  • The allocator’s central free lists have one lock per size class (decision 0383): building the compiler itself peaks 0.75 GB lower, at no cost in time.

Standard library against Go

Xo time / Go time, before and after:

  • big: exp 12.75 to 0.92, mul 3.00 to 1.29, long division 1.95 to 1.42
  • template render 2.92 to 1.86
  • toml decode 2.23 to about 1.58
  • mime detect 1.22 to 0.89; path clean 1.15 to 1.02
  • flate and gzip 1.43 to 1.94, now 1.22 to 1.57
  • uuid bytes 7.14 to 4.24
  • New Go comparisons for compress, template, mail, archive, big, xml, toml and websocket.

Language and std

  • A newtype may derive Ord (decision 0390): type Id struct(Str) derive Ord orders by the underlying value. min, max and clamp now work on every derived-Ord type in native builds.
  • uuid.Uuid derives Ord (u < v, sorting). Reading u.0 or building a Uuid by hand outside std/uuid is deprecated: xo vet warns XO0912 and names display(), parse and < (decision 0387). The representation changes in a later release.

Xo against Go

The released darwin/arm64 archive against Go 1.26.1, the same programs written in each (bench/perf’s Go twins), 10 interleaved rounds per workload under xo bench --ab (bench/results/release-vs-go-v0.33.0.md):

  • Xo is faster on 17 of the 20 workloads and slower on 3: two-task ping-pong 1.20, parallel map 1.09 and n-body 1.05 (from 1.42 in 0.32.0). Fib, sieve and rwmutex moved from within noise to faster.
  • Xo’s peak memory is lower on all 20 (0.38 to 0.97 of Go’s).
  • Binaries are 1.60 to 1.71 MB against Go’s 2.39 to 2.43 MB.
  • A one-function edit rebuild is 0.21 to 0.23 s against Go’s 0.10 to 0.11 s; separate compilation of the standard library (decision 0388) is the next release’s work on that gap.

Fixes

  • Dead-code removal no longer keeps a function alive just because a safety-range marker sits in front of it (the compiler’s own binary shrank by 721 KB).