Groups keyboard shortcuts have been updated
Dismiss
See shortcuts

Hotwire v React

50 views
Skip to first unread message

DAZ

unread,
Apr 23, 2024, 1:52:06 PM4/23/24
to North West Ruby User Group (NWRUG)
Okay everyone ... this 'debate' got going on another thread I started.

I've used React before and have found using Turbo frames and Stimulus to be like a breath of fresh air, especially how well they integrate with the rest of the Rails stack. 

Other people have said that it can quickly get messy and React is needed for anything complex.

Would love to hear everyone's thoughts?

Lee Hambley

unread,
Apr 24, 2024, 2:55:51 AM4/24/24
to nwrug-...@googlegroups.com
Hi Daz,

I wanted to jump in actually move the question away a bit from "X vs Y" to talk about some of the philosophy, and 2nd order consequences of such a discussion.

Starting with philosophy, Rails is _heavily_ "convention over configuration" driven, but it's a way of expressing that a bit part of what makes Rails "railsy" is that those decisions have been made for you, the thresholds for various trade-offs have been taken, and there's a large return on the investment you can get from your Rails app by enjoying the "tailwinds" by just following the status quo.

Not only is it maybe "easier" to use Hotwire, than X, but because it's the Rails preferred way, it tends to be a well-paved-road, unsurprising to Rails developers, and generally pretty smooth sailing.

That all being said, even if X were objectively better than Hotwire on a pure technical basis, at some point by adopting Rails, you are buying into the ecosystem.

Buying is a good segue into the next topic of second order effects too. The software doesn't exist in a vacuum, someone is paying for it, someone is paying (hopefully you) someone to maintain it, people will come and go, and the business this software, (whatever it may be) supports will evolve.

When considering what technologies to use in a business context, it essentially comes down to a triangle of business needs the preferences of the people involved, and the current "reality" of how the tech landscape looks right now.

Business needs first, if you're a React developer, and someone approaches you about building something, of course React-centric solutions will be foremost in your mind, after a couple of decades in the industry however we folks who've been around the block, we can see if a different setup might be more appropriate. Branding yourself as a "Rails Developer" will both limit, but enhance your access to a jobs market, it's the classic specialist vs. generalist argument, but even specialists should keep their ear to the ground and _learn_ other things even if they don't become your new speciality.

How is that related to X vs. Y question? If the business needs a prototype to get to market in a fortnight, and you're an X developer, and you are free, and they'll pay your rates, the choice of technology basically doesn't matter, but if the business needs to scale from 1,000 sales a week to 100,000 sales per week in the next 2 months by supporting mostly mobile commerce, well, then maybe your tech choices might change (hopefully they're also paying more)

Preferences of the people involved is next, assuming you're not a one man show prototyping something on the weekend for a friend, at some point you have to work with others. Ideally you work with open minded, broadly experienced people who aren't choosing to die on one or the other tech choice hill, but a "Rails by the book" shop might balk at the idea of having this whole separate X stack on the side, even if it's objectively a superior platform. Preferences go a long way, and programmers in particular are renowned for being hung up on details, tribalism and petty arguments. I specifically gravitate towards technologies where this is less of an issue, and proactively avoid software stacks where this is utterly petty. (The Scala community has a lot of this... two libraries, both doing basically the same thing in the same way, and nobody can agree if one or the other is better and people are super dogmatic about which one to use). Arguing about preferences takes away from the business needs, costs time and money and ultimately can lead to staff turnover and general dissatisfaction in the job, which manifests in frustrated, bickering people.

There's less of that than I think used to be common, but it does still happen.

The reality of the tech landscape can be summed up as "you made your bed, now lay in it". If you hired a team of React developers to build an SPA, and a team of Rails developers to build a backend, and you suffer an economic downturn and have to lay people off, and your React folks can't work on Rails and the Rails folks can't work on React, you now eat this problem. You end up halving your capacity to get things done because you chose (subjectively) "the best frontend, and best backend" technologies but now you need specialists, not generalists, and then you run into all kinds of fun situations where you now need to coordinate front-end deployments separate to your back-end deployments, and your continuous integration system now needs to be coordinated between your back and front end repository, and you now need to consider how to have the same view of your data models in the app, and on the backend, and what API technology you're using. Ohh, and you also need configuration as code for your AWS, or GCP account because they way you host the Rails app on a Docker container with nginx isn't the same way you host the frontend SPA which is now a static file server such as S3 with a CDN in-front of it with certificates and certificate rotations, and you now need to integrate all of that into the GitHub actions continuous integration too. Wait, none of this applies to you because you build a monorepo where the Rails app and the React apps co-exist in the same repo, see "preferences of the people involved", you'll be having the monorepo vs. macro repos discussion forevermore now.

In summary then, the code we end up writing, or the code that ends up being written is a small fraction of the actual result of the decisions we make. People like to say that lines of code are not an asset, they're a liability, it's like owning a building that needs constant maintenance and repair. From the pure financial bookkeeping situation it's exactly the same, and if programming were as mature as classical engineering, or real-estate we'd have better mental tools to help us reason about all this.

ps. sorry if this comes off a _little_ cynical, hyperblole is applied for artistic effect, and as a senior leader in a 150 engineer org who no longer codes all day, I see a lot of this stuff going on where we're now victim to years and years of decisions that only considered 5% of the actual impact of a choice for A vs. B :-)

Ahoy,



--
You received this message because you are subscribed to the Google Groups "North West Ruby User Group (NWRUG)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to nwrug-member...@googlegroups.com.
To view this discussion on the web, visit https://groups.google.com/d/msgid/nwrug-members/6b2f7f85-843c-478b-a326-26a07704ab0fn%40googlegroups.com.

Rahoul Baruah

