Rust is the answer to the wrong question
The below was 100% written by a human.
TL;DR: porting an app to another language is merely an anecdote. One shoting an application from scratch optimizes the easy part (initial authoring) and completely misses the point on the hard part: maintenance. Repeated one-shots are not the answer to security vulnerabilities.
What's needed is a rock-solid contract layer, complete with escape hatches to cover what the DSL doesn't handle natively. And a compiler.
Prologue
A chess program can beat me. That isn't clearing a high bar - I'm mediocre at chess. The fact that a LLM can beat me at coding isn't surprising either, despite the fact that I can credibly claim to be a world class coder, and have a portfolio of results I can point to.
Shared Nothing
Imagine a Google Sheet. A spreadsheet with collaboration abilities. Use it by yourself, with a friend or a small group. It is there when you access it, and consumes no resources when you are away. They are inexpensive and when you need a new one you create it.
A lot of applications look like this. Looking at the Once family of applications, Campfire, WrightBook, and Fizzy certainly are. In many ways, a VPS is overkill if it is still running when you are asleep.
In many ways, LLM conversations have the same shape. I explored that in Routing to Identity.
Showcase
I wrote an application for scheduling dance event competitions. As a CRUD application, Rails was a natural choice.
Over time, I added features including invoicing and scoring. Superficially, these are also CRUD so they fit.
The application as a whole is very much like a google sheet - each event is independent after creation. (I have a feature to enable seeding a new event with data you select from a prior event.) With fly.io, events in Australia are hosted in Sydney, events elsewhere are hosted near the event.
Offline
It turns out that one of those requirements is not like the others. Data entry before the event and report generation after the event are fine, but scoring during the event is problematic if WIFI is either not available or unreliable. It is also an ideal offline use case: each judge's scores are independent so there are no merge conflicts.
So, I have a bunch of ERB files, some minimal logic (let's get real: data entry of scores is not complex business logic), and some validation rules. Offline in this case means running in the browser or on your phone. Places Ruby doesn't run.
Look at the progression: a requirement that wasn't in the original scope changes the deployment target which changes the choice of language.
Transpilation
Ruby2JS was written back when JavaScript frankly sucked and CoffeeScript became popular. JavaScript improved, I lost interest, but now I had a reason to be interested again. I started exploring transpiling ERB and found I could do more; the main issue was that I needed to take type inferencing seriously (example: iterating over a hash is different than iterating over an array in JS), so when I see an ivar in a partial I need to trace its value back to the controller and even the model. I briefly explored building on Crystal's type inferencing, but quickly realized I needed to take ownership of this. Roundhouse was born.
https://rubys.github.io/roundhouse/demo/ shows the initial application. If you are more of a visual person, see the presentation: https://intertwingly.net/blog/2026/09/03/Continue-the-Argument.html or read the slides (press "S" for speaker notes): https://rubys.github.io/rubyconf-2026/ . Click on a language in https://rubys.github.io/rubyconf-2026/#/8 and download a blog application in the language of your choice, and follow the instructions in the README. You will have an application that uses TailwindCSS, TurboStreams, and Action Cable and is indistinguishable from Rails.
Along the way, I Spinel was born. It was a natural fit. Even if another language is the right ultimate target, transpiling first to CRuby then to Spinel are great stepping stones. And it works both ways, when I implemented Rust as a target, Spinel's output got faster. As did CRuby. Making things monomorphic enables optimization. Rails, as written, has everything as a hash. We can do better.
Future
What I have is mind blowing. I can run a three tier Rails app in your browser, complete with sourcemaps and breakpoints. Transpile your test cases and run them in watch mode in the browser on every save. I can deploy the same app to Vercel with a Neon database or to CloudFlare with a Durable Object - no rewrite required.
Try the Dictaphone demo: https://ruby2js.github.io/ruby2js/dictaphone/ and look at the stimulus controller - written in Ruby with direct access to the DOM and Active Record. In fact, every Rails route that returns JSON can be used as a server function.
Perhaps MVC is the wrong paradigm. Most JS Frameworks seem to be converging on Single File Components, where individual controller actions are placed alongside the associated view, and source file pathnames serve as convention over configuration. These could coexist in the same source tree as the server and share in the whole program type inferencing, guaranteeing that the client is always in sync with the server.
Reactivity and Server Functions are just two examples of features of JS Frameworks. Incremental Static Regeneration is key to scalability - your catalog needs to survive a DDOS, but your shopping cart needs to be live. These could be DSL additions to the existing routes that are ignored or applied based on deployment options.
And it goes deeper. If you can emit Kotlin and/or Swift - you can have a single definition that generates native applications as well as a web interface. This doesn't need to be all or nothing, nor does it need to be a leas common denominator. All from a single source of truth.
Conclusion
Yes, Rust is faster than CRails. Duh. But is that really the interesting question? What happens when your needs change and you are faced with a requirement than you never anticipated before?
As I stated up front, what's needed is a rock-solid contract layer, complete with escape hatches to cover what the DSL doesn't handle natively. It doesn't even have to be something a human ever reads. What is important is that it captures intent rather than mechanism.