Ruby Rules for Bazel

June 3, 2026 ยท View on GitHub

Overview

This repository hosts Ruby language ruleset for Bazel.

The ruleset is known to work with:

  • Bazel 8 using WORKSPACE and Bzlmod (tested on CI).
  • Bazel 7 using WORKSPACE and Bzlmod (no longer tested on CI).

Getting Started

Starter repo

The fastest way to try this in an empty project is to click the green "Use this template" button on https://github.com/bazel-starters/ruby.

WORKSPACE

  1. Install the ruleset following WORKSPACE instructions on the latest release.
  2. Download and install Ruby:
# WORKSPACE
load("@rules_ruby//ruby:deps.bzl", "rb_register_toolchains")

rb_register_toolchains(
    version = "3.3.9",
    # alternatively, load version from .ruby-version file
    # version_file = "//:.ruby-version",
)
  1. (Optional) Download and install Bundler dependencies:
# WORKSPACE
load("@rules_ruby//ruby:deps.bzl", "rb_bundle_fetch")

rb_bundle_fetch(
    name = "bundle",
    gemfile = "//:Gemfile",
    gemfile_lock = "//:Gemfile.lock",
)
  1. Start defining your library, binary and test targets in BUILD files.

Bzlmod

  1. Install ruleset following Bzlmod instructions on the latest release.
  2. Download and install Ruby:
# MODULE.bazel
ruby = use_extension("@rules_ruby//ruby:extensions.bzl", "ruby")
ruby.toolchain(
    name = "ruby",
    version = "3.0.6",
    # alternatively, load version from .ruby-version file
    # version_file = "//:.ruby-version",
)
use_repo(ruby, "ruby")
  1. (Optional) Download and install Bundler dependencies:
# MODULE.bazel
ruby.bundle_fetch(
    name = "bundle",
    gemfile = "//:Gemfile",
    gemfile_lock = "//:Gemfile.lock",
)
use_repo(ruby, "bundle", "ruby_toolchains")
  1. Register Ruby toolchains:
# MODULE.bazel
register_toolchains("@ruby_toolchains//:all")
  1. Start defining your library, binary and test targets in BUILD files.

Documentation

  • See repository rules for the documentation of WORKSPACE rules.
  • See rules for the documentation of BUILD rules.
  • See rails for the documentation of Ruby on Rails rules.

Examples

See examples directory for a comprehensive set of examples how to use the ruleset.

Toolchains

The following toolchains are known to work and tested on CI.

RubyLinuxmacOSWindows
MRI 4.0๐ŸŸฉ๐ŸŸฉ๐ŸŸฉ
MRI 3.4๐ŸŸฉ๐ŸŸฉ๐ŸŸฉ
MRI 3.3๐ŸŸฉ๐ŸŸฉ๐ŸŸฉ
MRI 3.2๐ŸŸฉ๐ŸŸฉ๐ŸŸฉ
JRuby 10.1๐ŸŸฉ๐ŸŸฉ๐ŸŸฉ
TruffleRuby 34.0๐ŸŸฉ๐ŸŸฉ๐ŸŸฅ

The following toolchains were previously known to work but no longer tested on CI.

RubyLinuxmacOSWindows
MRI 3.1๐ŸŸฉ๐ŸŸฉ๐ŸŸฉ
MRI 3.0๐ŸŸฉ๐ŸŸฉ๐ŸŸฉ
MRI 2.7๐ŸŸฉ๐ŸŸฉ๐ŸŸฉ
JRuby 10.0๐ŸŸฉ๐ŸŸฉ๐ŸŸฉ
JRuby 9.4๐ŸŸฉ๐ŸŸฉ๐ŸŸฉ
JRuby 9.3๐ŸŸฉ๐ŸŸฉ๐ŸŸฉ
TruffleRuby 33.0๐ŸŸฉ๐ŸŸฉ๐ŸŸฅ
TruffleRuby 25.0๐ŸŸฉ๐ŸŸฉ๐ŸŸฅ
TruffleRuby 24.0๐ŸŸฉ๐ŸŸฉ๐ŸŸฅ
TruffleRuby 23.0๐ŸŸฉ๐ŸŸฉ๐ŸŸฅ
TruffleRuby 22.0๐ŸŸฉ๐ŸŸฉ๐ŸŸฅ

