CLI tool
phusion/traveling-ruby avatar
phusion/traveling-ruby

Traveling Ruby: one archive per platform instead of nine OS packages

Self-contained Ruby binaries that can run on any Linux distribution and any macOS machine.

2,139 stars114 forksShellMIT

At a glance

What is it?
Traveling Ruby bundles a precompiled Ruby interpreter and an app's gems into a single tarball or zip, so end users install nothing. It cannot build on Windows, and native extension gems are limited to a whitelist on Linux and macOS.
Who is it for?
Traveling Ruby fits teams that hand a Ruby tool to operators who will never install Ruby: one archive per platform removes the nine-package matrix and the VM fleet that used to build it. Before adopting it, read RUBY_VERSIONS.txt and check the bundled Ruby against what your app needs, because that pin cannot be bumped without rebuilding every archive you ship.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 81 days ago.
What is it written in?
Mainly Shell, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Why one Ruby script becomes nine OS packages

Traveling Ruby exists because a working Ruby program still needs a Ruby underneath it. The project targets sysadmin automation scripts, developer command line tools and anything else destined for people who do not already maintain a Ruby installation. Hand such a script to a colleague and two things can go wrong before it runs: the machine has no Ruby at all, or it has the wrong Ruby version. Adding RubyGems on top of that opens its own failure modes, and the project groups them under a single anchor, end_user_problems.

The conventional fix is an OS-specific installation package, built as a DEB, an RPM or a .pkg. The project counts that cost exactly: support for about 2 versions of CentOS/RHEL, 2 of Debian, 3 of Ubuntu and 2 recent macOS releases means `2 + 2 + 3 + 2 = 9` packages to build, test and sign. Worse, each artifact can only be produced on its own operating system. You build Ubuntu 18.04 DEBs on Ubuntu 18.04, not from a macOS laptop, so the build estate has to mirror the support matrix you just declared.

One archive per platform replaces the VM fleet

The alternative the project advocates is to stop making OS packages. You build a single self-contained tar.gz or zip that already contains a precompiled Ruby interpreter for a specific platform plus every gem the application depends on. Three artifacts cover the supported surface: Linux x86_64, macOS, and Windows.

That choice inverts the build requirement. A tar.gz or zip can be produced from any operating system with small, ordinary tools, so one laptop emits packages for machines it has never booted, and none of them need Ruby installed first.

The comparison point comes from the project's own field: Chef's Omnibus, an automation system that spawns a fleet of VMs to build platform-specific packages. The stated difference is not packaging quality but where the OS variation gets paid for. Omnibus pays with dedicated build machines, and the project estimates you need a big build machine for reasonable build time. Traveling Ruby pays with a promise about binary portability that the README calls more easily said than done, deferring the hard part to an anchor named why_precompiled_binary_difficult.

A shell build system produces the portable interpreters

The project supplies binaries rather than a runtime library. An application developer takes a precompiled interpreter for a platform, puts their own program and its gems next to it, and ships the result. The repository's primary language is Shell, and the top level splits the payloads by platform, with a shared directory beside them and three version files at the root:

code
linux/
osx/
windows/
shared/
RUBY_VERSIONS.txt
BUNDLER_VERSION.txt
VERSION.txt

Those files are the first place to look before depending on the project. RUBY_VERSIONS.txt records which Ruby the binaries carry, BUNDLER_VERSION.txt the Bundler inside them, VERSION.txt the project's own version. Four tutorials sit alongside them at the root: TUTORIAL-1.md builds a hello world package without gem dependencies in 5 minutes, TUTORIAL-2.md handles gem dependencies through Bundler, TUTORIAL-3.md covers native extension gems, and TUTORIAL-4.md covers packages for Windows. REDUCING_PACKAGE_SIZE.md exists because archive weight is a design concern here, not an afterthought, since every download carries an interpreter plus a gem set.

The interpreter is pinned to Ruby 2.4.10

Every payload carries the same interpreter, and the version is not a moving target. The stated goal is supplying precompiled Ruby 2.4 binaries that work for all end users, and the support statement in the caveats names Ruby 2.4.10 specifically.

Because that interpreter is a build artifact of this project rather than something Bundler resolves on the target machine, the pin propagates straight into every archive you produce. An application that later needs a newer Ruby, or a native gem that only compiles against a newer one, has no in-place upgrade path: the interpreter has to be rebuilt into the project and every downstream archive regenerated around it. That is why the version lives in a file at the repository root instead of being buried in build scripts, and why reading RUBY_VERSIONS.txt is the first verification step for anyone wiring this into a delivery pipeline.

Windows packages yes, Windows builds no

Windows support is one sided, and the project is explicit about the direction of that asymmetry. Creating packages for Windows is supported. Creating packages on Windows is not, and the tutorials and documentation do not work for a Ruby developer on Windows, so Windows artifacts have to be produced from macOS or Linux.

