The whys and nots of Rails Wasm-ification

Before we start digging deeper into technical details of running Rails on Wasm, let's talk for a moment why, beyond the joy of problem solving, you might want to do that.

The cases of client-side Rails

There are many popular Rails applications out there in the wild (check, for example, Using Rails). They all embrace the client-server paradigm with the server responsible for processing requests from different clients (sometimes, tons of clients) and communicating with other systems and services. You cannot do all of that if you manage to launch a Rails server within your browser.

However, there are some scenarios when it could be beneficial.

Let's start with the obvious one—this application.

You can turn your network connection off and continue reading the book, even though it's backed by the Rails application. Try right now!*

* Might now work in some browsers, sorry :( Try visiting the debug page and see what happened.

The Writebook by 37signals, which we use here, is a good example of the application that can live fully in your browser. You can continue reading even if you're offline! That's because we installed a copy of the app right in your browser (along with the database snapshot).

Thus, the first use case for Rails on Wasm is the offline-experience. It could be limited (e.g., read-only); some parts of the app might not be accessible. Still, the UX would be more pleasant than a "No network" error or browsing through some static cached pages.

What if I tell you that I've been writing this book while being offline? This Writebook on Wasm fully works in the browser, meaning that I can create new pages, upload images, and so on. And whenever I'm back online, all the offline changes can be synced with the server. This makes our offline exprience much closer to the local-first paradigm.

Yes, could be a local-first application. Although I would call it offline-aware instead (since the primary scenario is writing books over the network, the local app is just a fallback).

But there could be truly local-first Rails applications:

You can run a local-first Rails application in the browser, or as a desktop application (remember, Wasm != Web), or even as a mobile application (see, for example, wasm3).

Finally, we should also mention the case of serverless Rails. Many platforms support Ruby as is, no need to deal with Wasm (there are also serverless frameworks, like Jets), but the portability of Wasm opens every serverless door.

Limitations and caveats

The most important concerns regarding shipping Wasm-based Rails applications into your users browsers are file sizes and browsers support.

A relatively small Rails app with all the source code, dependencies and assets (like Writebook) results in ~100MB with ~70MB just for the Ruby and dependencies (without any specific size optimizations). It is possible to implement some chunking and caching strategies, e.g., distribute the source code independently and caching the Wasm module at the user's device, but that requires additional work. The ruby.wasm also works towards minimizing the core bundle size, so we should expect it to drop in the future.

interpreter-size.png

The browsers support is pretty good for WebAssembly*, but still some companion technologies that we use are lagging behind (namely, OPFS and CookieStore API).

* Currently, we hit stack size limitations in Safari, see issue.

However, it still makes sense to provide Wasm-driven offline experience to users using fully supported runtimes.