Hotwire for Rails Developers: Keeping UI Fast and Maintainable
Reading time: ~ 4 minutes

The Challenge of Modern Frontend in Rails
Rails developers often face a dilemma: Should they stick with built-in Rails tools or go all-in on React for interactivity? The rise of JavaScript-heavy apps has made Rails projects harder to maintain. Many teams feel forced to separate the frontend and backend, leading to extra complexity, API management, and more dependencies to manage. While React is powerful, it often adds more overhead than necessary for traditional Rails apps.
But what if you could build a modern, dynamic UI without the extra complexity?
Enter Hotwire – A Rails-native alternative
Hotwire embraces the power of server-rendered HTML while still delivering a fast, interactive user experience. Instead of shifting everything to the frontend, it keeps Rails at the core and handles interactivity in a way that feels natural to the framework.
With Hotwire, you don’t need to set up a separate API, manage client-side state, or keep up with endless JavaScript updates. You get the best of both worlds—modern UI interactions without the React overhead.
What is Hotwire? A Rails Developer’s Perspective
Hotwire is a framework that brings modern UI interactivity to Rails without the complexity of a full JavaScript frontend. It keeps things simple by relying on server-rendered updates instead of pushing everything to the client.
At its core, Hotwire = Turbo + Stimulus:
- Turbo – Handles fast page loads, real-time updates, and partial page changes without writing custom JavaScript. This means forms, lists, and UI interactions feel instant without managing the frontend state.
- Stimulus – A small JavaScript framework that adds enhancements where needed. Unlike React, it doesn’t take over the UI—it simply connects behavior to existing HTML elements.
Why Hotwire Fits Rails So Well
Rails has always been about "convention over configuration." Instead of forcing developers to make endless decisions about frontend architecture, Hotwire follows Rails’ principles:
- It works out of the box with Rails' existing tools.
- It keeps backend logic in Rails instead of spreading it across multiple layers.
- It reduces unnecessary complexity by avoiding heavy JavaScript frameworks.
With Hotwire, you don’t need to rework how your app is built—you just extend Rails' strengths to create a fast, interactive UI with minimal effort.
When to Use Hotwire Instead of React
There are many cases where React is overkill in a Rails app. If you don’t need a full-blown single-page application (SPA), React might be adding more complexity than value.
When React is Overkill
- Your app isn’t an SPA, but it still has some interactive elements.
- You’re using React for only a few small features (modals, forms, or UI updates).
- You’re dealing with long build times, slow initial page loads, or performance issues caused by client-side rendering.
When Hotwire Shines
- You want to keep your app fully within Rails without adding a separate frontend framework.
- You need real-time updates but don’t want to set up WebSockets manually.
- You prefer less JavaScript and more of Rails' simplicity.
Hotwire is a great choice for those who want modern UI features without the complexity of a JavaScript-heavy setup. It lets you build fast, interactive apps while keeping your Rails app clean and maintainable.
Hotwire in Action: How We Use it at Planet Argon
In our recent project for Olsson Roofing, we built a mobile-first web application for field maintenance workers. Instead of using React as we typically would, we embraced Hotwire—Rails' modern approach to building responsive web applications without writing much JavaScript.
Turbo Streams for Form Steps
One of our main uses of Hotwire was implementing a multi-step form process for roof inspections. We used Turbo Streams to navigate different form sections without full page reloads. When users submit a form step, the controller responds with a Turbo Stream that updates just the form content:
The form partial is structured to work with these Turbo Stream updates:
This approach allowed us to:
- Keep each form step isolated and maintainable
- Provide instant feedback when moving between steps
- Maintain a smooth user experience on mobile devices with slower connections
- Handle form validation errors without losing context
Stimulus for Enhanced Interactivity
While Turbo handled most of our needs, we used Stimulus for client-side interactions that required JavaScript. Looking at our views, we can see how we connected Stimulus controllers:
This data-controller="form" attribute connects to our form controller that handles image previews:
The controller is automatically loaded thanks to our Stimulus configuration in app/javascript/controllers/index.js:
What We Learned
The Good
- Productivity Boost: Hotwire allowed us to build interactive features with significantly less code than a React-based approach.
- Performance: Thanks to Turbo's smart HTML streaming, the app feels snappy even on slower mobile connections.
The Challenging
- Mental Model Shift: Coming from React, it took time to shift our thinking from client-side state management to server-side HTML updates.
- Debugging: Initially, debugging Turbo Frame and Stream issues was tricky since they operate differently from traditional AJAX requests.
- Documentation: While Hotwire's documentation is good, finding solutions for edge cases sometimes required diving into source code or community discussions.
What We'd Do Differently
- Frame Organization: We would better organize our Turbo Frames hierarchy. For example, we could have nested frames for related form sections to better manage state:
Stimulus Controllers: Instead of the somewhat monolithic form controller we ended up with, we would create more focused, reusable stimulus controllers.
Error Handling: We'd implement more robust error handling for Turbo requests, possibly with a dedicated error Stimulus controller:
FAQ’s and Resources
- "Can Hotwire handle complex UIs?"
→ Yes, but it requires rethinking how you structure frontend logic. - "What about existing React components?"
→ Hybrid approach: Keep React where needed and transition the rest. - "Is it hard to learn?"
→ If you know Rails, you can pick up Hotwire fast—here are some of our favorite resources.
- Hotwired.dev
- Hotwire Native for Rails Developers by Joe Masilotti
- From React to Hotwire – An Unexpected Journey webinar from Arkency
- Hotwire for Rails Developers course by Pragmatic Studio
- Hotwire Spark: live reloading for Rails applications by 37 Signals
- Hotwired.dev
Key Takeaways
Our experience with Hotwire has been largely positive. While there was a learning curve, the benefits of simpler code, better performance, and enhanced reliability made it a great choice for this mobile-first application. The framework's approach to progressive enhancement particularly shined in our use case, where network connectivity couldn't be guaranteed.
We're excited to continue using Hotwire for future projects, applying the lessons we've learned to build even better applications. The framework's alignment with Rails' "convention over configuration" philosophy means we can focus more on solving business problems and less on technical implementation details.