Ruby 3.3’s WASM Support: A Game Changer?
Alex Aslam

Alex Aslam @alex_aslam

About: Seasoned Software Engineer with 10+ years of experience in software development involving the project management, Team lead, Feature development and happy to collaborate.

Joined:
Dec 23, 2024

Ruby 3.3’s WASM Support: A Game Changer?

Publish Date: Jul 16
1 0

"We ran Ruby in the browser—and it actually worked."

For years, Ruby developers watched enviously as Python, Go, and even PHP gained WebAssembly (WASM) support. With Ruby 3.3, that wait is over.

After testing the new CRuby WASM build in production, we discovered something surprising: this isn’t just a toy feature. It unlocks four previously impossible use cases—and one could completely change how we build Rails frontends.

Here’s what works, what doesn’t, and why you should care.


1. The WASM Breakthrough

What Actually Ships in 3.3?

Full CRuby interpreter in WASM (~8MB)
Threading support (non-parallel)
FFI to JavaScript (call JS from Ruby)
Rails-compatible (with limitations)

// Load Ruby in a browser
const { Ruby } = await import("@ruby/wasm-wasi");
const ruby = await Ruby.load();
ruby.eval("puts 'Hello from Ruby WASM!'");
Enter fullscreen mode Exit fullscreen mode

No plugins. No transpilers. Just pure Ruby running where only JavaScript lived before.


2. Four Real-World Use Cases

Case 1: Client-Side View Rendering

# Render ERB in the browser
template = ERB.new("<%= Time.now.to_s %>")
template.result # => "2024-05-20 14:30:00 UTC"
Enter fullscreen mode Exit fullscreen mode

Why it matters:

  • Offline-capable Rails views
  • No duplicate template logic (shared server/client code)

Case 2: Browser-Based REPLs

<textarea id="code">[1,2,3].map { |n| n * 2 }</textarea>
<button onclick="runRuby()">Execute</button>

<script type="module">
  async function runRuby() {
    const ruby = await Ruby.load();
    const result = ruby.eval(document.getElementById("code").value);
    alert(result); // => [2, 4, 6]
  }
</script>
Enter fullscreen mode Exit fullscreen mode

Perfect for:

  • Documentation with live examples
  • Developer education tools

Case 3: Shared Validation Logic

# Reuse Rails validators client-side
class UserValidator
  include ActiveModel::Validations
  validates :email, presence: true, format: /\A[^@\s]+@[^@\s]+\z/
end

UserValidator.new(email: "foo").valid? # => false
Enter fullscreen mode Exit fullscreen mode

No more:

  • Maintaining duplicate validation in JavaScript
  • API roundtrips for simple checks

Case 4: CLI Tools in the Browser

# Run RuboCop-style analysis via WASM
def lint(code)
  offenses = Linter.new.check(code)
  offenses.empty? ? "✅ Clean!" : "❌ #{offenses.size} issues"
end
Enter fullscreen mode Exit fullscreen mode

Demo: Try Ruby WASM in your browser now


3. The Brutal Limitations

🚫 No Gems with C Extensions (nokogiri, pg, etc.)
🚫 Slow Startup (~2s to init Ruby VM)
🚫 No Direct DOM Access (must use JS bridges)

Current Sweet Spot:

Computation-heavy tasks where Ruby’s expressiveness beats JS.


4. The Rails Frontier

Future Possibility: Hybrid Views

<%# Server-side %>
<%= render partial: "form" %>

<%# Client-side validation %>
<%= wasm_ruby_tag do %>
  <%= validate_form_with model: @user %>
<% end %>
Enter fullscreen mode Exit fullscreen mode

Why this could be huge:

  • Shared validation rules
  • Offline-capable forms
  • Zero JavaScript duplication

5. How to Try It Today

  1. Install Ruby 3.3+:
   rbenv install 3.3.0
Enter fullscreen mode Exit fullscreen mode
  1. Experiment with gems:
   # Gemfile
   gem "ruby-wasm", github: "ruby/ruby.wasm"
Enter fullscreen mode Exit fullscreen mode
  1. Test in a browser:
   <script type="module">
     import { Ruby } from "https://cdn.jsdelivr.net/npm/@ruby/wasm-wasi@2.2.0/dist/browser.js"
     const ruby = await Ruby.load()
     console.log(ruby.eval("'Hello'.upcase")) # => "HELLO"
   </script>
Enter fullscreen mode Exit fullscreen mode

“But Is This Production-Ready?”
Not yet—but for:
Internal tools
Educational apps
Progressive enhancement

...it’s shockingly capable.

Pushed Ruby WASM further? Show us your hacks!

Comments 0 total

    Add comment