There are some pretty big key differences though. Livewire is pure ajax (at least for now, may change in the future, a rewrite is in the works), Hotwire is mostly websockets. Livewire does DOM diffing in the frontend, Hotwire does it server side (sorta? didn't dig a ton but that's my understanding). Performance characteristics are pretty wildly different depending on the usecase.
Liveview is stateful and uses websockets (or long polling) whereas turbo is stateless and uses regular http requests.
NB. I haven’t used liveview, however turbo seems much simpler on a conceptual level because of the lack of state. This comes with extra performance cost, but on my current project I’m optimising for dev productivity and simplicity.
> I'd be interested in the "how" if you'd consider creating a blog on using Hotwire with Phoenix.
Technically it doesn't involve adding or changing even 1 line of code on the back-end to make Turbo Drive and Frames work with any tech stack.
It works out of the box by following Turbo's docs and using the HTML tags they mention along with bringing in the Turbo JS library.
But for Frames you can optionally do what Rails does and add some server side code that says "hey, if this request is coming from a Turbo Frame only send the partial template as a response instead of the whole layout". That logic for Rails is here: https://github.com/hotwired/turbo-rails/blob/main/app/contro.... It's a nice to have optimization that will reduce your frame's HTML payload size but it still works without doing this.
It can be ported to Phoenix or any back-end language by using a plug / middleware to not render the layout if a specific header exists in the request. The ETag stuff could be ported over too if your web framework's web server sets an ETag header.
Streams are a bit more tricky to get working in other tech stacks since it may involve Websockets. Hopefully we start to see more examples in the future. But I believe it should be possible to pull off in a production ready way with any back-end language that has a good library or built in support for Websockets at the framework level. That means Flask, Django, Laravel and Phoenix are all good to go in this regard (probably others too but I'm not familiar enough with their ecosystems to say for sure).
Ha, oh boy. They were both magical and a nightmare when I worked with them years ago.
One company I was at was adding more and more dynamic interactions to parts of their asp.net web app. It was a messy time trying to mix jQuery, ajax, update panels, and dealing with viewstate.
Id like to propose an alternative to the alternative posed in the article:
Years ago I was tasked with building dozens of basic web forms. Immediately recognizing the inherit silliness of this task (boring, error prone etc), I built a form creation tool, which all these years later lives on as RackForms.
Over the years the feature set grew organically to accommodate an ever growing set of demands. Yes we still build forms, but we also call into web services, display data, and so on.
Point being, RackForms and any number of other form builders are the blindingly obvious choice for this task -- it would be down right silly to code forms by hand in this era.
And yet that's what we do with the web as a whole.
Once again Microsoft seems to have had the right idea in the good old Web Forms days. Instead of coding app's you'd simply drag and drop components and add wiring code to do what you needed.
Sure it was never that easy, but it's really hard to see how it couldn't have been better given more time.
Fast forward to today and as much as I adore say, VS Code, it's really nothing more than a hyper-powerful text editor. It has none of that tolling to allow for drag and drop development, Id propose that;s the real solution to this issue - Better Tooling.
That's great if you're building an internal tool, and in fact we use the Django Admin site for this, there exist low-code/no-code tools like Retool for things like this, it's a great type of solution.
Where this breaks down is anything customer facing, like Hey (the product Hotwire was built for), Basecamp, or things like Thread the product I work on. These products aren't forms, or CMSs, and trying to fit them into those sorts of solutions results in a bad or counter-intuitive user experience, even if somewhere deep down these are essentially "CRUD" applications.
I understand your point here, but I think we're a couple of innovations away from dramatically reducing the cost of UI development.
The state of the art for web and mobile app development is a delicate stack of tools that require a lot of expertise to wield. However, if you pay attention, most the complexity of modern UI development is accidental, not fundamental.
Figma already has "auto-layout", which is essentially flexbox. Imagine a world where your designer just builds your whole app with in Figma with flexbox-like constraints, then they hand off to your developer who just writes a couple of snippets code to wire it up to a database and makes sure the elements are configured to be SEO friendly.
IMO developers dramatically underestimate the power of GUI tools to usurp their role because we think in terms of such low level tools.
Oh yeah that is absolutely a direction I can see this going. But that's enabling completely custom UI/UX and behaviours per screen. It's the form-builder style generic tools that I think have limited uses in consumer software.
I've never seen anyone actually say MS got it RIGHT with webforms.
Webforms was their attempt to bring the VB6 workflow onto the web and it was a terrible idea specifically because the web is not desktop.
I get your point, but as far as I'm concerned any rationale that ends with the conclusion that MS got it right with webforms needs to be seriously reconsidered.
I'm gonna say it, then: it was pretty good tech. It worked similar to Turbolinks/Hotwire, you could make reusable components like React, it had much better benchmarks than interpreted languages at the time, and it worked very well with or without Javascript active on the browser. The WYSIWYG was nice but it would be alright without it.
What killed it was lack of community best practices. It NEEDED Custom Components and separation of concerns (using something like MVVM) for it to work well. But without a community around it (and with Microsoft's lack of interest), most people ended up writing spaghetti code.
MVC on the other hand had a large community around it developing best practices. MVC code could also be a clusterfuck if you wanted to: you could put all your logic in the view for example. The reason it didn't happen was because there was widespread education around the MVC paradigm. WebForms didn't have this.
Also it didn't integrate too well with jQuery, which was the new hotness. Today most people are smart enough not to use jQuery to mutate a DOM tree generated by a React component, but back then jQuery was the new kid on the block and people blamed the problems on WebForm, rather on the fact they were mixing two incompatible paradigms.
You're confusing webforms with the asp.net framework.
The framework itself was mostly good tech, as long as you didn't use webforms.
Probably the biggest flaw in the framework was not having a way to capture all unhandled exceptions (Application_Error does not catch unhandled asmx exceptions).
No, I'm not confusing anything. What I'm talking about is exactly WebForms. Please don't distort my words.
WebForms was good, as long as you didn't try to use it in way it wasn't intended, like doing direct DOM manipulation on top of the UpdatePanel, trying to access private state, refusing to use components or not using separation of concerns. Those are the same things that would also make React apps shitty, but the reason React works is because in React we just don't do it.
WebForms was good, but it needed the same amount of good engineering that a modern React app needs to be good, period. Unfortunately lots of programmers using it back in the day didn't have this knowledge because of lack of good documentation and good practices.
> it had much better benchmarks than interpreted languages at the time
That seems an odd statement for someone not confusing WebForms with the tech stack.
You can build applications in asp.net framework without the use of WebForms (and you could do so before MVC existed). THAT tech stack was pretty reasonable. It was WebForms specifically that was the problem.
But it did have better benchmarks. Whether it was the merit of the language, interpreter, rest of the stack or anything else is immaterial. I'm just demonstrating that it didn't have performance problems. The reason I preemptively mentioned performance not being an issue is because you are not putting forth any arguments for why you dislike it.
While we're here, cherry-picking one sentence of a post and putting it out of context to try to invalidate all my other opinions is not arguing in good faith. You seem to be trying to prove that I'm "ignorant" or something, but you're the only one displaying any ignorance here, since you're not putting forth any argument, but rather just parroting that something is crap and trying to "win an argument" using fallacies. There is nothing to be learned from your posts at all, no different perspective, no justification of your opinion, no insights into why you dislike it. You're just doubling down on a preconception that you have no justification for.
> Webforms was their attempt to bring the VB6 workflow onto the web and it was a terrible idea specifically because the web is not desktop.
As for performance, viewstate was a huge performance issue. That's a large part about what I meant when I said they tried to bring the VB6 workflow onto the web. In order to get there, they had to create the viewstate mechanisms, which created a different set of problems.
They wanted developers to be able to dragNdrop and then double click and write a small bit of code to do a thing, just like in VB6. Only, in order to actually get that to work, they had to come up with things that were actively harmful in a website (and it got worse when they tried to shoehorn ajax into it).
> There is nothing to be learned from your posts at all, no different perspective, no justification of your opinion, no insights into why you dislike it. You're just doubling down on a preconception that you have no justification for.
this is just an HN dog whistle. You could have asked.
+1, It's very rare I run into people on the internet that seem to understand this. We're all obsessed with getting our delicate stacks of tools to work together that we fail to realize we're building at entirely the wrong abstraction level.
The solution to slow SPAs is higher level frameworks and tools that compile away the slow runtime. Svelte is a step in the right direction. We have many more to go.
Honestly, I believe the role SPA front-end developer is overvalued at the moment, not because the job is easy, but because the tools are so poor. Once we see platforms that properly balance ease of use with expressiveness and composability, I believe there will be huge opportunity for development agencies to undercut the market.
Maybe this would work for simple websites. But for web apps, it's a hard pass for me. For context, I write a web-based POS application, and waiting for a network request on every micro interaction is a no-go.
There are lots of other problems with this approach that could be solved, but aren't immediately obvious, such as (similar to React) over-rendering. If someone has their focus in an input within the frame that gets swapped out, they're going to lose their focus. This has implications for accessibility as well as just regular usability.
> after receiving HTML from the server, the browser asynchronously requested fragments of HTML to dynamically alter the parts of the page to change based on user interactions or events occuring on the server.
It sounds like the quality of the resulting UX would be strongly inversely correlated with the server connection latency. On a bad connection, surely the SPA way is preferable? (i.e. many UI updates would require no AJAX)
(I only read the first few paras and didn't really take in what Turbo is)
I've started using Turbo (Hotwire) on the new version of LibHunt (https://www.libhunt.com), and it is amazing. By adding preloading to all links, most pages load instantaneously. Then, if you need to keep the scroll context, you simply wrap the area in a <turbo-frame> and everything "just works". You can experience that on the homepage by switching the "Weekly"/"Monthly"/"Stars" views of the main table.
Your site does not seem to preserve scroll state correctly after clicking back on iPhone. Go to the homepage, scroll down to repos, tap on a repo, tap back, find yourself at the top of the homepage.
Which illustrates a general problem with these kind of libraries - you need to put in a lot of effort to make them work as well as normal old old web applications. Is the performance improvement actually there, and is it worth the extra bugs and effort?
Not to pick on you either. E.g. GitHub had broken back button behavior with their turbolinks for the longest time.
Your site does not seem to preserve scroll state correctly after clicking back on iPhone. Go to the homepage, scroll down to repos, tap on a repo, tap back, find yourself at the top of the homepage.
Wouldn't an old old web application exhibit this behavior too?
I've seen this comment before when it comes to turbolinks and it is a pain but if that is what I'm giving up to avoid doubling my state with an SPA, writing a ton more code to create an api and then writing more to hook it up to speak to the backend, double error checking, losing access to my whole database when creating a page and having to create a ton of endpoints to get the data I need, etc... Then I'll take that trade.
I do think SPA's still have their usecase for when it comes to complex screens but I would like to see that screen only have the incremental complexity on it. Svelte would be my goto for that page at the moment.
It's a bit like what HEY done with their mobile app, most of the app is SSR HTML but the main inbox screen calls out to the JSON API with a native screen.
I say all this but I do love the component nature of frontend frameworks, it is nice to put things in boxes like that and have pulled in data change the view in reaction. But this new hotwire turbo frame idea sounds again much simpler where say we have a chart we want to update over time and display, in SPA world we would speak to some API change some context/store/component prop etc and let the rerender happen. With a turboframe we just make a call out to get the new updated HTML from an endpoint.
I would love some examples of people comparing and contrasting the exact same webpages + functionality with SSR + Hotwire vs SPA. Take this page for example https://nomadlist.com/ its just PHP SSR but on my initial viewing I would think this warrants a SPA.
I'm totally sold on server rendered, HTML over the wire web apps. What I'm not sold on is websockets for the transport layer.
Unless you truly need real-time, I'd argue that something like HTMX (https://htmx.org) is a much simpler and more reliable route. Simple HTTP calls keep the request stateless and give architectural freedoms that shouldn't be taken for granted.
Most of Hotwire uses regular HTTP requests. Web sockets are only used for broadcasting real-time updates. (Basically anything you’d traditionally use polling for.)
57 comments
[ 4.8 ms ] story [ 110 ms ] threadSeems like Hotwire leans a bit more towards "SPA" territory.
I though progressive enhancement was the ability of a website to accomodate no-js and max-js?
Would be great to see someone to do a rewrite of an SPA using Hotwire, haven't come across anyone making the switch yet
Adding dynamic behaviour to pages is quick and easy using the existing templating system. The stateless nature of it helps avoid bugs.
If you really need a very complex / dynamic UX then this isn’t the way to go, but for everything else, I think it’s much simpler than react etc.
Could you share your thoughts on the difference between Liveview and Hotwire.
NB. I haven’t used liveview, however turbo seems much simpler on a conceptual level because of the lack of state. This comes with extra performance cost, but on my current project I’m optimising for dev productivity and simplicity.
Or, if the source is in a public repo.
Technically it doesn't involve adding or changing even 1 line of code on the back-end to make Turbo Drive and Frames work with any tech stack.
It works out of the box by following Turbo's docs and using the HTML tags they mention along with bringing in the Turbo JS library.
But for Frames you can optionally do what Rails does and add some server side code that says "hey, if this request is coming from a Turbo Frame only send the partial template as a response instead of the whole layout". That logic for Rails is here: https://github.com/hotwired/turbo-rails/blob/main/app/contro.... It's a nice to have optimization that will reduce your frame's HTML payload size but it still works without doing this.
It can be ported to Phoenix or any back-end language by using a plug / middleware to not render the layout if a specific header exists in the request. The ETag stuff could be ported over too if your web framework's web server sets an ETag header.
Streams are a bit more tricky to get working in other tech stacks since it may involve Websockets. Hopefully we start to see more examples in the future. But I believe it should be possible to pull off in a production ready way with any back-end language that has a good library or built in support for Websockets at the framework level. That means Flask, Django, Laravel and Phoenix are all good to go in this regard (probably others too but I'm not familiar enough with their ecosystems to say for sure).
"...stream partial page updates over WebSocket"
https://hotwire.dev/
But from what I remember ... I hated this technology with a burning passion back when I was still working on D7.
One company I was at was adding more and more dynamic interactions to parts of their asp.net web app. It was a messy time trying to mix jQuery, ajax, update panels, and dealing with viewstate.
Years ago I was tasked with building dozens of basic web forms. Immediately recognizing the inherit silliness of this task (boring, error prone etc), I built a form creation tool, which all these years later lives on as RackForms.
Over the years the feature set grew organically to accommodate an ever growing set of demands. Yes we still build forms, but we also call into web services, display data, and so on.
Point being, RackForms and any number of other form builders are the blindingly obvious choice for this task -- it would be down right silly to code forms by hand in this era.
And yet that's what we do with the web as a whole.
Once again Microsoft seems to have had the right idea in the good old Web Forms days. Instead of coding app's you'd simply drag and drop components and add wiring code to do what you needed.
Sure it was never that easy, but it's really hard to see how it couldn't have been better given more time.
Fast forward to today and as much as I adore say, VS Code, it's really nothing more than a hyper-powerful text editor. It has none of that tolling to allow for drag and drop development, Id propose that;s the real solution to this issue - Better Tooling.
Where this breaks down is anything customer facing, like Hey (the product Hotwire was built for), Basecamp, or things like Thread the product I work on. These products aren't forms, or CMSs, and trying to fit them into those sorts of solutions results in a bad or counter-intuitive user experience, even if somewhere deep down these are essentially "CRUD" applications.
The state of the art for web and mobile app development is a delicate stack of tools that require a lot of expertise to wield. However, if you pay attention, most the complexity of modern UI development is accidental, not fundamental.
Figma already has "auto-layout", which is essentially flexbox. Imagine a world where your designer just builds your whole app with in Figma with flexbox-like constraints, then they hand off to your developer who just writes a couple of snippets code to wire it up to a database and makes sure the elements are configured to be SEO friendly.
IMO developers dramatically underestimate the power of GUI tools to usurp their role because we think in terms of such low level tools.
Webforms was their attempt to bring the VB6 workflow onto the web and it was a terrible idea specifically because the web is not desktop.
I get your point, but as far as I'm concerned any rationale that ends with the conclusion that MS got it right with webforms needs to be seriously reconsidered.
What killed it was lack of community best practices. It NEEDED Custom Components and separation of concerns (using something like MVVM) for it to work well. But without a community around it (and with Microsoft's lack of interest), most people ended up writing spaghetti code.
MVC on the other hand had a large community around it developing best practices. MVC code could also be a clusterfuck if you wanted to: you could put all your logic in the view for example. The reason it didn't happen was because there was widespread education around the MVC paradigm. WebForms didn't have this.
Also it didn't integrate too well with jQuery, which was the new hotness. Today most people are smart enough not to use jQuery to mutate a DOM tree generated by a React component, but back then jQuery was the new kid on the block and people blamed the problems on WebForm, rather on the fact they were mixing two incompatible paradigms.
The framework itself was mostly good tech, as long as you didn't use webforms.
Probably the biggest flaw in the framework was not having a way to capture all unhandled exceptions (Application_Error does not catch unhandled asmx exceptions).
... and WebForms.
WebForms was good, as long as you didn't try to use it in way it wasn't intended, like doing direct DOM manipulation on top of the UpdatePanel, trying to access private state, refusing to use components or not using separation of concerns. Those are the same things that would also make React apps shitty, but the reason React works is because in React we just don't do it.
WebForms was good, but it needed the same amount of good engineering that a modern React app needs to be good, period. Unfortunately lots of programmers using it back in the day didn't have this knowledge because of lack of good documentation and good practices.
> it had much better benchmarks than interpreted languages at the time
That seems an odd statement for someone not confusing WebForms with the tech stack.
You can build applications in asp.net framework without the use of WebForms (and you could do so before MVC existed). THAT tech stack was pretty reasonable. It was WebForms specifically that was the problem.
While we're here, cherry-picking one sentence of a post and putting it out of context to try to invalidate all my other opinions is not arguing in good faith. You seem to be trying to prove that I'm "ignorant" or something, but you're the only one displaying any ignorance here, since you're not putting forth any argument, but rather just parroting that something is crap and trying to "win an argument" using fallacies. There is nothing to be learned from your posts at all, no different perspective, no justification of your opinion, no insights into why you dislike it. You're just doubling down on a preconception that you have no justification for.
> Webforms was their attempt to bring the VB6 workflow onto the web and it was a terrible idea specifically because the web is not desktop.
As for performance, viewstate was a huge performance issue. That's a large part about what I meant when I said they tried to bring the VB6 workflow onto the web. In order to get there, they had to create the viewstate mechanisms, which created a different set of problems.
They wanted developers to be able to dragNdrop and then double click and write a small bit of code to do a thing, just like in VB6. Only, in order to actually get that to work, they had to come up with things that were actively harmful in a website (and it got worse when they tried to shoehorn ajax into it).
> There is nothing to be learned from your posts at all, no different perspective, no justification of your opinion, no insights into why you dislike it. You're just doubling down on a preconception that you have no justification for.
this is just an HN dog whistle. You could have asked.
The solution to slow SPAs is higher level frameworks and tools that compile away the slow runtime. Svelte is a step in the right direction. We have many more to go.
Honestly, I believe the role SPA front-end developer is overvalued at the moment, not because the job is easy, but because the tools are so poor. Once we see platforms that properly balance ease of use with expressiveness and composability, I believe there will be huge opportunity for development agencies to undercut the market.
There are lots of other problems with this approach that could be solved, but aren't immediately obvious, such as (similar to React) over-rendering. If someone has their focus in an input within the frame that gets swapped out, they're going to lose their focus. This has implications for accessibility as well as just regular usability.
That's a hard pass for me!
Certainly you need a different mindset to use this technique. If you try to do it the same way you do SPAs you will find a lot of problems of course
JavaScript thrived under the reign of JSON.
It sounds like the quality of the resulting UX would be strongly inversely correlated with the server connection latency. On a bad connection, surely the SPA way is preferable? (i.e. many UI updates would require no AJAX)
(I only read the first few paras and didn't really take in what Turbo is)
Seems about the same from a network stability side.
It moves "rendering" complexity from device to server.
On the whole - it's a huge productivity booster.
Which illustrates a general problem with these kind of libraries - you need to put in a lot of effort to make them work as well as normal old old web applications. Is the performance improvement actually there, and is it worth the extra bugs and effort?
Not to pick on you either. E.g. GitHub had broken back button behavior with their turbolinks for the longest time.
Wouldn't an old old web application exhibit this behavior too?
I do think SPA's still have their usecase for when it comes to complex screens but I would like to see that screen only have the incremental complexity on it. Svelte would be my goto for that page at the moment.
It's a bit like what HEY done with their mobile app, most of the app is SSR HTML but the main inbox screen calls out to the JSON API with a native screen.
I say all this but I do love the component nature of frontend frameworks, it is nice to put things in boxes like that and have pulled in data change the view in reaction. But this new hotwire turbo frame idea sounds again much simpler where say we have a chart we want to update over time and display, in SPA world we would speak to some API change some context/store/component prop etc and let the rerender happen. With a turboframe we just make a call out to get the new updated HTML from an endpoint.
I would love some examples of people comparing and contrasting the exact same webpages + functionality with SSR + Hotwire vs SPA. Take this page for example https://nomadlist.com/ its just PHP SSR but on my initial viewing I would think this warrants a SPA.
I really liked the simplicity of AngularJS v1.2 & StimulusJS has some of it's simplicity.
I dont know why using plain old html has become a frowned upon!! Or at least that what I've felt in my tech bubble.
https://www.hotwire.com/
https://hotwirecommunications.com/
https://www.hotwireglobal.com/
I'm going to go ahead and say I don't love the name
Unless you truly need real-time, I'd argue that something like HTMX (https://htmx.org) is a much simpler and more reliable route. Simple HTTP calls keep the request stateless and give architectural freedoms that shouldn't be taken for granted.
This and htmx have me interested in making a web UI for the first time in a while, the max-JS frameworks are a big nope for me.