Is that headline click-bait? Yes.
Do I believe it? Also yes.
Think Rails is old, slow and past its prime? Think SPAs are the only way forward? Think again. StimulusReflex introduces a simple, blazingly fast new way to build incredible Rails apps. Go! Click it! I'll wait...
First off, I'm not some big name in the Rails or Ruby community. I'm not a core contributor. I know some folks, but I'm the quiet guy in the back room. I don't sit up nights working on new frameworks or libraries to try and push the envelope forward for the industry as a whole. Part of me would love to be that developer, but I'm just not.
I'm a practitioner.
I've built software that helps people enhance their careers; software that gets gamers deeper into their favorite game communities; worked on software that sells event tickets; software that presents network security dashboards to CTOs; software that configures SAN appliances; and software that trains Army battle captains.
But this is about to change.
My current tabletop RPG group is a bunch of dads, spread across the US, who've been playing D&D virtually through Zoom for several years. But suddenly, with lockdowns and kids permanently at home, we found ourselves (paradoxically, it might seem) with even less time to play. I'd already been toying with the idea of building a web app to help streamline game sessions, but the pandemic sent me into overdrive. With the (very) limited free time I had left, between homeschooling my kids and my day job, I started looking in earnest for a tech stack to build the app with. I had three requirements:
- The app needed to be really quick, smooth, and have a modern, reactive UX.
- I needed to be able to build it, quickly, by myself.
- I wanted to learn something new.
Could I build it with "classic" Rails? Sure. I'm real good at that... 15 years good at that, and I could cobble it together with spaghetti JS and get close to my goals. But I wanted something more ambitious, something more organized, and something where I could hone some skills. I looked at SPA frameworks like React, Angular, and Ember. They're amazing, and I have existing experience there through my day job. I figured I could beef up my existing SPA skills, and started down that path, but kept getting cold feet every time I looked at two git repos that I would have to build simultaneously, and a JSON-based interface to bridge them... or maybe GraphQL, but now I'd be fighting performant queries on the backend, or... ugh. With a team of developers, sure, I could push all that complexity off onto multiple people power, and it's a totally viable strategy. But Goal 2 was to see what I could build with 1 person; something that could compete with the reactive apps being built by whole teams (like the one I manage). Was it even possible?
Enter Stimulus, StimulusReflex, CableReady, ViewComponentReflex, Optimism, and their buddies. Enter surgical HTML-over-websockets. Enter hyper-responsive user interactions that don't create state synchrony nightmares.
Within four days (and really, we're talking a couple hours each night after the kids go to bed), I had a prototype of ChaosMage up and running that had the following characteristics:
- NO full page reloads after the initial load
- Controller actions and reflexes that resolve as fast as any JSON API endpoint
- Real-time JS-driven bells and whistles on nearly every user-facing page that could benefit from them
- Far less JS for the browser to load, since there's no state management libraries on the client
- A clean, organized, component-based code architecture that works seamlessly with all the standard Rails stuff, and sidecars .rb, .js, and html templates together
- CSS transitions for every button, User and Character avatars (with a JS cropping tool!), pop-up modals, pop-over drawers, remote forms with real-time validation, you name it...
- A Three.js-based dice roller with physics and collisions, served and controlled by Rails and Stimulus controllers
- A complete, Discord-like chat channel, complete with emojis, dice rolling commands, markdown support, parsing and re-rendering, and near-instantaneous broadcast of messages to everyone in the channel in under 50ms
Within a week, I had the app up on Hatchbox and alpha-tested with my gaming group on our next session. It worked flawlessly. Dice were rolled. Chats were... chatted? For the first hour, they thought I had found this new app somewhere online and didn't realize I had built it myself in just a few days.
I suddenly re-experienced the feeling I had back in 2005, tinkering with one of the earliest releases of Rails; the feeling of leaving behind the PHP development where I'd spent most of my time setting up the architecture of my project. Instead, I was getting some new, delightful feature up-and-running every hour.
For the past few years, I've been primarily building high-performance API endpoints to power fancy, reactive, gorgeous SPAs written fully in JS. I've been watching front-end teams fight race conditions with the back-end. I've been designing weird data architectures to make opinionated JS frameworks happy with the giant piles of JSON they're asking for. I've facepalmed at 50ms page loads, only to see an empty page full of spinners that, in total, take 3 seconds to all finally resolve. This wasn't what I was promised.
But with this new way of thinking about and building Rails apps, I suddenly found myself single-handedly launching features again. My view templates just pull together smart, wired-up components. Reflexes let me keep the state the user is experiencing totally in-sync with the back-end reality with only a few lines of code. Pages in the app render with few spinners and everything already on-page, often in under 100ms.
Developing an app feels fun again.
I didn't realize how much I'd missed that feeling in the past couple years.
But I truly believe that we shouldn't have to spin up two code repos to make something non-trivial. (And for many companies, this means two teams or a team with bifurcated 'front-end' vs 'back-end' responsibilities.)
We shouldn't need to spend days and multiple team meetings iterating on our data communications schema.
We shouldn't be building one-size-fits-all API endpoints that sacrifice performance for front-end compatibility.
We shouldn't be jamming megabytes of client-side code onto users' low-end laptops until they crash Chrome.
Sub-second page loads with multiple seconds-worth of spinners isn't an enjoyable user experience.
And are we really okay with sending more bytes of JSON than the actual HTML we're going to mutate on the front-end with it.
I'm sure some folks reading this will say, "But, my dude, you're probably just building your API+SPA stacks wrong." And they might be right. Lots of great apps are built with SPAs, and with a dedicated team, we can build just about anything. I'm sure there's plenty of room for optimizing architectures and processes.
But with StimulusReflex, CableReady, ViewComponents, and Optimism, we don't have to. We're now looking at a completely new way of building reactive modern apps, while still using an established framework that has a huge community of awesome people and existing libraries and solutions for common challenges.
And just think: if I can do all of that by myself, imagine what a team of full-time devs could do!
And in 2020, with the way things are going, we need tools that feel great and get us quick wins for non-trivial challenges, because we've got way too much to worry about otherwise.
Don't believe me that 2020 could mark a new era of Rails development? That's okay. Do your thing and be happy! Build awesome stuff that makes people happy in these unhappy times, using whatever tech makes you happy.
But if, like me, you've been feeling like maybe there's a simpler, quicker way to ambitious software, without sacrificing a modern UX... well, I'm urging you to take a look at what I think is a coming sea change:
Go check out this growing new ecosystem. Definitely toy with the demos and expos. But also take it from me: these aren't just clever trick libraries made to show off some weird thing you can do. This is a new paradigm, folks. This is a new path forward, a third option way beyond 'classic' server-rendered apps and API+SPA verticals.
I'm fully onboard, and I don't jump onto shiny new trains lightly. I intend to see where these new rails go.
(Hey, and if you're playing D&D, 13th Age, or Starfinder, keep your eyes on chaosmage.app ... I intend to open this thing up for everybody once it's polished up real nice!)