bouncer
← Back

Ruby on Rails · 5.1K views · 163 likes

Analysis Summary

30% Low Influence
mildmoderatesevere

“Be aware that the speaker is a published author on Hotwire; while his technical advice is grounded in experience, he has a professional and financial interest in the framework's success.”

Transparency Transparent
Primary technique

Performed authenticity

The deliberate construction of "realness" — confessional tone, casual filming, strategic vulnerability — designed to lower your guard. When someone appears unpolished and honest, you evaluate their claims less critically. The spontaneity is rehearsed.

Goffman's dramaturgy (1959); Audrezet et al. (2020) on performed authenticity

Human Detected
98%

Signals

The content is a recorded live technical presentation featuring personal storytelling, specific industry references, and natural conversational flow that is characteristic of human expertise and live public speaking.

Personal Anecdotes and Humor The speaker jokes about a friend not reading his book and references specific interactions from the previous day's keynote.
Natural Speech Patterns The transcript contains self-corrections, conversational transitions ('Well, at Halal booking...', 'Which is annoying for two reasons'), and contextual awareness of the physical event (RailsWorld).
Contextual Relevance References to specific conference speakers (Joe Mazzolotti) and the specific venue (RailsWorld) indicate a live, human-delivered presentation.

Worth Noting

Positive elements

  • This video offers a highly practical, code-adjacent explanation of how to use Turbo Frames and Streams to handle complex UI patterns like infinite scroll with server-side sorting.

Be Aware

Cautionary elements

  • The speaker uses his technical authority to subtly delegitimize alternative frontend architectures as 'hostile,' potentially narrowing the viewer's architectural perspective.

Influence Dimensions

How are these scored?
About this analysis

Knowing about these techniques makes them visible, not powerless. The ones that work best on you are the ones that match beliefs you already hold.

This analysis is a tool for your own thinking — what you do with it is up to you.

Analyzed March 23, 2026 at 20:38 UTC Model google/gemini-3-flash-preview-20251217 Prompt Pack bouncer_influence_analyzer 2026-03-08a App Version 0.1.0
Transcript