MRI

On Linux and macOS, ruby-build is used to install MRI from sources. Keep in mind, that it takes some time for compilation to complete.

On Windows, RubyInstaller is used to install MRI.

Fast Installation with Portable Ruby

For faster MRI installation on Linux and macOS, you can use portable Ruby binaries from bazel-contrib/portable-ruby instead of compiling from source. This significantly reduces installation time and ensures consistent, portable Ruby environments.

To enable portable Ruby, set portable_ruby = True in your toolchain declaration:

ruby = use_extension("@rules_ruby//ruby:extensions.bzl", "ruby")
ruby.toolchain(
    name = "ruby",
    portable_ruby = True,
    version_file = "//:.ruby-version",
)

This ruleset ships with default checksums to securely download and properly cache the Ruby binaries. If you want to use Ruby version not available with ruleset release, you should use portable_ruby_release_suffix and portable_ruby_checksums attribute.

We have provided the generate_portable_ruby_checksums utility to add/update these attributes for you. The utility needs to know the version of Ruby to download. By default, it will use the Ruby version specified in the .ruby-version file.

bazel run @rules_ruby//tools/generate_portable_ruby_checksums -- 3.4.8

After running the utility, the toolchain declaration in your MODULE.bazel should look something like the following:

ruby = use_extension("@rules_ruby//ruby:extensions.bzl", "ruby")
ruby.toolchain(
    name = "ruby",
    version_file = "//:.ruby-version",
    portable_ruby = True,
    portable_ruby_release_suffix = "2",  # default is 1
    portable_ruby_checksums = {
        "ruby-3.2.8.arm64_darwin.tar.gz": "4b5343a5513523409b4cc1b285ebaeb75356c758080e45d99f506a827492a8fb",
        "ruby-3.4.8.arm64_linux.tar.gz": "8348296d8148acbc6e5a170861810b693fb6ea72e1d59cc7b82f0369bffa9870",
        "ruby-3.2.8.x86_64_darwin.tar.gz": "75b72e64e42bb36a80e3382751c74bfe379efcf28880ed3c4c86657cac9d8462",
        "ruby-3.2.8.x86_64_linux.tar.gz": "2a2f40774634abed8eb32b762b8f440f85c6add74b5c14f28e70b42f49537464",
    },
)

Notes:

  • Portable Ruby is only supported on Linux (arm64, x86_64) and macOS (arm64, x86_64).
  • Setting portable_ruby = True has no effect on JRuby, TruffleRuby, or Windows.
  • On Windows, the toolchain automatically falls back to RubyInstaller.
  • Find available portable Ruby releases at https://github.com/bazel-contrib/portable-ruby/releases
  • Portable Ruby toolchains are multi-platform and can be used on for Remote Build Execution.

JRuby

On all operating systems, JRuby is downloaded manually. It uses Bazel runtime Java toolchain as JDK. JRuby toolchain is cross-platform and fully supports Remote Build Execution.

TruffleRuby

On Linux and macOS, ruby-build is used to install TruffleRuby. Windows is not supported.

Other

On Linux and macOS, you can potentially use any Ruby distribution that is supported by ruby-build. However, some are known not to work or work only partially (e.g. mRuby has no bundler support).

Known Issues

Code Coverage

Ruby rules support Bazel's native coverage collection using SimpleCov and simplecov-lcov.

Note

Code coverage is currently not supported on Windows.

To enable coverage:

  1. Add simplecov and simplecov-lcov gems to your Gemfile.
  2. Run your tests with the coverage command:
bazel coverage //...

The rules automatically configure SimpleCov to use the LCOV formatter and output reports to the location expected by Bazel. Coverage reports will have workspace-relative paths, allowing Bazel to aggregate results from multiple targets.

For JRuby, coverage requires --debug mode, which is automatically enabled by the rules when coverage is requested.

You can add additional coverage filters using coverage_filters attribute in rb_test or rb_binary:

rb_test(
    name = "my_test",
    ...
    coverage_filters = ["/vendor/", "/custom/"],
)