The reason offered is not a deep technical limit but an authoring choice: the documentation leans heavily on standard Unix tools, and those tools are absent on Windows. Replacing such tools with Ruby tools would make the documentation usable there too, and that work is not done.

Native extensions widen the gap further. Under the Windows list of caveats, native extensions are not yet supported, which confines a Windows archive to pure-Ruby dependencies. Any Windows target for a tool that depends on a compiled gem sits outside what these binaries can deliver.

Native extensions are a whitelist, per platform

Native extension support is the sharpest constraint in the project, and it has three parts. It applies only when creating Linux and OS X packages. It covers a limited number of popular native extension gems. And within those gems, only some specific versions. The project puts it bluntly: you cannot use just any native extension gem.

A gap opens up between the tutorial index and the caveats that only a close read catches. The getting-started list advertises TUTORIAL-3.md as managing and packaging native extension gems, with no platform qualifier attached. The caveats qualify the same feature twice, restricting it to Linux and OS X packages and then repeating under Windows that native extensions are not yet supported. A team planning a Windows build from the tutorial list alone designs its dependency set first and meets the platform limit afterwards.

For everything else, TUTORIAL-2.md is the route: gem dependencies that are pure Ruby go through Bundler, and the finished archive then carries the interpreter plus a resolved gem set.

Command line tools are the ones that ship this way

The real-world examples listed in the README share one shape: command line tools and small self-contained webapps used by operators, not installed through a distribution package. BOSH ships a traveling-ruby port in the cloudfoundry-community organization. Elasticrawl, an AWS Elastic MapReduce job runner, has a port under a matching name. VirtKick, a cloud web panel, has one. WebAirplay, a local webapp that sends videos to AirPlay devices, has one too.

Octodown, a Github markdown preview tool, is the most instructive case, because its repository carries both an issue and a pull request aimed at Traveling Ruby itself. That is the clearest sign that downstream packagers end up editing this layer themselves rather than consuming it unchanged.

Read together, the list marks the boundary. This is a delivery mechanism for tools that would otherwise ask an administrator to install a language before running a single command.

What the binary choice costs you at delivery time

The project is MIT licensed, and its last push was on 2026-08-03.

Bundling an interpreter has consequences the archive format hides. Each download carries a Ruby plus the full gem set, which is the subject REDUCING_PACKAGE_SIZE.md addresses. The same choice turns an update to the interpreter or a dependency into a fresh archive rather than a package manager transaction on the user's machine. No rollback path is described in the root files, and there is no compatibility matrix beyond the three version files, so the verification burden sits with the adopter: read RUBY_VERSIONS.txt and VERSION.txt, build a package from the current tree, and keep a plain gem-based install working alongside it for users who already have Ruby.

The wrong-tool cases are equally concrete. If the destination expects a DEB or an RPM, this project does not produce one. If the app needs a compiled gem outside the supported set, or a Windows package with native extensions, the constraint lives in the source tree rather than in your build script.

Editorial conclusion

Traveling Ruby fits teams that hand a Ruby tool to operators who will never install Ruby: one archive per platform removes the nine-package matrix and the VM fleet that used to build it. Before adopting it, read RUBY_VERSIONS.txt and check the bundled Ruby against what your app needs, because that pin cannot be bumped without rebuilding every archive you ship. Do not choose it when the destination demands a DEB or an RPM, when a native extension gem falls outside the supported set, or when your own build machine runs Windows.

Frequently asked questions

What Ruby version do Traveling Ruby binaries ship?

The stated goal is precompiled Ruby 2.4 binaries, and the current support statement names Ruby 2.4.10. The version is kept in RUBY_VERSIONS.txt at the repository root.

Can Traveling Ruby create Windows packages on a Windows machine?

No. It supports creating packages for Windows but not creating packages on Windows, so Windows artifacts must be built from macOS or Linux, because the documentation relies on standard Unix tools.

Does Traveling Ruby support native extension gems?

Only when creating Linux and OS X packages, and only for a limited set of popular native extension gems in some specific versions. Windows packages carry no native extension support.

How does Traveling Ruby differ from building DEB and RPM packages?

Instead of one package per operating system version, where 2 CentOS/RHEL, 2 Debian, 3 Ubuntu and 2 recent macOS releases add up to 9 artifacts, it produces 3 archives for Linux x86_64, macOS and Windows from any machine.

What do RUBY_VERSIONS.txt, BUNDLER_VERSION.txt and VERSION.txt hold?

They record the Ruby version carried by the prebuilt interpreters, the Bundler version inside them, and the project's own version.

Where should a new user start with Traveling Ruby?

With the four tutorials at the repository root: a hello world package in 5 minutes, gem dependencies through Bundler, native extension gems, and packages for Windows. REDUCING_PACKAGE_SIZE.md then covers trimming the resulting archive.

Official sources

  1. License: MIT
  2. phusion/traveling-ruby on GitHub
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/phusion-traveling-ruby.svg)](https://hysenlabs.com/projects/phusion-traveling-ruby)

Was this useful?