11 ms·
Can someone genuinely explain to the the desire/interest to use HTMX/Hotwire/LiveView etc? I was writing web apps when rendering templated HTML views on your s
by gavinray 5y ago
Can someone genuinely explain to the the desire/interest to use HTMX/Hotwire/LiveView etc?
I was writing web apps when rendering templated HTML views on your server was standard, and you had controller endpoints that returned HTML content, or things like Rails "Unobtrusive Javascript" where you had code like:
$(‘#user-list’).html(“<%= j render(‘index’, users: @users) %>”)
As an automatic callback to some action.
Whether or not you love or hate this model of development is irrelevant, because if at some point you need to render on a client other than a browser -- you have to start from the beginning and write an API now.
IE, so that your Android/iOS app in Java/Swift or whatnot, can ask your backend for data and render it using the tools available on that platform.
When we turned apps into pure API's and just exchanged data with them, it opened up the ability to be platform-agnostic.
I guess I don't understand why someone would choose to build an app that sends HTML over the wire instead of JSON/XML/whatever, that any client can render. All it means is that you have to write this functionality later when you want it, in addition to now having this HTML stuff.
- interactivecode 5y agobecause you still want server rendered html? because you focus on building websites? Being platform specific makes it easier to have a higher quality and integration on that specific platform.
- gavinray 5y agoI build exclusively web apps and I still use the backend as an API. You fetch data from the API and render it with JavaScript. React, Vue, Svelte, Angular, Alpine, pick whatever. Not sending HTML over server endpoints, or using templated views like ERB/EJS/EEX/etc doesn't mean you inherently have a worse quality app. If you do this in something like Next.js with "getServerSideProps()", it's functionally equivalent. React even went so far as to make "Server Components": https://reactjs.org/blog/2020/12/21/data-fetching-with-react-server-components.html https://reactjs.org/blog/2020/12/21/data-fetching-with-react...
- roywiggins 5y agoIf you render everything with JavaScript then HTMX is not really going to be useful at all. It's useful for developing apps that simply don't need the sort of complex client-side interaction that those frameworks enable. The article points this out- if you want to write a SPA in React, HTMX is not going to help at all. But if you want a mostly-server-rendered page with some AJAXy interactivity, HTMX is much much easier than trying to shoehorn in some client-side rendering just for the AJAXy bits. The main thing is is that there is still a substantial demand for tools that let you mostly avoid writing lots of JavaScript, whether on the server or the client.
- gavinray 5y agoThis is a super valid answer, thanks. Psychological bubble from the sorts of apps I build I suppose, I hadn't considered: > It's useful for developing apps that simply don't need the sort of complex client-side interaction that those frameworks enable.
- sodapopcan 5y agoI feel like I gotta call out the LiveView is a bit in a class of its own. HEEx is rendered on the server, but the diff sent over the wire is the absolute minimal diff it can be with a map of where it in the DOM. Often this is just text. LiveView also gives you a running process on the server (a virtual machine process, not a linux process) that holds the user's state (like if they're logged in, for example) and makes things like "who's online?" and other concurrent features almost trivial.
- deleted 5y ago[deleted]
- senko 5y agoYou build web apps. The parent talks about web sites. Not everything on the web is a full featured interactive application, this is exactly what they're talking about.
- czue 5y agoThe need for a native mobile app (or any kind of platform-agnostic behavior) probably negates much of the value of these stacks. That said, many projects don't have or need mobile apps, and many more can probably get away with a web-first mobile app. For those apps this stack can vastly simplify and streamline development
- gavinray 5y ago> That said, many projects don't have or need mobile apps, and many more can probably get away with a web-first mobile app. To me this is like building a house that can never be expanded, instead of starting with an open-ended design. > For those apps this stack can vastly simplify and streamline development I guess this is an opinion/subjective? I am very open-minded and experimental. I love trying new things. I've tried these technologies (HTMX, it's precursor Intercooler.js, Turbolinks + Hotwire, LiveView, etc) and for me they are less productive than the ways I know how to build API-first, JavaScript web apps. Have nothing against them, just genuinely having a hard time seeing the appeal.
- nauticacom 5y agoI've tried these technologies ... and for me they are less productive than the ways I know how to build API-first, JavaScript web apps I think I feel the same way you do, except the other way around. I genuinely can't understand how you build apps productively with a separate client/server model. How do you do form validations? How about authentication and authorization? What about a consistent domain model? Is there one copy of it on the server and one on the client? Or does your client just treat everything as dumb data and make network requests for every question of business logic? What about data consistency throughout the interface—when you update e.g. Document(id=45) with new data, how does that update get propagated to every other place in the app? Does that involve a client-side identity-map? Or are you manually trying to send updated data to other places with callbacks/whatever? etc. for ever and ever. Every time I try to build an app where the frontend and backend are split into a separate client and API, it ends up adding so many more considerations and so much more complexity than the traditional model. Mostly because now everything that just required a database query or method call before now also requires a network request, but also because data consistency in a long-running app is so hard to get right.
- ethnt 5y agoDepending on your architecture, an API or rendering HTML is an implementation detail, rather than the meat of the application. Have your business logic elsewhere and have the API or controller endpoints call out to those and just do the business of rendering JSON or HTML in the controllers. (I think this is inversion of control, someone can correct me if I'm wrong)
- dnautics 5y agocan't speak for the others, because they are still stateless, but LiveView is stateful and this is the point, you're not constantly rocketing perfectly good content into the trash can; it's essentially a "content-aware cache layer": https://www.youtube.com/watch?v=XhNv1ikZNLs&list=PLqj39LCvnOWYTNs1n3ZNMSNO3Svv_XweT&t=2450s https://www.youtube.com/watch?v=XhNv1ikZNLs&list=PLqj39LCvnO...
- roywiggins 5y agoIf you already have an app with no AJAX going on, HTMX is hugely helpful in progressively bringing it in. You just provide endpoints for the forms or other pieces of pages that need updating, and wire them up to the page with the right HTMX tags. Even starting from scratch, it can be very productive to keep all your HTML in one place- eg Django templates- and use HTMX and a sprinkling of JS to provide client-side interaction. You can jump straight into laying your app out without building the whole thing up as platform-agnostic APIs first. When you need API endpoints you can start adding them based on the context objects you're providing your Django templates, since all the information is in there anyway. There's real benefits to putting all your presentation and most of the logic on the server. And keep in mind that many web apps will never ever need to also be a native app.
- acdha 5y agoFirst, many sites do not need a mobile app — people who sell apps like to present that as a requirement but there large categories where it doesn't make sense and most users won't install it because it takes space on their device and they [correctly] fear ads, notification spam, and possible invasions of their privacy. I've seen figures for this where pretty well-known organizations spent millions on the app and then saw install rates under 10% with most users opening it only once or twice. Second, this is something of a false dichotomy: if you have a website, you need to have HTML somewhere. One approach is to use an SPA but that increases the cost somewhat significantly and absent a significant engineering effort will reduce performance and reliability because you are moving functionality out of a high-performance data center where you control everything onto the users' devices where you have to work with whatever browser and extensions/ad blockers they have installed. An alternative approach is to render HTML on your servers — quite possibly using the same JSON API as the source — and then progressively enhance it with the functionality which makes sense to do on the edge. This gives you a hefty performance win for the initial page-load times, helps with things like search engines, and ensures that your users get at least the basic experience when something goes wrong with client side JavaScript (network errors, browser compatibility issues, ad blockers, etc.) rather than nothing working at all.
- 0des 5y ago> First, many sites do not need a mobile app — people who sell apps like to present that as a requirement Yes, Testify! Also, I'd like to mention, so many of these upsold apps end up being a wrapper around the normal web view. I've seen this being advertised/proposed as a plus, as well "No need for your customers to learn a new interface, we specifically engineer your app experience to be just like the web experience". It's interesting to see heads nodding in reply to this.
- acdha 5y agoOh, yes — definitely saw those. My favorite were the ones in the pre-WKWebView era where the app was basically the website, except slower because it didn't have the JavaScript JIT enabled.
- 5y ago
- dagw 5y agoyou have to start from the beginning and write an API now. Is it really that much more work? Much of the time the big difference is just be replacing return render(my_template, my_data) with return to_json(my_data)
- acdha 5y agoA few years back, I implemented this as a Django CBV which worked quite well: https://github.com/LibraryOfCongress/concordia/blob/main/concordia/api_views.py https://github.com/LibraryOfCongress/concordia/blob/main/con... That handles a few things like pagination for list views, calling get_absolute_url() on objects in the template context which have that method defined, and running all URLs through request.build_absolute_uri().
- deleted 5y ago[deleted]
- recursivedoubts 5y agoBecause of the simplicity, flexibility and power of the hypermedia programming model. - simplicity: e.g. something like active search can be implemented with a few attributes: https://htmx.org/examples/active-search/ https://htmx.org/examples/active-search/ - flexibility: e.g. because of the uniform interface, versioning is much less of an issue - power: e.g. deep linking is trivial Additionally, there is increasing awareness[1] that Application APIs and Data APIs have different needs and "shapes", and, once you have split them up, reconsidering using hypermedia for your application API[2] is a reasonable thing to do [1] - https://max.engineer/server-informed-ui https://max.engineer/server-informed-ui [2] -https://htmx.org/essays/splitting-your-apis/ https://htmx.org/essays/splitting-your-apis/
- lhorie 5y agoWorth pointing out that HTML is more ubiquitous than you're making it out to be: just plop a WebView in your native app, and you're done. I know, for example, that the Uber app does webviews in some places; you probably wouldn't even be able to figure out where just from looking at it as a user. Another case in point: is your dev team going to support PSP devices[0]? [0] https://shkspr.mobi/blog/2021/01/the-unreasonable-effectiveness-of-simple-html/ https://shkspr.mobi/blog/2021/01/the-unreasonable-effectiven...
- andybak 5y ago> because if at some point you need to render on a client other than a browser Been doing this for decades and this has cropped up so few times I can't actually think of any. Your clients might not be my clients. Your projects differ from mine. Don't generalise from your own experience. There's a lot more websites than there are apps.
- javajosh 5y agoThis is a specific example of a class of problems I refer to as "Where the indirection go?" In this case, the indirection is in the form of a function that takes structured data and produces html. That function can execute in the server, or on the client. Which we can term moving a function "closer" or "further" from the client. This is easier to imagine with isomorphic javascript code, but it applies to anything (with an extra translation step as you cross the network boundary). What you've discovered is a general property of systems that you want to keep your entropy low for as long as possible, and defer the final boost in entropy until the last possible minute. This keeps your options open. It also means publishing low entropy APIs and boosting in the client. In your case, you've correctly noted that it allows you to support different clients more easily. There are 3 reasons to pay the price to boost entropy on the server: to intentionally make it harder to consume your API, to protect a proprietary boosting function, and because you didn't realize it was bad design.
- brylie 5y agoInteresting way to frame the idea as entropy. Starting every project with a backend and SPA client seems like adding unnecessary entropy. I'm glad we have middle-way options where we can progressively add dynamic functionality to rich-server, lower entropy applications and make an intentional decision whether to add a rich-client if the need arises.
- nerdponx 5y agoSurely the lowest-entropy solution is plain hypermedia, no?
- sodapopcan 5y ago> because if at some point you need to render on a client other than a browser -- you have to start from the beginning and write an API now. The answer lies in the "if" there. The speed and lack of complexity developing server-side with no API is unparalleled to doing client -> api -> backend. Not to mention, you aren't tying yourself into several different JS technologies (Which GraphQL or REST lib? Which view framework? What testing frameworks? And what's the whole backend stack? etc. etc.) I can only speak for LiveView but the whole top-down experience is in Elixir with sprinkles of vanilla JS (the community is big into Tailwind and AlpineJS as well, but not exclusively). I have real world experience of dev'ing API-first only to have the company nix any plans to open up the API. Adding new features is always a slog as we have to think about if the business logic needs to be on the client, the server, or both... not to mentioning have to update about 18 different places the name of a new field you're adding. The company I work for actual has a LiveView widget that is embedded on their client's apps. I can't speak very well to it since I only just started working there and don't actually start until next week, haha. But ya, I'll also echo the whole idea that a lot of companies don't need mobile apps. I'm certainly one of those people who uses the browser on my phone whenever I can.
- simion314 5y ago>you have to start from the beginning and write an API now. You could refactor your code to share mostly everything . I have no idea how this templates system work though so maybe you need a different one. so the API returns an array of users object as a json the html side of things would have a render function that has as input the same array of user objects. What you will probably lose versus complex frameworks is magic stuff like 2 way data bindings but from my experience those always caused issue, I prefered the old react way of doing things, it was more "functional style" and less magic under the hood and I could(and used) JS and not a special template language with special keywords to render stuff. Amway my point is yu can reuse the API code for the html render stuff too.
- hedgehog 5y agoI've used Intercooler.js (the predecessor to HTMX) a bit on top of Django and small Go apps (no framework). If you don't need a lot of complex state and interactivity on the front end it can work well. This approach avoids the complexity of having two codebases, you can get the performance/usability benefits of partial page updates while keeping 99% of the codebase in one language.
- joelbluminator 5y ago> Whether or not you love or hate this model of development is irrelevant, because if at some point you need to render on a client other than a browser -- you have to start from the beginning and write an API now. That's not true generally since many mobile apps are simply wrappers around a WebView. Rails Turbolinks basically has mobile shims that allows you to deploy to all platforms. Sure, if you can't use a Web View on your mobile app (idk, for performance reasons) that's something else. But that's not the rule.
- kirse 5y agoLots of reasons: 1) No need for 3.7GB of node_modules to crank out a simple site 2) Single solution, easier to bring on junior developers and reason about application logic 3) Caching much easier, too many people think they need real-time push when NRT-polling + caching is far easier and more performant Broadly speaking it's often a case of YAGNI. The JS ecosystem really does still suck for its complexity, I remember that every time I ramp up a new developer onto a React project. It's smoothed out with tooling but the litany of JSON configuration files and the mess created by hot-reload + proxying + microservices etc etc. Often just YAGNI. People today don't remember the VB6 IDE days where you could slap a button on a Form, write a line of code for a MessageBox, and smash that play button with zero effort. JS development is often about working your way through a tangled spider-web of helper utilities and config files and JS modules at which point when it finally works you're afraid to rev anything.
- recursivedoubts 5y agobang on, especially that last part a bit focus of htmx, alpinejs (and htmx's sister project, https://hyperscript.org https://hyperscript.org) is putting the logic on the element, so you can see exactly what a button, etc. does just by looking at it, and without trawling through ten files of indirection i am trying to popularize the term Locality of Behavior to describe this design goal: https://htmx.org/essays/locality-of-behaviour/ https://htmx.org/essays/locality-of-behaviour/
- lhorie 5y agoI'm curious about your thoughts on that locality of behavior idea vs aspects of precision and composability. For example, the argument goes that the behavior of `hx-get` is obvious upon inspection, but the terseness is achieved by omitting the event type (i.e. it's assumed/implied that hx-get runs on click). The quintessential widget where that breaks down is the table w/ checkboxes for batch operations over an arbitrary subset of rows. That's where less DSL-ish frameworks' abstraction via state management tend to shine, since they allow the developer to more precisely specify how disparate checkboxes relate to a bigger picture that may also involve table sorting (both client and server varieties) or nested modal structures or other forms of complexity.
- Mikeb85 5y agoHonestly because sometimes it's all you need. Take Rails Hotwire for example. It's easy to write, easy to add JS when you need it, easy to make mobile apps since they've already done the work. It's live on Basecamp and Hey.com apps, it works very nicely. Hey is easily the snappiest email client I've ever used.
- AmericanBlarney 5y agoIt's funny because it's strikingly similar to .NET web forms' original (and utterly trash) implementation of AJAX. Everything that is old is new again...
- nerdponx 5y agoThis is a baffling and backwards mentality to me. I don't want an "app" most of the time, I want a damn webpage with hypermedia.
- nprateem 5y agoPeople need to learn to make their own mistakes. It's an anti-pattern. Just ignore it.
- rmbyrro 5y agoI presume you can keep the logic code separated and being consumed by the UI generation on the server. This way, if you only need the logic for another platform, you can just consume it directly. Perhaps you'll have an additional job to write the HTTP endpoints around it directly, but that's a quite simple job.