Fork me on GitHub

A Ruby you can embed,
written in Go.

go-embedded-ruby (rbgo) is a from-scratch Ruby — lexer, parser, compiler, bytecode VM and an AOT backend — that embeds in any Go program and cross-compiles to a single CGO-free binary. Built in the open as a digital common (commun numérique), free to use, study, modify and share under the BSD-3-Clause licence.

23,511 ruby/spec language/+core/ examples passing~100% of real Ruby parsed6 64-bit arches
rbgo — zsh
# a real Ruby, no cgo, no Ruby installed
$ rbgo -e 'puts (1..20).reduce(:*)'
2432902008176640000

# AOT-compile the hot path and drop the front-end
$ rbgo build --closed app.rb -o app
rbgo build: app (1 method(s) AOT-compiled: Object#fib)
rbgo build: closed-world — front-end dropped
rbgo build: binary size 172.5 MiB

# the real Puppet CLI, end to end
$ rbgo run puppet_apply.rb
Notice: Compiled catalog for  in environment production in 0.00 seconds
Notice: hi from rbgo cli
Notice: /Stage[main]/Main/Notify[hello]/message: defined 'message'
The go-ruby-* family — all CI-green, 100% coverage, 6-arch. 178 modules across 176 orgs are bound into rbgo today; a selection:
Why rbgo

Everything a Ruby runtime gives you — as a Go library.

No FFI, no libruby, no system Ruby. Drop a genuine, monkey-patchable Ruby object model into your Go binary and ship it anywhere.

🧩

Embeddable

A real object model — classes, mixins, method_missing, metaprogramming, Fiber. The Go API is deliberately small today: ruby.Run(src, out) runs a program on a fresh VM and writes its output to one writer. Calling a Ruby method from Go is not exposed yet.

📦

One static binary

CGO=0 by default. Cross-compiles to amd64, arm64, riscv64, loong64, ppc64le and s390x.

⚡

AOT for integer kernels

Ahead-of-time compilation of integer-bound methods to unboxed Go. Measured on this project’s own micro-benchmarks (darwin/arm64, whole-process wall time): 8.7× MRI+YJIT on the tight-loop case, 2.0× on recursive fib(35). Only methods the compiler can lower benefit.

✅

Conformance, measured

23,511 ruby/spec language/ + core/ examples pass, gated in CI file by file: no spec file may pass fewer examples than its recorded row, so a regression is named rather than absorbed in a total. Only language/ and core/ are swept: library/, optional/ and security/ are not run, so this is not a percentage of Ruby. Front-end: ~100% of valid Ruby parsed across Rails + Puppet (2026-06).

🔒

Closed-world builds

rbgo build --closed bakes the program to bytecode and drops the front-end for a smaller binary.

🌿

A real ecosystem

Built from the go-ruby-* family — each a 100%-coverage, 6-arch stdlib module, bound natively.

8.7×
rbgo+AOT vs MRI+YJIT, tight-loop benchmark (2.0× on fib(35))
23,511
ruby/spec language/+core/ examples passing · gated per file, not by a total
178
go-ruby-* modules bound into rbgo
CGO=0
across 6 arches · 3 OSes
The road

Lexer to AOT, in nine phases.

Phase 0 — Vertical slice

ready

Lexer → parser → compiler → bytecode VM, end to end.

Phase 1 — Object model & dispatch

ready

Classes, modules, inheritance, mutable method tables, @ivars, new/initialize, constants, include mixins, super, blocks & yield, block_given…

Phase 2 — Core types & mixins

ready

Integer (with Bignum promotion + arbitrary-precision literals, radix literals 0x/0o/0b/0d, bitwise/shift << >> & | ^ ~), Float, mutable …

Phase 3 — Control flow & Fiber

ready

Exception hierarchy, raise/rescue/ensure/else/retry (block- and method-level), non-local break/next, Kernel#loop, and the eager Enumerator…

Phase 4 — Metaprogramming

ready

define_method, instance_eval/instance_exec, class_eval/module_eval/class_exec, send/public_send, respond_to?, instance_variable_get/set/…

Phase 5 — Full front-end

ready

Interpolation, keyword args, endless methods (def foo = expr), beginless/endless ranges, the stabby lambda, multiple assignment, full …

Phase 6 — Standard library

active

Regexp bridge landed: /re/imx literals, Regexp/MatchData, =~/match/scan/gsub/sub/split and the match globals, on the pure-Go Onigmo engine (…

Phase 7 — Build toolchain

ready

rbgo build landed: AOT method compilation to native Go (unboxed int64 kernels beat MRI+YJIT ~4×), and closed-world builds (rbgo build --…

Phase 8 — Conformance & performance

active

Since July the work has been runtime conformance, measured against [ruby/spec](https://github.

Ruby that ships like Go.

One binary. Six architectures. No cgo, no runtime to install. Embed a real Ruby — or compile it away. Open infrastructure, governed as a commons.

Read the source on GitHub →