Ruby's + means addition between integers, concatenation between strings, concatenation between arrays, and a runtime raise between an integer and a string. To produce correct output for one operator in six target languages, a compiler has to know the operand types at each site — in Rust where types are mandatory, and equally in Elixir, Python, and TypeScript where they're not. Roundhouse's bet rides on that observation. Today two pieces of load-bearing infrastructure landed: RBS ingestion on both sides of the compiler, and a diagnostic pipeline that surfaces what the typed IR can't resolve.
Rails apps come pre-typed. Schema declares column types, conventions thread them across associations and controllers, and standard inference fills in the rest. None of it requires annotations — the information is already in the source. Roundhouse reads it, types every expression, and emits to seven targets. As of today, the TypeScript and Rust targets produce the same DOM as Rails on the standard blog scaffold.
Roundhouse reads Rails applications and produces standalone projects in other target languages — the deployment target becomes a compiler flag rather than a runtime choice. It started two days ago. Here's what it is, what it can do today, and why the Rails subset it targets is larger than it sounds.
The internet says Claude Code is nerfed. That has not been my experience. A Rails blog app, transpiled to six compiled languages with real-time WebSocket broadcasting, downloadable binaries, 126+ tests. Nine days.
Railcar can now transpile a Rails application to Rust. The same blog app generates a working Axum server with rusqlite, Turbo Streams — 21 tests passing, zero compiler warnings, the sixth target language.
Railcar can now transpile a Rails application to Go. The same blog app generates a working net/http server with view functions, modernc.org/sqlite, and Turbo Streams — 21 tests passing, the fifth target language.
Railcar can now transpile a Rails application to Elixir. The same blog app generates a working Plug + Bandit server with EEx templates, Exqlite, and Turbo Streams — 21 tests passing, the first functional language target.
Railcar can now transpile a Rails application to TypeScript. The same blog app generates a working Express server with EJS templates, better-sqlite3, Turbo Streams — 21 tests passing, the third target in a single day.
Railcar can now transpile a Rails application to Python. The same blog app that compiles to Crystal also generates a working Python web application with aiohttp, SQLite, Tailwind CSS, and Turbo Streams — 21 tests passing, full CRUD with nested resources.
Compiling arbitrary Ruby is hard. Generating type signatures for arbitrary Ruby is hard. But Rails isn't arbitrary Ruby — it's a DSL with known semantics. Railcar exploits that to do three things: transpile Rails apps to Crystal, provide a Rails-compatible Crystal framework, and generate RBS type signatures.
Ruby can call C. Ruby can call Python. But calling JavaScript has always meant eval strings or manual bundling. Boax embeds the Boa JS engine in Ruby via Rust, letting you call JS libraries with the same proxy-object pattern Ruby developers already know.
Most transpilers work file by file. But Rails encodes meaning across files — controller names imply view paths, associations imply async behavior, group_by in a controller implies Map operations in a view. Juntos reads the whole application and carries that knowledge forward.
We took Basecamp's Writebook — a real Rails 8 application — and ran it through Juntos. The server starts, the database initializes, and HTTP requests are served. Here's what we learned.
The Ruby2JS documentation site now compiles itself. Every live demo runs Ruby2JS transpiled by Ruby2JS — no Opal, no server, just the transpiler in your browser.
A Rails blog transpiled to JavaScript produces identical HTML. Not similar. Not close enough. Identical. Here's how I proved it and what I found along the way.
A Rails blog running across three browser Workers — SharedWorker for application logic, dedicated Worker for SQLite with OPFS persistence, main thread for Turbo and Stimulus. Under 600KB gzipped. No server required.
The full test suite—model tests, controller tests, system tests—running continuously on every save at 47ms per test. Faster than jsdom. In a real browser. The tests DHH gave up on, running on every save.
Transpiling Ruby to JavaScript is usually discussed in terms of deployment targets. But it has a second payoff: system tests that run in 75ms with zero flakiness. Same Capybara DSL. No browser required.
Kubernetes routes to capacity. Cell orchestration routes to identity. These are fundamentally different problems, and everything downstream follows from which one you're solving.