Ruby implementation with yet another JIT compiler.
Rust
140
3,410 commits
updated Sep 24, 2026
Ruby implementation with yet another JIT compiler written in Rust.
master that touches the interpreter.Highlights from the last two months; earlier months are in the changelog, linked at the end of this section.
Enumerator::Lazy / Product / Chain, fiber-free #each/#with_index internals, ARGF reimplemented in Rust, Refinements, and a full spawn-exec engine with real Data subclasses (#1039β#1065, notably #1046, #1054, #1064).gc-stress then went opt-in and ran at every safepoint on both arches, catching a string of unrooted-Value and FP-pool bugs (#1070β#1075, #1123β#1125).RValue cell, JIT-inlined accessors ([]=, size, default, β¦), and correctness fixes for tombstone deletes and iteration order (#1060, #1086β#1108).Imm19 reach, and ports of the class-version recovery jump-back (#1153, #1175, #1176, #1182, #1183, #1189).Symbol#to_proc procs, dispatch-free Array/Range scans and equality-by-identity fast paths, plus a JIT correctness fix for inlined send and method_missing dispatch (#1200β#1214).defined?, flip-flops, BEGIN/END, and predefined globals (#804β#874, notably #861).case/in, =>) (#883) and MRI's full eigenclass tower (#877).IO::Buffer with mmap file mapping (#927, #931); IO.copy_stream (#924).setup-monoruby GitHub Action with prebuilt binaries (#884, #886) and CRuby-compatible command-line option processing (#891).full_message, NameError / NoMethodError metadata (#893β#896).Fiber β transfer / raise / kill / storage and a real root fiber, making core/fiber fully green (#1036) β and refined Thread semantics: the async Thread#raise protocol and structured Thread::Backtrace::Location (#1026, #1027).... forwards (#1012).Encoding::Converter state and String#encode fallback / newline decorators (#1018, #1019); Regexp gained native-encoding byte matching for non-UTF-8 subjects plus upstream Onigmo engine fixes (#1037, #1038).require / load / autoload resolution rules (#1033), a Rust fnmatch engine backing Dir.glob (#1017), and an mdBook documentation site published to the project portal (#1008).Earlier months: Changelog (from January 2026), and Progress summary (April 2025 β April 2026) for a prose account of the same period.
Conformance with Ruby has improved dramatically over the course of 2026, driven by an extensive ruby/spec-based compliance effort.
Pass rates are re-measured on every interpreter change and published on the project portal: as of commit a13bfe0 (2026-08-31) monoruby passes 97.6% of the core specs (22468 / 23029 examples) and 59.1% of the library specs.
As of July 2026 it also passed 100% of the command-line specs and 99.6% of the language specs.
Daily-updated pass statistics, compared with CRuby / TruffleRuby / JRuby, are published at rubyspec-stats.
The Compatibility chapter of the documentation breaks the numbers down by category, explains how they are measured, and lists the behaviours that differ from CRuby by design.
macos-latest) runners. Linux arm64 works as well.See Installation and Build for prebuilt binaries, platform notes, what the build installs, and the full command-line reference.
(1) Install Rust.
Check here to install Rust if you have no Rust yet.
Caution!! only nightly Rust works for monoruby. You do not have to select the channel yourself: rust-toolchain.toml pins the exact nightly the project is tested against, and rustup installs and uses it automatically the first time you run cargo in the checkout.
(2) Clone this repository.
> git clone https://github.com/sisshiki1969/monoruby.git
> cd monoruby
(3) Build and run monoruby with Ruby script file.
> cargo run --release -- test.rb
(4) or, Launch REPL.
> cargo run --bin irm
or
> bin/irm
(5) or, install monoruby and irm onto your PATH.
> bin/install # cargo install + the native extensions (psych, zlib, β¦)
> monoruby test.rb
> irm
This repository doubles as a setup-monoruby action (see action.yml),
modeled after ruby/setup-ruby. The ref
after @ selects the monoruby version to install:
steps:
- uses: sisshiki1969/monoruby@master # or a release tag
- run: monoruby my_script.rb
The action first tries to download a prebuilt binary attached to a GitHub
release (built by the release binaries workflow), which installs in seconds:
release tags use their own release's assets, while @master / @nightly use
the rolling nightly prerelease, rebuilt on every master push (so it
can lag a just-pushed HEAD by one build, ~15 min). Automatic builds cover
x86-64 Linux only; assets for Linux arm64 and macOS arm64 are published on
demand by dispatching the release binaries workflow with the wanted tag and
targets. When no asset exists for the ref/platform β or
prefer-prebuilt: 'false' is set β the action falls back to building monoruby
from source on the first run for each monoruby revision Γ runner OS/arch and
caches the resulting binary and runtime tree with actions/cache, so
subsequent runs restore in seconds. Linux (x64/arm64) and macOS (Apple
Silicon) hosted runners are supported either way.
Inputs and outputs:
| Name | Kind | Description |
|---|---|---|
prefer-prebuilt ('true') | input | Set to 'false' to skip release assets and build the exact ref |
cache ('true') | input | Set to 'false' to disable the source-build cache |
cache-version ('v1') | input | Mixed into the cache key; bump to discard existing caches |
prebuilt | output | 'true' if a prebuilt release asset was used |
cache-hit | output | 'true' if the built binary was restored from cache |
monoruby-version | output | Output of monoruby --version |
ruby-version | output | RUBY_VERSION reported by the installed monoruby |
Up-to-date benchmark results (yjit-bench, re-measured on every interpreter change) and the ruby/spec compliance dashboards are published on the project portal. On the x86-64 run of commit a13bfe0 (2026-08-31), over the 59 benchmarks that completed on both interpreters, monoruby averaged 1.28x the speed of CRuby+YJIT (geometric mean).
The Benchmarks chapter of the documentation explains the measurement methodology and how to reproduce a run locally. The numbers below are older one-off measurements, kept for the record.
Several Ruby implementations described below were measured by optcarrot benchmark. See Benchmarks β optcarrot for details.


