Zeo compiles a whole Ruby program to native code. It reads the source with
Prism, analyzes the entire program at once, lowers it to Cranelift IR,
and links libzeo.a — Zeo's own Ruby runtime, written in Rust and compiled
ahead of time: the object model, the core classes, the dispatcher, threads,
fibers, and the reference-counted heap. There is no interpreter to boot and
no JIT to warm up. The machine that runs the binary needs no Ruby.
$ cat hello.rb
puts [1, 2, 3].map { |x| x * 2 }.sum
$ zeo hello.rb # runs it, like `ruby hello.rb`
12
$ zeo -o hello hello.rb # or write a native binary
$ ./hello
12Every test compares Zeo's output with real Ruby 4.0.6, byte for byte.
Experimental, and moving fast. Read Limitations before depending on it.
The corpus (test/) runs green, each program compared with real Ruby
on stdout, stderr and the exit status. Every module, method, constant and
visibility that Ruby 4.0.6 reaches has a Zeo answer, so what remains is
behavioural, not missing surface.
Every known difference is recorded: in
Compatibility when a user can see it, in
test/divergences/ when it is deliberate, and in
test/gaps/ when it is not fixed yet.
The first release is not cut yet, so today the way in is a build from
source (below). The release will ship three ways: cargo install zeo,
gem install zeo (a per-platform gem that carries the binary), and a
relocatable tarball:
$ tar xzf zeo-<version>-<triple>.tar.gz -C /usr/localBuilding a binary needs a linker (cc) on the machine, the same requirement
any native toolchain has.
$ git clone https://github.com/ryanseys/zeo && cd zeo
$ cargo xtask deps # Gemfile.lock -> vendor/, no ruby needed
$ cargo build
$ cargo nextest runRuby is needed for one thing only: recording a test's answer. Getting started walks the whole loop.
docs/ is the map. The pages people reach for first:
- Getting started — clone to first test
- CLI reference — every verb and flag
- Architecture — what happens between
hello.rbandhello - Compatibility — library by library
- Performance — measured, with the method beside it
Issues and pull requests are welcome. A bug report is most useful as the
smallest .rb that shows it, what ruby printed, what zeo printed, and
zeo --version; the issue template asks for exactly that. The one rule
that matters: keep every difference from Ruby visible.
- Check each new behaviour against real Ruby.
- Leave a comment at the site of any difference you accept.
- If a user can observe it, add a row to
Compatibility and a note under
test/gaps/.
CONTRIBUTING.md has the conventions.
MIT (LICENSE-MIT) or Apache 2.0 (LICENSE-APACHE), at your option.