OCRAN: Turn Ruby Scripts into Executables for Windows, Linux and macOS
I maintain OCRAN, a Ruby gem that packages Ruby applications for distribution. It bundles your script, the Ruby interpreter, your gems and the native libraries they need into a self-contained artifact, so people can run your program without installing Ruby. Since version 1.4 it works on Windows, Linux and macOS.
OCRAN stands for “One-Click Ruby Application Next”. In this post I explain where it comes from, how to use it, and what changed recently.
From OCRA to OCRAN
OCRAN is a fork of OCRA, the One-Click Ruby Application builder that Lars Christensen started in 2009. For many years OCRA was the usual way to turn a Ruby script into a Windows .exe. Its last release, 1.3.11, came out in March 2020, and its changelog lists support for Ruby 2.2 to 2.7.
In 2023 I forked it to keep it working with current Ruby versions. The first OCRAN release, 1.3.12, supported Ruby up to 3.2. It has not been a one-person effort: shinokaro is a co-author in the gemspec, and a large share of the commits since the fork are theirs. Lars Christensen is still listed as an author as well, because the foundation is his work.
If you are still using OCRA, I wrote a short migration guide from OCRA to OCRAN. The command-line options are the same.
What OCRAN produces
OCRAN has four output formats:
- Self-extracting executable (default): a
.exeon Windows and a native executable on Linux and macOS. It unpacks itself to a temporary directory and runs from there. - Directory (
--output-dir): all files in a folder, plus a launch script (.shon Linux/macOS,.baton Windows). - Zip archive (
--output-zip): the same as the directory output, packed into a.zip. - macOS app bundle (
--macosx-bundle): a.appbundle for Finder, the Dock and code signing.
On Windows you can also create a proper installer with Inno Setup (--innosetup).
Getting started
OCRAN requires Ruby 3.2 or newer.
gem install ocran
ocran script.rb
This runs script.rb, records which files and libraries it loads, and builds script.exe on Windows or script on Linux and macOS.
The other output formats:
ocran --output-dir myapp/ script.rb
ocran --output-zip myapp.zip script.rb
ocran --macosx-bundle --output MyApp --bundle-id com.example.myapp --icon icon.icns script.rb
You can add extra files, directories or glob patterns, and pass arguments to your script after --:
ocran script.rb assets/**/*.png
ocran script.rb -- --some-option=value
ocran --help lists all options.
How dependency detection works
OCRAN does not analyse your code statically. It runs your script during the build and includes everything that gets loaded through require and load. Code that is only loaded under certain conditions is included only if those conditions are met during the build run.
For programs that open a window or wait for input, you can check for the Ocran constant. It is only defined while OCRAN is building:
app = MyApp.new
app.main_loop unless defined?(Ocran)
If files from a gem are missing at runtime, try --gem-all=gemname first, then --gem-full=gemname. For Bundler projects, --gemfile Gemfile includes all gems listed in the Gemfile.
When the self-extracting executable runs, $0 points into the temporary directory, and the environment variable OCRAN_EXECUTABLE contains the full path of the executable itself. That is useful for finding files you ship next to it:
base_dir = File.dirname(ENV["OCRAN_EXECUTABLE"].to_s)
Things to keep in mind
- No cross-compiling. OCRAN bundles the Ruby from the machine it runs on, so you build Windows executables on Windows, Linux binaries on Linux and macOS binaries on macOS. The README contains a GitHub Actions workflow that builds all three.
- glibc on Linux. OCRAN bundles shared libraries such as libyaml or libssl, but glibc always comes from the target system. Build on the oldest distribution you want to support.
- CPU architecture. The output matches the Ruby you build with. An ARM64 Ruby on Apple Silicon produces an ARM64 executable that does not run on Intel Macs.
- Startup time. The self-extracting executable unpacks on every launch. If that is too slow, use
--output-dir,--output-zipor an Inno Setup installer.
What changed recently
- 1.3.17 (May 2025): multibyte (UTF-8) file and directory names on Windows 10 1903 and newer.
- 1.3.18 (March 2026): Ruby 4.0 support, Windows Authenticode code signing, and Ruby 3.2 as the minimum version.
- 1.4.0 (March 2026): Linux and macOS support, plus
--output-dir,--output-zipand--macosx-bundle. There are now platform-specific gems, sogem install ocranpicks the right pre-built stub automatically. CI tests Ruby 3.2, 3.3, 3.4 and 4.0 on Linux, macOS (ARM and Intel) and Windows. - 1.4.4 (August 2026): on Linux, detected shared libraries are bundled so executables also run on distributions where they are missing. Distro-packaged Ruby, for example on Fedora, works too. The OCRA-style wrapper executable for Inno Setup installers is back.
- 1.4.5 (August 2026): the new
--chdir-exe-diroption sets the working directory to the folder that contains the executable. There is also an experimental--cosmo-rubyoption, which packages a cosmopolitan Ruby build into one file that runs on Linux, macOS and Windows. It is still experimental, so read the README before relying on it.
The full list is in the changelog.
Feedback
If something does not work, please check the issues on GitHub first and open a new one if your problem is not there yet. Reports that include the Ruby version, the operating system and the exact ocran command help a lot.
- Source code: github.com/largo/ocran
- Gem: rubygems.org/gems/ocran