Several Ruby implementations described below were measured by yjit-bench. See Benchmarks β yjit-bench for the raw data.
The graph shows the speed ratio against truffleruby. (higher is better)

Rust
80.7%
Ruby
18.8%
Ruby implementation with yet another JIT compiler.
Rust
140
3,410 commits
updated Sep 24, 2026
Ruby implementation with yet another JIT compiler written in Rust.
master that touches the interpreter.Highlights from the last two months; earlier months are in the changelog, linked at the end of this section.
Enumerator::Lazy / Product / Chain, fiber-free #each/#with_index internals, ARGF reimplemented in Rust, Refinements, and a full spawn-exec engine with real Data subclasses (#1039β#1065, notably #1046, #1054, #1064).gc-stress then went opt-in and ran at every safepoint on both arches, catching a string of unrooted-Value and FP-pool bugs (#1070β#1075, #1123β#1125).RValue cell, JIT-inlined accessors ([]=, size, default, β¦), and correctness fixes for tombstone deletes and iteration order (#1060, #1086β#1108).Imm19 reach, and ports of the class-version recovery jump-back (#1153, #1175, #1176, #1182, #1183, #1189).Symbol#to_proc procs, dispatch-free Array/Range scans and equality-by-identity fast paths, plus a JIT correctness fix for inlined send and method_missing dispatch (#1200β#1214).defined?, flip-flops, BEGIN/END, and predefined globals (#804β#874, notably #861).case/in, =>) (#883) and MRI's full eigenclass tower (#877).IO::Buffer with mmap file mapping (#927, #931); IO.copy_stream (#924).setup-monoruby GitHub Action with prebuilt binaries (#884, #886) and CRuby-compatible command-line option processing (#891).full_message, NameError / NoMethodError metadata (#893β#896).Fiber β transfer / raise / kill / storage and a real root fiber, making core/fiber fully green (#1036) β and refined Thread semantics: the async Thread#raise protocol and structured Thread::Backtrace::Location (#1026, #1027).... forwards (#1012).Encoding::Converter state and String#encode fallback / newline decorators (#1018, #1019); Regexp gained native-encoding byte matching for non-UTF-8 subjects plus upstream Onigmo engine fixes (#1037, #1038).require / load / autoload resolution rules (#1033), a Rust fnmatch engine backing Dir.glob (#1017), and an mdBook documentation site published to the project portal (#1008).Earlier months: Changelog (from January 2026), and Progress summary (April 2025 β April 2026) for a prose account of the same period.
Conformance with Ruby has improved dramatically over the course of 2026, driven by an extensive ruby/spec-based compliance effort.
Pass rates are re-measured on every interpreter change and published on the project portal: as of commit a13bfe0 (2026-08-31) monoruby passes 97.6% of the core specs (22468 / 23029 examples) and 59.1% of the library specs.
As of July 2026 it also passed 100% of the command-line specs and 99.6% of the language specs.
Daily-updated pass statistics, compared with CRuby / TruffleRuby / JRuby, are published at rubyspec-stats.
The Compatibility chapter of the documentation breaks the numbers down by category, explains how they are measured, and lists the behaviours that differ from CRuby by design.
macos-latest) runners. Linux arm64 works as well.See Installation and Build for prebuilt binaries, platform notes, what the build installs, and the full command-line reference.
(1) Install Rust.
Check here to install Rust if you have no Rust yet.
Caution!! only nightly Rust works for monoruby. You do not have to select the channel yourself: rust-toolchain.toml pins the exact nightly the project is tested against, and rustup installs and uses it automatically the first time you run cargo in the checkout.
(2) Clone this repository.
> git clone https://github.com/sisshiki1969/monoruby.git
> cd monoruby
(3) Build and run monoruby with Ruby script file.
> cargo run --release -- test.rb
(4) or, Launch REPL.
> cargo run --bin irm
or
> bin/irm
(5) or, install monoruby and irm onto your PATH.
> bin/install # cargo install + the native extensions (psych, zlib, β¦)
> monoruby test.rb
> irm
This repository doubles as a setup-monoruby action (see action.yml),
modeled after ruby/setup-ruby. The ref
after @ selects the monoruby version to install:
steps:
- uses: sisshiki1969/monoruby@master # or a release tag
- run: monoruby my_script.rb
The action first tries to download a prebuilt binary attached to a GitHub
release (built by the release binaries workflow), which installs in seconds:
release tags use their own release's assets, while @master / @nightly use
the rolling nightly prerelease, rebuilt on every master push (so it
can lag a just-pushed HEAD by one build, ~15 min). Automatic builds cover
x86-64 Linux only; assets for Linux arm64 and macOS arm64 are published on
demand by dispatching the release binaries workflow with the wanted tag and
targets. When no asset exists for the ref/platform β or
prefer-prebuilt: 'false' is set β the action falls back to building monoruby
from source on the first run for each monoruby revision Γ runner OS/arch and
caches the resulting binary and runtime tree with actions/cache, so
subsequent runs restore in seconds. Linux (x64/arm64) and macOS (Apple
Silicon) hosted runners are supported either way.
Inputs and outputs:
| Name | Kind | Description |
|---|---|---|
prefer-prebuilt ('true') | input | Set to 'false' to skip release assets and build the exact ref |
cache ('true') | input | Set to 'false' to disable the source-build cache |
cache-version ('v1') | input | Mixed into the cache key; bump to discard existing caches |
prebuilt | output | 'true' if a prebuilt release asset was used |
cache-hit | output | 'true' if the built binary was restored from cache |
monoruby-version | output | Output of monoruby --version |
ruby-version | output | RUBY_VERSION reported by the installed monoruby |
Up-to-date benchmark results (yjit-bench, re-measured on every interpreter change) and the ruby/spec compliance dashboards are published on the project portal. On the x86-64 run of commit a13bfe0 (2026-08-31), over the 59 benchmarks that completed on both interpreters, monoruby averaged 1.28x the speed of CRuby+YJIT (geometric mean).
The Benchmarks chapter of the documentation explains the measurement methodology and how to reproduce a run locally. The numbers below are older one-off measurements, kept for the record.
Several Ruby implementations described below were measured by optcarrot benchmark. See Benchmarks β optcarrot for details.


Several Ruby implementations described below were measured by yjit-bench. See Benchmarks β yjit-bench for the raw data.
The graph shows the speed ratio against truffleruby. (higher is better)

Rust
80.7%
Ruby
18.8%