 Alright. First of all, thank you for having me. This is the first time I'm giving it up on programming, so I'm a little bit nervous, but let's see how it goes. A little bit about myself. My name is Wander. I'm originally from Istanbul, Turkey. I lived in Singapore for 10 years. During the pandemic, I was in Switzerland for three years, but I love Singapore so much, so I had to come back. And during the pandemic, I started a company doing marketing consultants, and I worked with mostly startup founders to help with their marketing strategy. But during the pandemic, I also decided to learn programming. And today I'm going to talk a little bit about my personal programming journey, and then I hope they will get to hotwire the interesting part. Now, my modern web development journey was a little bit like this. I look at what's the hottest thing on the block that everybody is using, and the answer was Next.js. So I tried to get into Next.js and tried to build simple things using the tutorial apps that are available. Then I quickly found out that in order to learn Next.js, you need to know a little bit about React. So then I went into React and had to learn things like useState, which I still don't know what it is, but somehow you need to use that, apparently. Then I realized in order to do React, you need to learn about ES6 and JavaScript, which is a bit more interesting than React, but I'm not really a big fan of JavaScript. I don't like the syntax. I know I have to use it, but I don't really like it. And then after going through this entire journey, which took about three months, I decided to build a simple app. Users would be able to log in. I would save some basic information about them. There would be some authentication authorization. I quickly found out I needed to have a data storage somewhere. I needed to weigh an ORM system to access the data. I needed the authorization solution. I needed, in order to interact with APIs, I need a different solution. Apollo seems to be the one for GraphQL and so on. And I said, screw it. Sorry? Yes, exactly. And I said, screw this. I'm going back to Ruby. I said back to Ruby because I remember the time when Rails was first introduced and I was really fascinated with the whole concept of MVC and how logical it seemed at the time. And I knew this wasn't very cool to go back to Ruby, but I said, let's keep the track. It's probably going to work. So Rails also has a troubled history with JavaScript. Originally, I don't know how many of you remember, but there was this thing called Prototype.js and Script.js. Prototype.js was their version of the MVC framework that allowed you to logically organize your JavaScript code. And Script.js was a way to build interactivity on the front end. This was the first version of Rails 1. And during Rails 3, they introduced this thing called CoffeeScript, which was essentially a better-looking syntax, which compiled in JavaScript. And the whole purpose of building this was that so they don't have to write JavaScript in the first place. That's how much the Rails team did not enjoy JavaScript. Of course, there were other reasons, but at some point around 2015, they introduced TourGoldings, which I'm going to talk a little bit more in detail, and a little bit later, they introduced ActionCable, and all these signals eventually got repackaged as HotWire. And Stimulus.js, a way to organize your JavaScript, was introduced in 2018. With Rails 6, again, there was Webpecker. It was a messy implementation. The Rails team, what they were trying to do was to make Webpack workable within the Rails environment, and ideally avoid writing or configuring Webpack as much as possible, because it was a challenge for developers who are not from the JavaScript background or don't want to spend any time doing it. With Rails 7, they embraced import maps, and they completely abandoned Webpecker worlds, but they also introduced a couple of other options such as ES builds for people who are not ready to completely abandon the JavaScript compiling step. Now, how do you currently build modern web applications? What are the options that are available to you? We want the applications to be fast and responsive, but we also want a simple and productive workflow, and we also want to keep template rendering on the server, and we don't want to introduce additional complexity, which we talked about Webpecker. It was funny we were just talking about this. So this whole JavaScript world between 2010 and 2020, they went through a decade journey only to rediscover server-side rendering. The reason I put all of these up here is because hotwire, essentially, is one way to tackle all these problems at one. It's not the only way, and it's definitely not the best way, but it's the Rails way of solving these problems. Now, how do traditional web apps work? In the simplest form, there's an HTTP request that is handled by a web server and a Rails application, and the Rails application renders a response and returns it in the HTML format to the browser. Nothing surprising, right? This is the JS component approach. If we want a particular element on the page to send that request as a Ajax request, I don't know if Ajax terminology is still used, but it goes to the Rails application, and the Rails application might be returning a JSON response, and the JavaScript on the client side might be doing some processing to manipulate the DOM elements on the page or do something else, process that JSON somehow, right? This approach works, and it's quite simple, but the problem with this approach is the more components you have on the page, the more complex your code base becomes, and it becomes really difficult to manage. The third approach is single page applications, which a lot of the React world is doing now. With this approach, you can build really complex applications where the entire client side is one single page application. It's one big JavaScript bundle, and you can use Rails as a simple JSON API, which I'm sure you are familiar with this. In this example, the JSON API just returns JSON responses, and all the processing is handled on the client side. Now, the challenge with this approach is, first of all, you have to write JavaScript, and if you also maintain an API in Ruby, then you have to constantly contact switch between Ruby and JavaScript, which a lot of Ruby developers don't necessarily enjoy doing. The second challenge with this approach is state management. Now, you have to manage the state on the server and on the client side, which can become a big problem as well. There are certain apps which require this approach because there's very heavy processing on the client side that may be very difficult to solve with more traditional server-side approaches, but as a rule of thumb, you are definitely introducing a lot more complexity when you go with the SBA approach and couple it with a JSON-only Rails application. This is what brings us to HotWire. I really like, I think the name HotWire is quite clever because if you think about it, it's HTML over the wire. Their whole approach was predicated on the philosophy that JSON itself is essentially a data format, just like HTML. So why do we need to create JSON, send it, and then process it again on the client side, whereas we could be sending HTML files directly to the clients and have the HTML file snippets replaced on the client side. Now, the philosophy behind HotWire is how can we introduce the responsiveness of an SBA without the additional complexity of an SBA single-page application. The second thing that I really like and I'm going to demonstrate here is when we write Rails applications, we are using partials. Why don't we reuse these partials instead of reinventing them or instead of building a separate JSON API and then trying to recreate the same thing on the client side and duplicating code. The last one I talked about, let's just send HTML instead of sending JSON files. What is HotWire? I think this is where the Rails team needs to do a little bit more work because it is, from a marketing perspective, I find it extremely confusing and it took me a long while to figure out what the components are and that's what I wanted to share, something I've learned throughout this process. I hope you guys don't have to spend as much time as I did. Essentially, it's three things. Turbo, stimulus, and strata. Strata has not been announced. There's a Rails World Conference happening in Amsterdam in October and I think they are going to announce. This is a way to build mobile applications using Rails. I'm not going to talk about that today. So that leaves us with two components. Stimulus is a way to organize JavaScript files on the client. You can almost think of it like a version of jQuery. The analogy may not be very appropriate, but I think in our case it works. Turbo is where the majority of our discussion today is going to preside. Turbo is a set of technologies that enable you to build more responsive applications on the client side. Now, there are three parts to turbo. Turbo drives, turbo frames, and turbo streams. The first one is turbo drive. The good thing about turbo drive is you don't have to do anything to start using it. Most Rails applications by default, especially Rails 7 applications, come with turbo drive enables. The logic is quite simple. When you click a link, there's a client side JavaScript that intercepts your get and post requests and converts them into Ajax requests. And when the server generates an HTML response, the client side JavaScript looks at the response and checks it with the current heads of the HTML. And if the heads match, then it just replaces the body. So this makes the application feel much faster because it doesn't feel like a complete page refresh. And I'm going to demonstrate how that works. Short takeaway is if you don't do anything and just use turbo drive, your applications are going to start feeling a bit snappier, a bit more responsive, a bit faster. Because the head is not getting replaced, therefore the browser is not doing a full page refresh. The second part is turbo frames. This is a way to introduce partial page updates. And the way it works is you take an HTML element and you wrap it in something called a turbo frame. The way it looks is a simple HTML tag. Now, what Rails does, it creates a context specifically for this element. And when you send a request, turbo really converts that request and sends it to the Rails application and looks at the response that comes back from the Rails application. If you don't do anything, if you are using your vanilla Rails scaffold response, it returns your complete HTML response. Rails is smart enough to compare the HTML response with the entire HTML body and figure out that this request is coming from this particular turbo frame and only replace that part of the portion. Having said that, if you are, like I am, particular about the kind of response that you are returning from the server, it is also possible to only return the turbo frame portion of that page, and therefore your response sizes are going to get much smaller. There is also a component called turbo frame headers, which I am going to talk about. Turbo streams is the third component. This is turbo frames work when you scope responses to a specific element. But what happens if you want to simultaneously update two different parts of the page with one interaction? That's when the turbo streams come in handy. You can update multiple parts of a page in response to a single request. And with turbo streams, you can define what actions you want your client-side Rails application to take. You can, say, replace this part of the page or append this portion into this page or pre-panded or remove it. You basically define your directors, and then those directors get executed on the client. Turbo streams also allows you to create web socket connections and build applications that work in multiple browsers simultaneously, which is quite an interesting feature. So far so good. Too fast, too slow. All good. All right. The last part is stimulus. I didn't know how to visualize this, so I kept it very simple. Essentially, stimulus is a way to organize your JavaScript, similar to how you organize your Rails Ruby codes in the NBC pattern with controllers and actions, right? Your stimulus controllers are essentially JavaScript objects, and your stimulus actions are JavaScript functions. When the page loads, the stimulus library looks for any declarations that you have defined that there's a stimulus controller on the page. And if you have defined it, it connects to a specific element. And now you have a designated place for you to put all your component-related code into. You can say, for this particular component, I want to execute this JavaScript code, and I want to take these actions. Where does this come in handy when you want to build custom functionality, when you want to include third-party libraries using NPM and so on? This is essentially a way to organize your code. Now, I figured out one of the best ways to showcase this was to build a demo app. I'm not proud of having built yet another to-do app, but I'm proud of the fact that I managed to cram all the features into the smallest possible app that I could possibly build. So, let's give it a try. This is my do-app. Oops. And I will try swapping. This is the most simple possible to-do application. The things that you can do in this application is go to will be conference. When you click Add, it adds it to the list. You can check it as done. You can uncheck it, or you can delete it. Now, in terms of the code base, this is as simple as it gets. We have a task stable. We have a title, and we only have a boolean field that says, this is whether this is checked or not. In our tasks controller, we have a couple of actions. We have an index action that lists all the tasks, and also because we have a new form, we have this task instance. In the create controller, we just basic rail stuff. There's nothing interesting here. We just create a task, and we save it, and we redirect to the task URL with the notes. Yeah, the task might look a little bit different than what you are used to, which I'm going to explain later. We update the task, or we destroy the task. That's all there's to it. Now, I'll start with the create action, because I think that's the simplest one to talk about. What happens when we... Oh, there's one more thing I think I can show here. Application.js. Let's turn off turbo. Now we have turned off turbo, and let's open an inspector here. Let's go to the network tab. We have the fetch request and the document requests here, right? So, let's see what happens here. When we send a get request, it's a get request server returns a 200 okay response, and we look at the response. It's an entire HTML with the response body. No surprises here. This is what we expect to happen. Let's enable turbo, and this is only a helper function that adds a bar that helps you visualize turbo drive in action. Let's add one more request. Maybe it was too fast. I don't know if you saw the bar here, but let's see what happens here in the requests. So, now you see this was not a regular browser request. This was a fetch request. This was initiated by the JavaScript that was included by default interval, right? And now we look at the details of this request. If we look at the request headers, you will see something here, text slash vnd.turbostream.html. These are the request types that Rails is using in order to communicate with the application app. And if you look at the response, which is here, right? It's a standard HTML response, but Rails is smart enough to know what we want to do. And compared to the original request, it feels a lot more responsive. If I didn't set the progress bar with a one millisecond idly, I don't think we would be able to tell that this was done instantly. Now, let me show you about the updates version as well. In the tasks controller, when we want to send an update, what happens? It seems fairly simple, right? We click and something happens instantly. If we look at the code for this, this is our index page. This is a simple task rendering a collection using a partial. Let's look at the partial. Sorry. Let's look at the partial. We have a form. Ignore the controllers for now. We just have some helpers. If the task is just, we style it differently. And we have a delete button, right? So this form is essentially the form that enables us to check. I will show you why once we check it instantly submits the form. That's the stimulus part. But the interesting part here is this turbo frame tag directed. What this does is, if you go and inspect this code here, it wraps all the tasks in an HTML tag, like I showed you in the slides. That's called a turbo frame tag, right? Now, Rails knows enough that this component is a turbo frame and limits the interaction to that specific component. And the server, if you go and look at our controllers here, and you look at the update action, the server responds. If the update is successful, it just returns a task object. Now, there's a lot of convention happening here. The convention is that Rails is basically using the same partial that we have defined for tests and all creating that partial content is a server response and sending it back to define. And therefore, only that portion of the page is updated with this specific piece of content. Technically, if you're really particular about writing an app that works without JavaScript, it is possible, just like how you do, like whether you want to render a JSON or HTML, you can define your format as a turbo stream format. And you can say if the request is a turbo stream format, then return the task object. And if the request is a HTML request without turbo stream, then redirect to the task URL. And therefore, your application would work soullessly with and without JavaScript. But this is a lot more effort. And if you're making the assumption that the client is going to have JavaScript, you don't really need it. Now, once we submit this request, if we look at the network tab again, have a look and see what's happening, let's click this. The turbo frame sent a post request that's sent by fetch. And if we look at the response, because we are rendering a task object and the contents of that task object is using the same partial that we have used in order to create these, the response only includes a turbo frame. And the contents of that response is only our task object. There's nothing else in that response. Therefore, the interaction is really best and responsive. Now, the third part is the delete. This is again, as simple as it gets, right? When we click the trash icon, we delete this. Now, why did I include this? Because normally, we wouldn't have to do anything specific to the cater for this, right? But the thing is, when we delete a task or also when we add a task, we want the total number of tasks here to be updated. So we actually want two things to happen. The first one is we want this row to completely disappear from our DOM in addition to the database. But we also want the total number of tasks to reflect our actual task count. Now, Rails has a few conventions to help us with that as well. How that works is, if we go to our views and if we go to our tasks, you will see something quite interesting here. Destroy the TurboStream.erb. This is very similar to how you would write new.html.erb, if you look at the file format, right? What this means is you can declare TurboStream actions just like you were writing an HTML code. And in this case, we are just giving two directives. We are saying, updates the task count using the partial from the tasks folder and the count file and also remove the task item from the task list, right? So, when we do this, it sends a response that removes this line, but it also sends another response to update this count. What does that count look like? It looks like this. It's just a helper method and it's just a tiny snippet that shows the latest count. What does the server response look like if we open the inspector again? If we look at the network now and if we click delete, we sent a post request. Let's look at the response, right? There's a TurboStream action that says updates and there's a task count with the template that we have provided and the number that's here is from the task count helper method and number happens to be seven. And the second action is remove this and it's sending an ID. This test slash test underscore eight is the ID of the test and how is this ID is generated is the TurboFrame tag helper that we have initially defined inside the partial. So, just like everything else in Rails, as long as you stick to the Turbo conventions, your life is really easy. But what happens when you want to go outside the conventions a little bit and introduce your own functionality? This is what I skipped earlier a little bit. Normally, when you use a form helper to write your own code, which is what I did initially, you would write something like onChangeThis.Form.Submix or something along those lines, right? The JavaScript directive inside the helper or you would write it as a HTML without using any helpers. Whereas, what I've done here is to use something called data and define an action and the format of this action looks like what's the action that we want to define? Which controller do we want to use and what action within that controller do we want to take? And all of this is referring to a stimulus controller, which is essentially a JavaScript file called task controller, not JS. The controller format is like this. It inherits from the hot wired stimulus controller class and it essentially exposes a few methods. One of these methods is connect. Every time the page gets initialized and your stimulus controller connects to an element, this connect method runs. I just put it here to demonstrate. We are not really using this method. There are a couple of other callbacks that you can use, but not necessarily useful right now. The only action I have defined is submit. And in the submit, I have just said submit this form. This is as simple as it gets in terms of actions, but I think there's a job of demonstrating what you can do. This is where you define all different actions that you can take. And within your HTML, you can declaratively define which actions you want to run as a result of which user actions get triggered. And this essentially is stimulus. There's a lot more to stimulus than this, but this I think does a simple job of explaining. Now the last thing I want to demonstrate today is one of the cool features of this. Let's try to zoom out a bit. And let's look here. So what happens if I go and check this one? It gets updated on the second browser as well. And what about by deleting? It happens on the second. How does this happen? This is using TurboStreams. This is the last feature that I mentioned. By using ActionCable under the hood. And ActionCable is Rails' way of handling WebSocket connections. And if you go in and look at the network panel again, and if you look at the WebSockets, and if you refresh the page, you can see a little bit more detail on what's really happening under the hood. There's something called Cable. And what it does is it initiates, when you load the page, it initiates the WebSocket connection by sending a subscribe message to a TurboStreams channel. If you are wondering how do I enable this in the first place? It is as simple as defining a TurboStream from AlperMessage and giving it a unique name. Now there's a lot more to this, obviously, if you want to create private channels and if you don't want everyone to be able to get updates for every interaction that happens, you can customize this. But this is the simplest version of how that works. And every time we take an action here, there's another message that gets triggered here, which includes a TurboStream action and a target and a template. So the underlying technology is essentially the same as the previous TurboStream example that we have seen. But the way it gets communicated is by using the WebSocket connection that's enabled by ActionCable within Rails. All right, so how do we start using this today? If you are using Rails 7, this already comes by default. You don't really need to do anything else to start using TurboDrive. It's already included. And TurboFrames and TurboStreams, you can go and read the documentation and start using it today. With Rails 6, there are two gems, the TurboRails gems and StimulusRails gems. You can install these gems and start using them. In other non-Rails applications, you can still use them by using the NPM package versions of these. You would lose out on the conventions, but it would still work in a similar way. Now, if you want to learn more about this, obviously, you can read the official documentation. I personally find it a little bit bland and for me personally a bit confusing, but maybe it's a bit easier for you. Some of the resources that I found quite helpful, the HotWire for Rails developers that pragmatics could be as a very good online course. I think they even have the parity discount for people based in Singapore. I highly recommend taking this course. It's helping me really understand what's going on. There's an online tutorial called HotRails.dev, which is also quite good. I would recommend it. The HotWire, there's newsletters. I don't know if you're familiar with John Nassalotti. He's quite active in the community and he runs a very good newsletter with all the HotWire news. There's a lot of useful resources, articles and stories in each episode that gets sent out. And the last one, if you're curious about the job market, someone I know that lives in the US started a job bot specifically for HotWire jobs. So you can take a look at what kind of skills that people are looking into. Thanks so much for the opportunity to share as the least experienced Ruby developer here. I'm on LinkedIn if you want to connect. I stop using Twitter, so I'm on most of them as well. I have a website where I don't really post and I have a company if you want to learn or talk about marketing at all, you can find me. Thanks so much.