Pretty good article. But I'm still wondering if I really want to use Turbo. I tried it and I was just endlessly confused between streams, frames and how to do error handling etc etc.
You’re not alone…I think the docs for hotwire need two entry points:
1. (This is the current entry point): I have a rails app already, and I’m looking to progressively enhance it with a splash of turbo, responsiveness, magic.
2. (This is where something is missing): I’m building a rails app for the first time, and want to start out with a relatively high level of interactivity using hotwire. The docs don’t really offer much wisdom here, I’ve found, probably because the main adopters have all added this incrementally.
When you’re building from scratch, it’s harder to know which pattern will work best.
Just want to add my two cents: I've had really great experiences using Hotwire and rails 7 in general. The developer experience is really good and it's a fantastic toolset for building middle-complexity user experiences. You can build surprisingly sophisticated web experiences with a small amount of code and simple mental models.
If you haven't tried it, you can basically annotate your html with tagged areas, use your normal server-side rendering, and do in-place replacements / edits / updates with your normal server-side rendered pages. It's very railsy, and I mean that in the best way.
I wouldn't use it for the most demanding client-side interactive experiences, but for most use cases, it's close-to-react level interactivity for maybe 10% of the dev time.
I've done and loved at least 15 years of Rails, but not since the new Hotwire/Turbo/Stimulus releases. I've played with it a bit in side projects and it seems interesting, though I'm still skeptical that it's a good model for apps that plan to stick around for a while.
One of the things I've found difficult coming back to Rails is how spread out all of the behavior is in so many different files and partials and helpers. While SPAs have a lot of trade-off, organizing related code into components works so much better than any experience I had with server-side MVC, especially when using something like TypeScript and Remix's islands that very effectively isolate even further into logical modules. What little I've done with Hotwire/Turbo made it seem like very basic behavior is even more spread out and even harder to reason about for someone who didn't write it, which seems like it would make maintenance and refactoring in Rails even more time-consuming and perilous than it already is.
I'm really interested in the technology because I hear such glowing reviews of it, but I'm not sure I see it. I'd love to see a non-dogmatic comparison of SPAs vs Rails with Hotwire/Turbo MPA for post-MVP longer-term projects.
You hereby have permission to organize code as you would like!
I think your complaint is fair but I'm not sure it is a fault with Rails so much as I've rarely seen anyone interested in organizing their Rails code more than the default.
Personally, I think it is really helpful, especially when it's as easy as using modules or having interfaces between modules. If you want feature-based structure, I'm pretty sure you can do it but that'll be a bit more involved. There are some gems out there that support those efforts.
I've found with Stimulus/Hotwire/Turbo that separation of concerns and finely composed partials can help a lot.
I've yet to come across a project where turbo streams aren't the better approach in my day to day. Reduced code, reduced complexity, easy to reason with code that fits inside most people's head. I can't believe all the complexity people go with for a frontend app that isn't much different.
> Let’s say your app also allows promotional codes to be used, and that promo codes in your app live outside Stripe, because Stripe does not support promo codes for your type of product. What this means in practice is that before calling Stripe’s confirmPayment, you have to send a request to your server with the promo code that the user wants to apply. This request can respond in one of two ways - either the promo code is valid, or it isn’t. If it is valid, then you can go ahead and call confirmPayment. If it isn’t valid, then you need to render validation errors.
This is an extremely trivial bit of JavaScript, but it is made difficult because it is trying to use a JavaScript framework developed by people who hate JavaScript. Do the form validation on the client side to give users instant feedback and then do final validation on the server side where you enforce business rules. These are two different kinds of validation and it's not actually effort saving to try to combine them. If you have good client side validation, you can just be a hard ass on the server side because you know that anyone who gets the server side error is already bypassing client side validation, so they are being naughty to begin with. It makes like easier to keep the validation separate.
In this case, are you recommending the serverside validations (is a promo code still active and not expired) run after the call to stripe's confirmPayment, because you have a clientside validation (promo code matches a regex)? If so, that seems problematic because your severside validation could have prevented stripe from ending up in a dirty state. If not, then I'm not following what you are recommending.
I find the setup as described confusing. What is stopping a customer from just triggering the Stripe call with an invalid code? Presumably, the answer is they can do it, but after the Stripe call, the order will be rejected at fulfillment time. So, the check is just a preflight, but the real validation comes later. (Or is there a signature involved? Could be, but TFA doesn't specify it.)
Either way, you can just do a quick JSON fetch call on the client side as part of client side validation once customers type the code into the box and then pass it along to the server for the final POST.
I'm using Hotwired (Turbo + Stimulus) for my products, and it's been fantastic. The lack of client-side logic can make some tasks a little tedious, such as only showing an "edit" button on a card to certain users. But, overall the speed of development is fast - particularly for things such as infinite scroll or real-time updates.
Does anyone have opinions on htmx + Go for a similar to Hotwire? I’d imagine it’s less “batteries-included”, but I wonder if it gains some of the benefits of Go.
I've found the hotwire experience beyond frustrating. There is no offical docs, a bunch of youtube + blog posts are the only way to navigate the landscape. As opposed to similars like Livewire and Liveview. Not suprised since its a DHH special made for basecamp that he decided to open source.
If you're willing to jump the hoops of googling everything yourself and figuring out it's intricacies or better yet reading the source then go for it. The official docs are not just lacking they dont even exist.
20 comments
[ 1.7 ms ] story [ 53.5 ms ] thread1. (This is the current entry point): I have a rails app already, and I’m looking to progressively enhance it with a splash of turbo, responsiveness, magic. 2. (This is where something is missing): I’m building a rails app for the first time, and want to start out with a relatively high level of interactivity using hotwire. The docs don’t really offer much wisdom here, I’ve found, probably because the main adopters have all added this incrementally.
When you’re building from scratch, it’s harder to know which pattern will work best.
If you haven't tried it, you can basically annotate your html with tagged areas, use your normal server-side rendering, and do in-place replacements / edits / updates with your normal server-side rendered pages. It's very railsy, and I mean that in the best way.
I wouldn't use it for the most demanding client-side interactive experiences, but for most use cases, it's close-to-react level interactivity for maybe 10% of the dev time.
One of the things I've found difficult coming back to Rails is how spread out all of the behavior is in so many different files and partials and helpers. While SPAs have a lot of trade-off, organizing related code into components works so much better than any experience I had with server-side MVC, especially when using something like TypeScript and Remix's islands that very effectively isolate even further into logical modules. What little I've done with Hotwire/Turbo made it seem like very basic behavior is even more spread out and even harder to reason about for someone who didn't write it, which seems like it would make maintenance and refactoring in Rails even more time-consuming and perilous than it already is.
I'm really interested in the technology because I hear such glowing reviews of it, but I'm not sure I see it. I'd love to see a non-dogmatic comparison of SPAs vs Rails with Hotwire/Turbo MPA for post-MVP longer-term projects.
I think your complaint is fair but I'm not sure it is a fault with Rails so much as I've rarely seen anyone interested in organizing their Rails code more than the default.
Personally, I think it is really helpful, especially when it's as easy as using modules or having interfaces between modules. If you want feature-based structure, I'm pretty sure you can do it but that'll be a bit more involved. There are some gems out there that support those efforts.
I've found with Stimulus/Hotwire/Turbo that separation of concerns and finely composed partials can help a lot.
This is an extremely trivial bit of JavaScript, but it is made difficult because it is trying to use a JavaScript framework developed by people who hate JavaScript. Do the form validation on the client side to give users instant feedback and then do final validation on the server side where you enforce business rules. These are two different kinds of validation and it's not actually effort saving to try to combine them. If you have good client side validation, you can just be a hard ass on the server side because you know that anyone who gets the server side error is already bypassing client side validation, so they are being naughty to begin with. It makes like easier to keep the validation separate.
Either way, you can just do a quick JSON fetch call on the client side as part of client side validation once customers type the code into the box and then pass it along to the server for the final POST.
If I understood correctly it does. They are handling promo codes outside of stripe.
I feel like you are missing the point of the article
> This is an extremely trivial bit of JavaScript, but it is made difficult because it is trying to use a JavaScript
Yes, it is trivial javascript, and it was trivially solved by a couple of javascript lines
https://github.com/while1malloc0/hotwire-go-example
https://github.com/jfyne/live
if that's the case, there is definitely an opening on the market for such tech.
As someone who's been writing web apps since DHTML days, Livewire/Turbo feels like we've finally reached the future, although with caveats.
If you're willing to jump the hoops of googling everything yourself and figuring out it's intricacies or better yet reading the source then go for it. The official docs are not just lacking they dont even exist.