Legacy, it has as a word, it has multiple meanings. If we look it up in a dictionary as an adjective, it has the usual negative meaning that comes to mind when we talk about software systems. It means a an outdated computer system. But if you look at it as a noun, it has a sort of more positive spin on it. It's something we've inherited from the past and this also reflects the values in terms of software development. If we look on the negative side, legacy systems are often convoluted, complex, outdated, they have high entropy, they are slow to develop in. In other words, they are hard to work with. On the other side, they generate value, they have an established user base, they solve a real problem, they've been battle tested. In other words, they're valuable. And this is the reason why we still work with the legacy systems. If we only had the negative parts, we would have long ago put the system out of its misery and moved on. And Hotwire makes a promise of lowering complexity, increasing productivity and allowing us to focus on delivering value. Which sounds perfect for amplifying the good parts and inhibiting the bad parts. But you might be wondering, can it help a legacy Apple? Because after all, Hotwire is easiest to use if you start a new app with it. Well, at Halal booking we were not in the perfect spot, but we still benefited. And let me tell you how. My name is Radhan Skoric, I come from Zagreb, Croatia and I'm a lead software engineer@hlalbooking. com, a large travel website. And we wanted to move to Hotwire. Now at this point I actually have to pause for a moment. Turbo frames will be mentioned a lot in this talk. They were very, very useful. And I showed the talk to a friend who is not that familiar with Hotwire and at the end of the talk he went, so wait, what are Turbo frames? Exactly. Which is annoying for two reasons. One, I wrote a book about Hot wire and he clearly did not read it. The other reason why it is annoying is that he was right. This is a Rails conference, not a Hotwire conference. And I can't assume that you are familiar with that. Luckily, at a previous event I did a lightning talk on the topic of Turbo frames and I had enough buffer in the presentation at that point, so you get to see it. I adapted it for Rails World, of course, keeping it professional. I wouldn't want to just wing this. And it talks about Hotwire. Hotwire consists of three Turbo, stimulus and native. Turbo is the part which is responsible for integration with the backend. It's where most of the things which are magical lie. Stimulus is a delightfully simple front end library that stands on its own, but also happens to work very nicely with Turbo and Native is for native apps. If you missed Joe Mazzolotti's keynote yesterday, watch it when it comes out. He covers it in great detail and wonderfully zooming in on Turbo. It consists of drive streams and frames. Turbo drive is what takes over the page life cycle injects itself and where most of the magic lies like full page morphing streams are like little commands that the server can send to the front end and the front end then executes and frames is what we'll have a closer look at. Let's imagine that we have a page which is displaying a geometric shape for no other reason than that it looks good on a large slide and the pages are connected so you can browse through shapes of increasing complexity and it's just a series of plain HTML pages which are connected. But let's imagine now that you want to take those pages and put them inside another page so you can browse the shapes inside another page. At this point you might reach for a JS widget in whatever library, or you can mark part of the page as a Turbo frame and tell it to load the other part of the website. Because conceptually what Turbo frames do is they allow you to take a part of the website and then squish it inside another page, which makes it look like an spa. And then you can browse through the shapes as you go along. And here's the thing about Turbo frames, they're very easy to introduce. They don't make any assumptions about the page, the technology on it. They will work with whatever is there. They won't break anything. You can add the rest later if you want and they deliver value quickly. And I write about this on my blog@radon. dev and I also published a book about it at masterhotwire. com back to the original presentation. So online examples are on fresh apps, but I was tasked with migrating a legacy application. Here was the state of affairs at Hall Booking when we started the presentation, large part of the front end was in React. Well, React using clojurescript if you're if this seems odd, it's not actually. React is functional in its nature. Clojurespt is functional in its nature. If I was to use React, which I'm not inclined to do, but if I was, I would look at this pairing. It's a nice pairing. There was also some CoffeeScript and some unobtrusive JavaScript if you remember that. By the way, I like it when I come into a legacy app that looking I can date when certain features were introduced to the application by just looking at which front end technology it used to. I think this is how geologists feel when they take a slice through the rock and then look at it. But I digress. An important thing about Halal Booking is that it's a travel website, which means that content naturally has to be consumed from the server. It's very content heavy. So what happened is that there were already cases of reaction components consuming HTML from the server and rendering it inside React ui. And this makes sense. The user is essentially exploring a large collection of content and that has to come from the server, which made some parts very easy to migrate over. For example, certain parts of the page are just content which is loaded after the initial load. So you load the page and then you go for more content. It's a very common pattern and, and that mapped very cleanly to Turbo like you saw in the embedded lightning talk, that you can put that into a Turbo frame. Other parts were not quite so trivial, but still pretty straightforward, like for example, login registration flow in a React app. That would be a series of components. But if you look at it, it's just HTML forms with some links, which is a separate side of the website. It could be standalone pages. You've just taken them and you've shoved them into a model and the model is just a Turbo frame. And I want to point something out here and that's that I wasn't using TurboDrive, I couldn't use TurboDrive, nor could I use full page morphing, the big feature of Turbo 8. And if you're looking at a legacy application and you're thinking oh, should we go over? You might like hello booking, have a lot of pre existing JavaScript which assumes a full page life cycle, which Turbo takes over. And it seems daunting what to do with that. Well, it turns out that most of the value of Hotwire is delivered by Turbo frames, Turbo streams and stimulus. And these technologies make no assumptions about your website. They will work in whatever hostile environment you throw them in. And to drive explain why that is, let's look at a little bit more complex example. Halal booking search. Like most searches on travel websites, you have a large number of options you can select from and then you get results which are sorted in a certain way. And in Halal booking case, browsing is implemented as an infinite scroll. So you're going down the list, and as you get to the bottom, more content is loaded. And implementing an infinitely scrollable list in Turbo is very straightforward. Turbo frames it works like this. You have a Turbo frame which loads the first page. Properties are listed in it. At the bottom of it, you just put another Turbo frame for the next page and mark it as lazy loaded. What this means is that Turbo will load its content only when it enters the viewport. So as the user is scrolling down, they get to the bottom, the Turbo frame enters the viewport and it's loaded. And that Turbo frame then has another frame inside it, and so on and on until you get to the end of the list. There's a bunch of stuff you can put around it to make it nicer, sort of put bells and whistles on it. But the essential mechanism is this. That's the essential mechanism. However, there is a problem. That is the unavailable properties. Now, properties are sorted, but you want to show first the available ones and move the unavailable ones to the end of the list, because that is what the users are interested in. And the problem is checking availability is slow. Here's the thing I wasn't aware of until I started working on a travel website is that it's incredibly hard to cache results. And the reason is first, dynamic pricing. The price can change in a very short period of time. And also you can't even if searches are close to each other in time, you can't assume the result from one search to the next. Because if somebody has booked, for example, six days and then they add another day, some promotion for a week long stay might kick in. And then suddenly the prices and maybe even the availability of a room changes just because of that. So you can only cash for a short amount of time. And then also remember, there are a lot of options. So chances of two users, even if you have high traffic, chances of two users coming and making the exact same query within 15 minutes or 30 minutes are diminishingly slow. So caching on the server, you get a very, very bad hit rate. So what you do if you have a react app is you are pulling 20 properties at a time. The server checks those 20 properties, it goes all the way to the sources, to other providers or hotels, even directly gets the prices and the availability sends that to the front end. The front end, then react, front end would look at the JSON payloads, take the available ones, render those immediately and save the unavailable ones into an array that it then can pull from later. And we wanted to solve this in a similarly elegant manner. But still stay true to the hot wire principle, still keep the logic on the back end so that we can reap the rewards. And we went through a few iterations and landed on something that I will explain to you just now. So the frame is loaded like we saw before on the left. And as the server is rendering as HTML, it's just rendering HTML. If the property is available, it renders it normally. If it's unavailable, it wraps it in a little turbo stream append action, which is a default turbo action which just says take the content that's inside the turbo stream and append it to this div that I'm giving you as a parameter. In our case, we created this unavailables div and made it hidden and we're putting the properties in there. Essentially we're creating sort of like a very, very local cache that's right there inside the HTML, inside the browser. And the server just needs to track how many properties are in the hidden div. Just one number. And as it's going to the list as the user is scrolling, if the server gets to the bottom of the list, there are no more available properties. But it knows there are still properties in the user browser that it could show. At this point it starts returning Turbo stream pop actions. And this is a custom turbo stream action we added, which was just a few lines of JavaScript, which takes the target div and then does the opposite action, takes the first child of the div, takes it out and then places it in the place of the turbo stream action. And we've got our solution. At this point you might be wondering why you're doing all this. Why not just slap a stimulus controller, put the logic on the front end and be done with it. Well, by going through this, making this solution, we kept the benefits of Hotwire, the rendering is on the back end. All of the logic of the rendering, but also the logic of the ordering and the logic of the presentation. The front end is just a very low level tool. It makes almost no assumptions. And the benefits of making ingest HTML with the logic on the server became apparent relatively quickly when a colleague who was not involved in the migration at all had a ticket where when the site is rendered inside the mobile app, at some cases they had to insert a little banner asking the user to rate the app in the middle of the property results. And if this was a whole pipeline where a bunch of logic was on the front end, then you would have to kind of modify the whole path as the data travels to send a special payload that Says, oh, instead of a property, this is a special case here. I was very happy to say, well, how you want. It's just a server template and it's just HTML. So he opened the template, he saw that there's a loop that's rendering the properties, and then he just broke the loop in two parts and then under certain conditions just rendered this HTML. And the front end didn't have to change at all. He didn't have to understand the whole stack, he didn't have to figure out what's happening on the front end. He could just modify the HTML that's rendering and everything else just work. And the key reason why it worked is because we eliminated a lot of assumptions from the code. Hotwire itself doesn't make many assumptions. That's its beauty. That is why it's so versatile. And by leaning into that and eliminating assumptions from our own code, we were doing good engineering. It's good engineering for Hotwire. It's good engineering when we do it. It's just that Hotwire supports it very elegantly. And this is also why I decided to show this example. I don't think that this particular pattern is something that can be widely applied and that you should all now memorize it, but what can be widely applied is the underlying principles of seeing how you can stay within the concepts of Hotwire, how you can push the logic to the back end, and how you can eliminate assumptions from your code. And as I was doing this, I was overall removing code. And I know, I know lines of code is a very poor proxy for complexity. In this case, it happened to match the subjective judgment of people working on it. And in some cases I was removing a lot of code, like in simple ones. But even in the case of search, I was removing some code and I was wondering how was I getting less code? If this was JavaScript, I could make a case for the fact that Ruby is just more expressive than JavaScript just by nature of it. But this was Clojurescript and Clojure and Clojurescript by extension, when you look at it, can quite often be even more dense than Ruby when it's written well. And this was well written closure script. And I was asking myself, what's the reason for that? And after thinking about it for a bit, I realized that the key question to answer is where is the complexity in case of halal booking? The complexity lies in digesting this sea of content and presenting in the right place. And the source of the complexity is entirely on the backend. So what we were Doing is we were simplifying code by moving it to the back end. We were moving the logic closer to the source of complexity. Hotwire is not magic, it just enables you to move logic to the backend. If that's also where the source of complexity is, then naturally part of the complexity vanishes. And for most applications this is exactly where it is. You don't get to grips with complexity by putting barriers and walls and building trenches in front of it. It always finds a way, it always breaks through, it finds a leak, comes through and eventually gets there. Instead, what you want to do is you want to get up close to it, get really personal with it, and then dance with it. And if you're experienced, you will lead the dance. And to explain what I mean more, let's look at another example map search, which was more complex. It's a regular map search where you've got the same filters and you've got the list is the same on the left and you've got it's just scoped to what is seen in the map. And map search has a problem. If you zoom in and out, the list changes sort of arbitrarily. Things can disappear from anywhere in the list. It's not just a simple case of, of appending to the end of the results. And this is more complex. And it was kind of harder to find a solution and keep all the hot wire benefits. So we ended up on a sort of compromise and let me explain. So there are a few stimulus controllers here. There is one around the map, there is one around the list of properties, and there is one around each property. And when you pan or zoom, the one around the map gets the list of visible IDs and then passes it on to the list of properties. And the list of properties now inspects the HTML. It doesn't inspect the HTML directly, it communicates with the property controllers through a feature of stimulus called outlets. And what it does, it goes through the list of properties, it hides what is visible, it shows what was hidden and is now visible and calls the server with a list of what is missing. The then takes that list. The server responds with an HTML, it takes the list, goes through the list and merges the two lists and it uses a data attribute to define the order. In this case we got some of the benefits. The rendering is still on the back end, the order is controlled from the backend. But some of the logic of how it's actually presented has moved to the frontend and map complexity in increased slightly. Again, disclaimer lines of code, not a good proxy. It matched the subjective judgment. And by the way, if you're trying to do the mental math of that, let me save you the trouble, it adds up to 10. It didn't increase by a lot, but it did increase slightly. And the reason is simple. This particular problem fits the reactive style very nicely. And you might be wondering why not just do the map in React? Hotwire certainly does a great job allowing other solutions to coexist. In our case, the answer was kind of boringly simple. It was just not worth it. In our specific case, it's just one component. Why drag in another framework just for this one case, if there was more components we would consider it. We were essentially making a trade off. One thing got more complex and the rest got simpler. It's a pretty good trade off. Again, worth repeating. We were optimizing for the source of complexity. There is no silver bullet to managing complexity. Hotwire doesn't claim nor wants to be a silver bullet, and that's something I really like about it. It just happened to hit the right spot for most real world apps. But by deciding not to add another framework, you also gained a technical simplicity of the tech stack. It allowed our developers to be more sort of real full stack developers. Because let's be honest, most people that say they are full stack and that definitely counts me mean I'm actually backend and then I know a little bit of JavaScript and CSS. Like I know when you say you know prototype what that means. But the only thing that anyone really cares about when you say full Stack is can you deliver this feature on your own? Nobody really cares about the technical details. That's really important. Like if you sit down can you actually deliver the entire feature? And I can't go deep on both backend and frontend. I can't be great at backend and then also master React, but I can master Hotwire, which accidentally is the title of the book. If you're interested, Rails World will give you a discount if you type it in, but Hotwire allowed me to stop lying about being full stack and then actually deliver that feature. In summary, always optimize for the source of complexity. Ask yourself if is it on the back end? If it is on the back end, recognize that Hotwire moves logic closer to the backend and that frames, streams and stimulus do the bulk of the moving and that they work nicely with any other technology. They are very, very resistant, which makes them very suitable for retrofitting on legacy. Thank.

Video description

Is Hotwire only for greenfield 'rails new' projects? Absolutely not. In this #RailsWorld talk, Radan Skoric shares his experience migrating HalalBooking.com, a large hotel booking platform, from a React-centered stack to Hotwire—and the huge boosts in developer experience and performance that followed. Through real-world lessons and concrete examples, he shows why Hotwire is not only viable but powerful for mature applications. #RubyOnRails #RailsWorld #Hotwire #DX #frontend #React Thank you Shopify for sponsoring the editing and post-production of these videos. Check out insights from the Engineering team at: https://shopify.engineering/ Subtitles (Japanese, Spanish, and Brazilian Portuguese) thanks to Happy Scribe, a transcription service built on Rails. https://www.happyscribe.com/

© 2026 GrayBeam Technology Privacy v0.1.0 · ac93850 · 2026-04-03 22:43 UTC