Getting out of JavaScript Hell
The JavaScript Spiral
I was trapped in API purgatory. My days were spent crafting pristine Ruby on Rails backends, pumping out JSON all day. Then came the front-end—a separate Angular app, patched together with npm, TypeScript, and a mountain of configuration files. My screen was full of dependency errors, RxJS streams gone rogue, and Angular’s cryptic debug logs. One minute I was in a Rails controller, the next I was untangling an Angular service. Coding felt like running a mental gauntlet, and my Emo Punk Thursday Afternoon daylist wasn’t enough to keep me sane.
Why I Ditched the API-Front-End Split
The API-plus-Angular life sounded sleek: clean endpoints, decoupled systems, enterprise vibes. But it was a slog. I was writing double the code, juggling two repos, and deploying two apps. Switching between Ruby’s elegance and Angular’s rigid ceremony gave me whiplash. Hosting costs stacked up, and debugging meant ping-ponging between server logs and browser dev tools. I was done.
Then I went all-in on full-stack Rails 8 with Hotwire—game changer. It was like swapping a clunky tour van for a Porsche. One app, one codebase, one deployment. Barely any JavaScript, zero Angular. Hotwire’s latest tricks even let me turn my web app into a native mobile app with minimal Swift or Kotlin. Here’s why full-stack Rails became my middle finger to JavaScript hell.
Full-Stack Rails: JavaScript? Hardly.
Rails 8 and Hotwire slashed my JavaScript to almost nothing. Forget and Angular component—I lean on Hotwire’s Turbo and Stimulus. Turbo Streams push real-time HTML updates over WebSockets, like live chat or notifications, without a single API call. For my real estate app’s tenant messaging system, one line—<%= turbo_stream_from @chat_group %>—delivered instant message updates. No JSON, no Observables, no Angular modules.
Stimulus handles the rare client-side tasks, like toggling a modal or validating a form. I built a file upload feature with a Stimulus controller—15 lines of JavaScript, max. Compare that to the 300-line Angular directive I’d have wrestled with. Hotwire makes things far simpler.
One App, One Life
Hosting separate backend and front-end apps was a nightmare. Two servers, two domains, two sets of SSL certs. Full-stack Rails collapses it into one. My real estate app—a single Rails 8 app with Hotwire—does it all: server-rendered views, real-time updates, authentication. No splitting between Heroku for Rails and Vercel for Angular. One git push, and I’m live.
This unified setup saved me on my last project. I used Solid Cable with SQLite in development for real-time tenant notifications—zero setup, no Redis. In production, It would be the flip of a switch to use postgres.
No More Code-Switching
Bouncing between Ruby and Angular was like mixing languages mid-sentence. Rails’ convention-over-configuration clashed with Angular’s “configure everything twice” dogma. Full-stack Rails keeps me in Ruby land. Views are ERB, logic lives in controllers or services, and Hotwire handles the dynamic stuff. I’m not flipping between rails console and ng serve—it’s just me, my Rails app, and a little stimulus JS. This focus lets me ship new features in a weekend and not worry about a house of cards falling to the ground.
Hotwire Native: Mobile Without the Pain
Hotwire’s latest gem, Hotwire Native, clinched it. It turns a Rails app into a native iOS or Android app with minimal Swift or Kotlin. My real estate app’s mobile version was a revelation. Using Hotwire Native’s Swift library, I wrapped my web views in a native shell, added push notifications, and had an iOS app running in a couple days. The Navigator class handled routing, and Turbo’s hybrid rendering meant my server-side views worked out of the box.
For notifications, I used Hotwire Native’s bridge to route taps to URLs—like /chat_groups/5 for a new message. A sprinkle of Swift for the payload, and tenants could jump to chats from a notification.
Rails 8’s Full-Stack Arsenal
Rails 8 makes full-stack life effortless with tools that cut the cruft:
- Hotwire (Turbo + Stimulus): Real-time updates and minimal JavaScript. Turbo Streams for live features, Stimulus for light interactivity.
- Solid Cable: Database-driven WebSockets for real-time, no Redis needed. I used it with SQLite in dev and PostgreSQL in production for my app’s chats.
- Importmap-rails: JavaScript dependencies without npm. Pin a library in
config/importmap.rb, and you’re set.
These let me build my real estate app—payments, tenant apps, maintenance requests, messaging—in weeks. It really allows you to ship comfortably without the sweat of checking both servers for logs and errors.
The Catch
Full-stack Rails isn’t flawless. There are some learning curves involved with Stimulus and Turbo. Sometimes the Rails magic leaves you scratching your head. The more Stimulus controllers I write, the more things start to click. The main hurdle for me was how it makes JavaScript feel closer to Ruby. You write these controllers so similar to how you would write a rails controller, but you get the neat Javascript methods that can make life easier. The catch will quickly turn into a pro.
Why I’m Done with Angular
Switching to full-stack Rails 8 with Hotwire was like quitting a soul-sucking desk job to go live in the woods—a simple life. I write almost no JavaScript, host one app, and live in Ruby’s cozy world. Hotwire Native turns my web app into a native mobile app with barely any fuss. I’m not just coding—I’m shipping, fast. My real estate app’s users will get a snappy, real-time experience.
JavaScript hell is real, but full-stack Rails is my way out. If you’re sick of API sprawl and Angular’s baggage, try it. Spin up a Rails 8 app, add Hotwire, and build something. You’ll wonder why you ever dealt with two codebases.
What’s your JavaScript horror story? Drop it in the comments on substack. Let’s vent.