unread,
Apr 24, 2024, 2:56:09 AM4/24/24
to 'Rob Whittaker' via North West Ruby User Group (NWRUG)

Sorry - a bit of a long response below.

> Okay everyone ... this 'debate' got going on another thread I started.
>
> I've used React before and have found using Turbo frames and Stimulus to be like a breath of fresh air, especially how well they integrate with the rest of the Rails stack.
>
> Other people have said that it can quickly get messy and React is needed for anything complex.

I've been building a big Rails monolith using extensive Hotwire over the last three years.

When I started out there wasn't a huge amount of documentation on how to use it and I got a bit over-excited with the turbo-stream and broadcast stuff as I wanted live updates everywhere.

That was a mistake and some bits of the code are a mess.

My biggest issue is the Broadcastable mixin for ActiveRecord models.

According to the docs, you should use them within ActiveRecord callbacks, which are quite coarse-grained.

For example, my system shows documents in folders. If you rename the document, any partials showing that document need to be updated. But if you move a document from one folder to another, the document's folder_id has changed, but the document itself doesn't need to update. Instead, the original folder needs a "broadcast removed" notification and the new folder needs a "broadcast append". So you either 1) skip the model broadcasts and do everything in controllers (which, as my system has user-configurable actions that happen in the background, will mean missing updates that should have been sent), 2) add in complex `after_commit` callbacks to your models that vary their behaviour based on attributes that have changed, or 3) pepper your model's methods with view-related code.

Another issue is because broadcasts happen outside the normal request cycle you don't have access to the `current_user`. This means that you end up sending the same HTML to everyone, so you can't show/hide bits of the views based on the user's permissions or context. Or you could add the user_id to the stream identifier, have the model enumerate every user who might be interested and send each one a unique broadcast. Or do what some of my older code does and send a broadcast that is actually a lazy turbo-frame, so it re-requests the view in the context of a normal request.

To deal with this, I've built my own observer system. I use ViewComponents instead of partials, and most ViewComponents take a user parameter (so it doesn't matter if they are rendered outside the request cycle). They then register themselves and the events they are interested in with my "Observatory" class (which in turn stores the user_id and any other model ids needed in Redis). My models' methods can send fine-grained notifications (such as folder#document_removed or folder#document_added as well as the usual coarse-grained document#updated) to the Observatory, which finds the interested components, reinstantiates them with the new state and sends that user-specific HTML only to the relevant clients.

It works and the theory of it is pretty good - but the code itself was written in a hurry, is overly complex and very messy.

It's basically the same as publishing model-specific channels sending fine-grained notifications over a web-socket. Each React (or whatever) component can subscribe to the relevant channels and update itself as needed. But in that scenario, the component state is all stored on the client so it can easily redraw itself. Whereas with the Observatory, I need to store and retrieve the state elsewhere so I can render the correct HTML.

Finally, if I were starting over, I would skip 90% of the turbo stream stuff - broadcasts and partial page updates. Turbo 8 uses morphing so full page reloads no longer lose all your front-end state. Which means as long as your controller responses are fast enough you get many of the benefits of frames and streams without the complexity. It's a shame to miss out on the live updates everywhere though.

Baz

(Stimulus is great though)

Ian Moss

unread,
Apr 24, 2024, 5:59:06 AM4/24/24
to 'Christine Wong' via North West Ruby User Group (NWRUG)
Similar, in that for rails 5 or rails 6, many projects had a JS front-end - Vue.js was pretty popular at one point, whilst react was very popular it felt like overkill for many use cases. 

I actually gave up on the front-end side, as the JS side was just changing all the time, and it was too much to keep up with. It felt like Rails 5 / 6 was a bit of a mess on the front-end, ymmv.
There was plenty of Backend / Rails API work at the time in Berlin, so no biggy. It's pretty rare that one person can be good at BE and FE, though there's much blagging of this fullstack aspect - better to understand how to interact with the customer and their needs before this IMHO. A team of 2 is still a small team afterall.

Back in the Rails 2/3/4 days I used to quite like the Prototype coupling, and ease of creating rich/interactive front-ends. However, I full got the argument that this coupling was too much. Jquery still sometimes get used. 

I slightly worry that they'll break things with rails 8 and the momentum gained with rails 7 will be lost. Lots of rails work is now done in eastern europe, phillipines, india. Not as many people using it western europe now. 

Hoping to make the Sarejevo or Romania Rails conferences later in the year. 


--
Ian Moss

DAZ

unread,
May 2, 2024, 9:04:29 AM5/2/24
to North West Ruby User Group (NWRUG)
Thanks for those replies - really interesting.

I've used React quite a bit in the past and for the past few weeks I've been using Hotwire in Rails 7 and have to say I really like it.

What I like is the fact that you can build your application in the traditional sense and it will already have some speed increases through Turbo Drive intercepting internal links and form submissions. Then you can gradually add some Turbo frames to different pages to speed things up a bit more using partial page re-renders. And the way they are integrated using CRUD feels like you're not deviating too much from the server-side mindset ... usually just a case of adding format.turbo_stream to the responds_to block in the controller.

And Stimulus is a nice little library for adding a bit more nuance to things and also uses the controller paradigm.

Overall, it feels very Rails-like and it's obviously made easier by the tight integration and helper methods.

Once you start using React, you're replacing chunks of HTML (or even whole pages) with a virtual DOM and then having to communicate with the server to keep the state in sync with the database. And you either lose the ability for it work without React or end up writing the large parts of the view code in Rails AND React.

I assume that there's been a lot of work done to make integrating React and Rails easier, but it feels like Hotwire is good enough to cope with a large number of use cases without having the extra overhead of adding another framework into the mix.

That's just my initial thoughts from playing around with it anyway!
Reply all
Reply to author
Forward
0 new messages