I am using htmx. I still have a nagging feeling that this has mostly dragged the overton window back towards hypermedia (big fan of the book, recommended).
It still feels wrong. I don’t know if I mean wrong as in “incorrect” or wrong as in “cheating/too easy.”
It gracefully makes sites work like it’s 2025 or 1999, but I have to design my markup like it’s 1999. I can never decide if this is good or bad.
My projects all depend on an API for automation. So by buying into this doctrine, and rejecting even content negotiation, I am at least doubling my endpoints.
It’s like being 12 years old, and falling in love with a “bad girl” who doesn’t go to church—and never shows up to class—but makes you remember a lot of basic truths.
Being less poetic. Installing python-multipart to do anything interactive with forms seems like a codesmell, but I don’t know what it is ;)
EDIT: my final comment was not a diss on htmx obviously. But the idea of using browser-consumable response data after the success of computer-readable encodings for web apps
I started webdev in 2007, CodeIgniter, jQuery etc. Things were fun to build and fast to iterate. Deployment was a faff but you dealt with it.
I was late to React (like 2020 late!) but have worked on three large (code base and requests) projects in React since then. Development was not fun, iteration was slow, but deployments were fast, yay for DevOps.
I am now building an in house platform in HTMX and it’s wonderful. I get the fun and speed of the early days with the CI/CD we have now.
The project I’ve built would already be a pain to deal with in React, instead it’s fast to load, has snappy interactions, has less code and is easy to extend.
It feels like cheating, but only because React projects get so hard to work on.
Just out of curiosity, what makes the development with React slow for you? Is it amount of code required to do something? The actual latency between change and visible output? The time it takes to get something running? The app itself being too slow (maybe from weight)?
Because of primeagen I've been bit buy the curiosity bug, so I wanna try it, but till I try it I am trying to figure out why the day-to-day experience is better. Because for me the biggest win is the idea of having thinner client logic. But I think I would use a React Server Component today to ease that issue.
Two big things in React from the projects I’ve worked on:
1. Horrible project structure because it’s so unopinionated. Angular has its problems but it’s so much easier to navigate around (one of the reasons I like NestJS is it uses a similar structure). I once worked on a React project where every component was a folder with an index.tsx file in it and default export so tracing issues was hell since the folder name was the best clue you had but people renamed components on import. Not soley a React issue, but made worse by its lack of opinions.
2. State management in React becomes a nightmare for:
a: keeping server and client state in sync, thunk/the other one
b: everyone eventually puts it all in a global store so you’ve got the faff of dispatching, reducing, whatevering each and every update, adding a single toggle can involve updating half a dozen files.
On the performance side I have a table in my htmx app showing a few thousand bits of data. In React this would need to be paginated, with HTMX I just send the fully hydrated table to the browser and it loads it in a fraction of a second. Then when it updates I just rerun the SQL query, rerender the table on the server, send it back to the browser and HTMX swaps it in.
For me SPA + API always felt like building an application twice. With htmx I build it once.
Agree that React isn’t the problem, I worked on an equally large Angular project that was also a pain, just slightly less of a pain.
React makes it easy to create a big mess.
Because I only spent 3 years in SPA land I feel quite comfortable with only shipping what the browser needs to display what the user wants. Getting JS to render everything always felt a bit odd to me.
React has abstracted everything that works so that you can wrap every bit of code in the 'React way of doing things' e.g. styled components, hooks, stores... so much so that we've forgotten architecture and what programming languages can do. I think if you draw a good architecture you won't need most of its fluff
It is unnecessarily complex for many problems. You can blast away state in many instances. Sure, use it for multithreaded real-time chat, but don’t use it for simple CRUD.
Instead of living the basic react way and gathering state in one component and passing it down as a prop to a child, you feed it into a global "state store". The child component then requests the exact state they need from the state store. This also works reversed, instead of passing "setX" as a function to a child, you just rely on them to gather the state and pass it to the store.
The thought behind this is that components live in pyramids, and state and props ideally only go down and rarely up by setters-> parents and their immediate children can easily share state and props.
This gets more complicated the larger your family line gets. Many grandchildren down, you have since passed the respective props via prop drilling through a lot of components that perhaps don't care for them. It also gets complicated if you want to share state not in an immediate family line, but in a neighborhood.
Overdoing it is almost like hoarding. You think "eh, maybe I need this later somewhere else) and suddenly, your entire application basically lives in the global store.
Right. And I think the point is that Redux is a godsend for some small percentage of products but for the vast majority the cure is worse than the disease. Simple and slightly verbose is just "better" as a general solution than the powerful but complex solutions you get with Redux.
I made something last year in a functional style as I was fresh off the back of a few React jobs and projects. I got a proof of concept working but the code was awful to work with.
I took a couple of days to start over and rewrite it with OOP principles and it was in a much better state afterwards.
The major issue, IMO, is that the DOM is just markup with an API grafted on, and so any framework attempting to add the slightest bit of composability or state management has to twist and turn itself to be compatible in all browsers.
And that's how we got here, because everyone wants to make their applications available on as many platforms as possible, without having to maintain five or six separate teams that have to coordinate a roadmap, and the browser is the only somewhat consistent way to do this.
I have seen people arguing that you shouldn't be using the same API endpoints for front-ends and for integration. I can see arguments both ways though...
I mean, I’ve built both ways. The least productive thing I have seen from the debate involves two teams doing the same thing, but one team are python nerds making an API and the other are node nerds making an API. N’er the twain shall meet, right?
I don’t mean to exaggerate, but your code will tend to mirror your organization structure. I have worked at companies where I thought our product was great because the API rocked.
Then in my last 3 months I got to meet the frontend (definitely a jobsmell: not seeing the frontend every day.)
Definitely misjudged the quality of our product, because apparently we wrote two different products (shrug) ;)
Pretty strong argument for htmx, actually. But again, in a weird way where we fire the frontend and become actual full-stack engineers for everrrrything.
Have you implemented it? The orm aspect is actually pretty weak. You end up implementing an RPC api anyway. And then you wonder how this was sold to you as declarative and idempotent.
I exaggerate here because graphql does not solve the datalake problem. And it doesn’t do graphs (you can). The curb appeal looked super promising, but then it was just rpc with a bespoke ORM syntax.
How? GraphQL is just another way to make query API with structured output, almost always JSON in practice. If you wanted server-side rendering, you still need another endpoint even if it happens to use GraphQL internally, just like you could made a rendered endpoint using another form of API internally.
Plus, if you’re writing the front end in react or something else, that’s essentially the “other endpoint”. You’re just moving that back closer to the source of the origin.
>My projects all depend on an API for automation. So by buying into this doctrine, and rejecting even content negotiation, I am at least doubling my endpoints.
If you can query that client-side, you don't need an hypermedia client, you need an RPC client.
The real power of HTMX and Web Components is that Web Components self-initialize when they get attached to the DOM, so they are easy to AJAX in. This was always a PITA in the jQuery world since you would have to hunt down the new interactive elements and run a library's init function on them.
> The real power of HTMX and Web Components is that Web Components self-initialize when they get attached to the DOM,
I've run into some problems with the Custom Element lifecycle, though. Not sure how to solve them, because `connectedCallback` is the wrong place for my custom code. The odds are I am doing it wrong (or have a fundamental misunderstanding!)
Basically, lets say I have two custom elements: A and B.
All Bs are a descendant (even if not direct) of an A.
Each A grabs all B children and copies the data out of a specified child of the B, then uses it.[1]
When the connectedCallback for A is executed, the Bs are not yet connected and thus don't show up in a call to querySelector.
I've (sort of) worked around this by having each B, when connected, find the closest A ancestor, and add itself to an array field of that ancestor. A's connectedCallback performs a setInterval with ever-increasing delays until some specific maximum (I use 10ms). The setInterval just redisplays with whatever labels are in the array.
Now, this is probably a stupid way of doing this, and I believe a better way is to use MutationObserver, which I will probably switch to at some point.
However, my point is still: the life-cycle did not offer me some way to hook into A only when all the children are attached to the DOM.
[1] A practical example of this would be tabbed-containers. The <tab-container> shouldn't hold the labels for each <tab-item>, it should get the labels from the <tab-item> itself.
Another option would be for the B to dispatch a `CustomEvent` on itself. That event will bubble up the DOM until it hits A. A would then need an event listener that would probably stop propagation and do whatever bookkeeping is necessary.
This seems like the best option, because it works just as well if the child components are loaded async (Ie: a tab component loading sub tabs on hover, and then the parent tab container needing to subscribe to that)
I think your workaround is probably the most preferable of the options. I've worked with mutation observers a lot and I wouldn't want to rely on them for anything that didn't have a simpler mechanism to achieve the same thing.
In "regular" frameworks, this problem would be expressed as state that is owned by A, that B's contribute to. Maybe by calling a function passed down to them, or by updating a shared store. It's a big shortcoming that composition of web components is limited to string attributes unless you use some sort of framework to mediate things.
I think this is decent approach, although setInterval may be unnecessary. I do this similarily as a base Class, and i made a generic solution that would not allow for A's to be initialized until all of its children registered thsemselves.
slotchange is your answer. In the connectedCallback add the eventListener and inside your slotchange handler: const myBs = this._slot?.assignedElements();
This is the exact use-case I found for them, and it’s terrific. I define any tag, e.g. <my-modal>, put normal HTML within it as if it were just a div, and then I can define the callbacks (like adding/cleaning up listeners) and custom attributes in a tiny bit of JS.
Any React/Vue/Angular/... client application using `fetch` to make a request, is making an AJAX request. Just because you haven't seen the term in a long time does not mean it is outdated.
Is anyone using htmx in a large project? Seems like it could be great for small things, but unmaintainable at scale, and that all the praise is based on the former.
Something tells me that the backlash will be enormous.
I doubt it. I think it's like svelte, but a bit earlier in the hype cycle.
The "State of JavaScript" survey is illuminating for these kinds of technologies. They often follow a trajectory towards "more liked", while remaining consistently and firmly in the "not used" quadrant. Everyone thinks they look amazing and refreshing, and maybe some people have even actually written some small apps in them, but (almost) nobody is using them at scale.
It's not a bad thing really, but the hype can be annoying
I've used Rails for small-medium sized projects and overall have a good impression of it (I'd even argue it did a lot to drive web development forwards) and I know there are still orgs out there using it regularly, but is Rails honestly still being used to build large scale apps (excepting the ones that have already been around forever like Github)?
Every org I've worked at since the last Rails project I worked on around 2014 has built JavaScript heavy thick clients on top of API's. That's not really where Rails shines, and I've not seen it around at all for newer projects since roughly that time.
It's anecdotal, but it's my experience that the industry has largely settled on the SPA + API's architecture, and the technologies every org I've worked at use to build those SPA's are either React, Angular, Vue, or very occasionally for niche cases their own JavaScript framework.
I understand that some people on Hacker News still dislike the complexity of modern front ends, and I get it, I really do. But I haven't seen any real alternatives that have been seriously used in anger to build an actual commercial application since React, Angular (and Vue) took over.
Oh, scale in terms of team size. Yeah that is why React. I was thinking scale like you can build the hey.com mail client with htmx and be happy about your choice.
I wouldn't categorize Hotwire as a well-established technology simply because it's included with Rails. Its prominence isn't solidified even with support from notable figures – as all tech trends have their advocates. In my perspective, it's somewhat analogous to htmx: The cool kids are using it for smaller, manageable use cases, but it's far apart, like magnitudes, from the adoption React has.
In theory it seems like it should scale like a variation on a pretty standard full stack application that does the HTML work on the backend -- as opposed to a SPA -- but instead sends fragments instead of entire pages. I'm also be curious to see how it plays out in practice, since it's been pretty neat for my small projects and I'm intrigued by it, generally.
There is the occasional tech talk on YouTube where some kind of migration from React to HTMX in a large project is discussed. You will have to search though as I do not have any links at the ready.
However I have not seen anything really substantial either that confirms that HTMX works in large projects just as well as in smaller ones. I plan to use HTMX in another larger, upcoming project though as I want to gain some insights on the side too.
That being said I am aware that it might turn out to be a mess. But I would be content with the fact that HTMX is generally very useful for smaller projects and just put it in my respective imaginary toolbox to keep in mind for those kinds of projects.
Every time this is brought up (use in larger projects), people usually only mention this article/video and nothing else, so I'm not sure if that's a good or bad thing.
Yes, that is exactly my point! I think the lack of real world examples of large HTMX projects is a little telling. But it might just be large projects usually happen in large companies where you aren't necessarily allowed to disclose project details to the community. Again, I think at this stage the best way to determine if HTMX is a viable option for large projects is to try and ideally share your insights.
To be honest I am looking forward to the day when we can put all the HTMX/React whatever debates to rest and it will just be another great tool amongst other tools.
to be fair unless you are doing a complete rewrite it doenst make much sense to swap frontend. I bet we will see later this year htmx getting used because of people getting confortable with it
htmx’s growth trajectory isn’t as steep as you’re making out with that expectation. I remember seeing conference talks about it ages ago. It’s ostensibly getting more interest now sure, if not legitimate adoption, but it does feel like more of the early starters would have something to share by now.
>> that confirms that HTMX works in large projects
Define large? By size of project or volume of users.
HTMX is more targeted for the latter, not the former.
THere is a continuum. Static pages, SSG's on one side, and SPAs/react all the way at the opposite end. They both do VERY different things. HTMX is some where in the middle, think content heavy PAGES that need lightweight public facing interaction (email/contact, validation loops, a form or two, maybe some dynamic conversions, a carrousel)
Static home page for cache performance, html for sales contact cycle, react for the app you sell ... all three can and should be coexisting!
Majority of apps are small, yet they load tens of megabytes of javascript and it's becoming the unwanted norm. You can't browse many blogs without enabled javascript for no other reason than personal data harvesting needs.
Agree they're different, but it's important not to miss the first point:
> Majority of apps are small
I'd like to see some data on it, but intuitively that resonates. The lighthouses of UI frameworks - notably React & Angular - emerged from the needs of big apps, with 100s of people, and structures that delineate front-end and back-end teams. The organisations behind the frameworks - Google, Meta - are very influential in setting industry direction. So those frameworks become "the way to do UI". That doctrine spreads through the community, and the context of origin and use is occluded.
If htmx or similar drives a re-think then that's healthy to me. My own experience is with lots of comparatively small apps. Plain old server-side rendering hits the 80/20 for most, and something like htmx might move that indicatively to ~90/10. Which is attractive because it means 1 tech stack and comparatively less requirement for hard delineation of skills in dev teams.
It's not saying "throw away React/Angular/..., you never need them". There are clearly situations where they're a good fit. Where fit means both organisational and technical. But they're not a good fit in every case.
React actually wasn't built for SPAs; Facebook built it for widgets on a server-rendered page.
That is why it has no built in SPA features, like routing, data management, data fetching or other batteries a SPA or PWA might want.
Conveniently, it provided a very nice set of primitive and composable APIs so that all of those features can be added on in a way that fits naturally, such as react-router and the rest of the ecosystem.
That's all driven by the community, not the "lighthouse", so to speak.
AngularJS likewise didn't require using the router, and in fact can just as easily run multiple instances on a single page. I haven't used Angular in years, so I don't know the story there. Same goes for Vue, but that's hardly backed by a "lighthouse".
I don't disagree that there's no use for HTMX or server rendering of html. Not everything needs to be a SPA. The problem is the argument is a whole lot less convincing when presented with a lot of incorrect facts
> Seems like it could be great for small things, but unmaintainable at scale, and that all the praise is based on the former
Why does it seem that way? There are plenty of talks on youtube of commercial projects that switched from React to htmx and found considerable benefits.
I don't see any reason why it shouldn't scale. It also allows you to use any backend language. If you write messy code in php and think it is the language 's fault then you can use something else. Rust, Go, Java, C#, Elixir. Everything should work. Just don't write messy code.
A) There are some important differences. For instances: sizes, spacings and colors are picked from a scale, not set in pixel values (although you can do that now if you need it.)
B) There are many ways to "reinvent inline styles", this one is good, actually. I used to work with a fairly mature codebase. We enforced BEM-style names, but otherwise the CSS was extremely ad hoc (which, it is my impression, is quite normal). I ran some queries on our existing code, and found that most of our CSS classes were only used once, and most elements had only one style. They quite often had generic names, though, and when working with them you were always afraid to change a class because you didn't know if it'd been recruited elsewhere. And you certainly didn't delete anything. The growth in the size of the CSS was also quite extreme - it doubled over a year as far as I can remember. Probably because nobody ever deleted a class, even when they stopped using it, because then you would've had to check for sure that it was now unused and.. meh.
I starting referring to all this as "might as well be inline"-styles, because really, all we did was move the inline information to a different file, which... has no benefits when you think about it[0]. A thoughtful application of atomic CSS would have been a massive ergonomic improvement IMO, and I've since used Tailwind on a big project and found it much, much easier to work with over time than the other system.
[0] Yes, I know about the CSS Zen Garden. I don't think the principles apply to web applications - and, if anything, the approach to colors and font sizes in Tailwind makes theming much easier than in a messy codebase like what I used to work with.
It is inline css with all of the warts removed, eg. media queries are available, it exports a coherent design system rather than allowing any CSS, etc.
yea between tailwind doing all my css as a string in an attribute, and htmx doing all my coding as a string in an attribute feels great! who says i need types in programming, who says i even need symbols, i can just do everything in strings! and then if i imagine the strings aren't there, then its like i'm programming for realzies. good times ahead!
This is how Tailwind works. This sort of comment comes up every time Tailwind is mentioned. Here's a recent piece on the popularity of the framework: https://matt-rickard.com/why-tailwind-css-won
Considering that low-level atomic CSS lib like https://open-props.style are now up-ticking in popularity, it is too early to say that Tailwind CSS "won".
But how is class="border-solid border-black" better than style="border:solid black"? It's hard to imagine that you'll change the border-black or border-solid classes to do something else, so some is clearly just a different inline style.
People do that (not me) because you can easily change all elements that have that specific border type. You might change the radius or thickness, could add an outline or at least see what it looks like applied to everything. border-solid wont change but it follows the same approach for consistency.
Border-solid can indeed be inlined but black is a color i think not all agreed on.
I like #252325 but some will go for #030303.
Also, it's like building your new and shiny app with i18n in mind. Do you really need translations when you are the only user? Probably not, but development is also about trying to predict what will happen next. classes helps you to grow.
'black' is a named web colour, no? In 1999. #000000 [1]
Or aside from re-writing standards, I don't get the point about translations. I go for classes on elements, like
<h1>
h1: var(--c0-b);
That means colours can be swapped around like an i18n language, by changing the palette that sits in the CSS file. Putting 'black' inline be it in actual inline css. or pseudo inline css that seems to be the case with the library here, is the exact opposite of an analogy to i18n in mind and seems a great step back, back to pre stylesheet days, in the power of abstraction.
Web components are great! HTMX is great! But there is no answer for WHAT ABOUT THE JAVASCRIPT. You can't build a web app without it, so...what about bundling? What about binding? What about state? Yes, I understand that I'm doing it wrong and I need to do this on the server or something, but these are not specific enough answers which would make me abandon React or Vue which have great answers to all of these questions.
HTMX looks pretty much like something I would use for fast prototyping with very limited complexity/the scope is known ahead to stay simple. I've been working in full-stack for a decade together with extremely skilled engineers on large monorepos. Our wisdom is to stay as vanilla as reasonable and understand what your technology does underneath. As soon as there are layers over layers (tools calling tools with domain specific languages) you wish you could simply change X directly instead of having to go through e.g. create-react-app or htmx. But if any framework can provide me that level of comfort then I'm fine with it although I learned the more comfort frameworks provide the darker the other side.
I see these kind of comments pop up and as a long time backend/full-stack dev I don't follow the logic all too well.
HTMX is just another tool to be deployed. If your app requires a SPA experience or large amounts of javascript for the UI, its not the right tool for the job. Where I have had great experience with it is for applications that have discrete javascript implementations or none. Lot's of applications that are quite valuable to the end user, are really just a bunch of CRUD like operations and don't really need a full blown FE framework.
i disagree. making the backend format a div and send it back is much faster than creating a json, sending it to client and having the client hydrate stuff inside the page
I have found this to be true in my experience too, but I’m not a professional dev, rather a hobbyist, so HTMX suits me just fine. That isn’t to say it doesn’t have a place in the toolchain of professional devs though!
I had some 'fun' figuring out how to deal with not going through create-react-app without doing a full eject, got something barely working ... and discovered https://craco.js.org/ already existed and did precisely what I'd part-implemented except better.
On the upside, by that point I knew the CRA codebase well enough to predict what it would do even in edge cases, and CRACO's implementation was immediately comprehensible, and none of my colleagues had to try and understand my half-arsed NIH version.
(avoiding being in any of this situation in the first place would likely have been preferable, but given where things were when I landed on the project in question that would've required a TARDIS)
Good thing about htmx style solutions is that it's easy to implement the features you need without extra bs. Often it's so much simpler and cleaner to code something than using a generalized library or framework.
You can still use react , vue, solid or whatever for the dynamic parts that make sense to do clientside
Am I right in my understanding that HTMx is kinda "adding data requests to document elements".
I can see how that might be useful for simple things but for anything with any level of sophistication aren't you going to have to jump right into JavaScript?
I just don't really get the big picture of HTMx. Is it making easy things easy and leaving hard things to React or Vue or whatever?
Can someone please sell me on it - why should I be excited given that to get anything hard done I have to jump straight into JavaScript.
What are hard and easy things? I don't understand the bifurcation.
Some applications benefit from being in the style of a SPA, others do not. For the scenarios that do not benefit from a SPA (or other full JS framework) htmx is really nice to work with, I still use javascript along with htmx but I delineate its usefulness to projects that don't benefit from massive amounts of global state that the FE needs to know about. Over the years I have found that the majority of applications I have built in a commercial setting, global state was not all that useful.
My mental historical model kind of went like this. We got backbone.js and started to make these magical like interfaces for the web. We then started to build everything as a SPA. We optimized for state management and how to efficiently update the dom. Because SPA were uncrawlable we would manage a static site and the SPA, then we got frameworks that could handle requests to specific views within the applications. After playing around with htmx I started to think that perhaps all that management the FE app was doing was not really necessary for a lot of the applications I had built. I can couple html with discrete javascript applications where necessary. For me thats the sweet spot but again, htmx is not a one tool fits all. There are many apps out there that benefit from using vue/svelte/other frameworks.
People today write static blogs with TS/React/Next/whatever because that's what they know. It's not because it's the best tool for the job (or even close to that).
It has become standard to use React/Next/GraphQL for any new project, regardless if you're building a new Google Docs (which definitely benefits from JS) or yet another CRUD application that has lists, details and the occasional interactive page like a graph or something similar.
That's the crux of the issue: we seem to have lost the ability to think critically and choose what we require, in favor of copy pasting choices from everyone else and calling it a day.
Once you're heavily invested in all the JS-only technology, your incentive is to stay in that lane. To consider better alternatives is simply too costly for many.
That's why we turn everything in sight into JS. Someone I can't recall said once: everything that can will be rewritten in JS. We even have people building email templates with React now because all they know is JavaScript.
I am writing a complicated website - the typical single page application and, so far, htmx is working wonders (and removing a lot of frontend work which I find duplicating data models already done on the server)
One problem I did face is trying to put together a large json to a POST request. I did experiment if I could do this all in the 'htmx way' of using input=hidden but was not working. With this, it was best to store this as a JS variable, or call a JS function to return json, which was all specified in htmx (in html)
Point is there are some exceptions that I have to do some javascript but the amount is much less when using other popular frameworks.
Overall, I am doing most work using htmx and odd exceptions with simple javascript functions to returns text or json.. or javascript to compliment my css.
What was in your json? I've taken forms pretty far with htmx. Getting to accept "the state lives in the html" takes a bit of mental wrangling, but I've found it to hold up well so far. (One nice htmx trick is the ability to include hidden inputs/forms/whatever from outside the current form if necessary.)
Thank you for expressing interest and, potentially, an approach to suggest ideas.
On my original attempt, I just couldn't get the POST request to work. I cannot remember the details but, due to time constraints, had to resort to something.
I will admit that this is an area I would like to revisit, but the current approach does work well... for now.
My json is larger than below, but provides examples of the inputs they represent on screen:-
{
"catA": {
"capacity": 90, // value from slider control
"memberType": 4, // value from single drop down
"members": [1, 2, 10, 100], // values from multi select drop down
},
"catB": {
"dateRange": { // both individual text fields
"from": "2024-01-03 10:00:00",
"to": "2024-01-04 10:00:00"
}
}
}
I've found it most useful to have form types that are derivable from db entities, but which are designed for parsing (and rendering) forms.
What backend library do you use? Mine (javalin) gives me back forms as: `Map<String, List<String>>`, i.e. a map of form keys to list of values.
In your case, you have five keys that matter: capacity, memberType, members, from, to - so you could have a completely flat form object from which you derive your catA and catB entities easily enough.
I wrote a function which converts from the generic form structure to a more nested/typed structure, but I found that two levels of nesting becomes hard (maybe impossible) to reason about (consider lists with mismatched lengths, and how you'd handle them on nested objects); in any case, I'd be able to have:
data class MyForm(val catA: CatA, val catB: CatB)
...where CatB is flattened:
data class CatB(val from: OffsetDateTime, val to: OffsetDateTime)
...and then I'd be able to transform the form as:
request.toFormObject<MyForm>()
I've found this to hold up well so far. (I plan to write a few blog posts about the whole stack I'm playing with, including this -- subscribe on http://smaller.fish if interested in seeing them when published. No spam.)
> Framework updates often render components not usable anymore (anyone has changed, or tried to, major versions of Vue or React recently?)
I migrated my personal site from pure Vue 2 to Vue 4 + Nuxt recently. The migration guide was a garden path, but when I started a new project and just moved my components over into the conventional nuxt locations, everything went quite smoothly.
My use case is quite narrow. It's basically a blog but with some embedded applications (mostly simulations), heavy use of a particular custom component. I like the hot swapping from the vue framework and I appreciate the static compilation of the result from Nuxt.
I thought about doing something like HTMX + web components, but I would still need to figure out how to bundle what javascript into each page. Plus, web components have absolutely no server side rendering without another layer of complexity. Setting all that up seemed to me to be effort better spent on the occasional migration. Plus, when the going gets rough, Vue always had my back. My next step will be embedding wasm though... so that might change things, I'll see.
That really depends on how you want to use web components. I have used custom elements quite a few times with Astro, mostly leveraging custom elements for life cycle events.
I end up with a `.astro` file that server renders the HTML and adds a script to define the custom element. In the browser its more pike cheap hydration - the custom element doesn't re-render anything up front, it will just grab references to the server rendered DOM nodes and setup event handlers.
I know Lit has an SSR helper, though I haven't used it myself I think its supposed to make server rendering you lit web components much easier.
I don't know if I fully grok the web components described by the author. I did find that using templ with Go makes it reasonable to have components you can inject some logic and state into for sending back HTML to htmx where it makes sense. The thing that makes sense is we focus on generating HTML once and there is no need to redefine models in the frontend. This is important because it means we don't take HTML, convert it to a data structure, validate the data, then send the data to a server, that has to validate things again, and return some resulting data, that once again gets rendered as HTML. Each data transition is expensive from a complexity perspective and requires caching state where caching is hard.
I'll admit that I'm not a frontend guru so my bias for writing apps like I did 20 years ago likely shows here.
Still, when I consider all the different abstractions and details around using something like Next.js + Typescript, and where the division between server and client becomes mixed, reducing complexity feels advantageous.
Tailwind is another good example where the explicit nature of attaching styles makes sense if you are writing React components. You've encapsulated all that noise behind a simple JSX tag. Using Tailwind with something that returns HTML then requires a similar way to encapsulate the noise. Again, I found using Templ with Go made that feasible, but I still have avoided Tailwind just b/c I don't want to introduce the noise too soon if possible.
It all makes me wonder if we lost the idea of a fullstack engineer, not because the problems became so challenging that we needed the extra complexity, but rather because we organized our applications into frontend and backend organizationally when we should have been more diligent in maintaining teams that could do everything.
The real tl;dr is that Templ for Go is pretty handy for writing components :)
Is Htmx a good case for UI for a local application? I want to build a server app which I could host openly behind some auth, but at the same time I'd want to be able to run it in local mode, as a simple UI for local tests.
I understand there are some security challenges, as in "local" mode it can only communicate over HTTP with local app, or probably without CORS, etc. XSS might be a real issue here.
Strange question... if something works over the public internet why would it not work locally? There's no magic sauce with HTMX. It's just a JavaScript library that does what a million others do. You can run it on a local toaster if you felt like it.
What are the impacts HTMX has on SEO/crawlability?
I can't imagine doing XHR requests that return partial HTML snippets to be "good" for a crawler that expects one page to link to another (assuming they are running JS to begin with).
I don't get why people would use something like this, for most use cases this seems like a massive step back. I guess it's for applications where you want a little bit of interactivity but not build a complete single-page app. Which seems like a pretty small niche. The amount of boilerplate code and mental modeling needed for such a simple example seems absurd though. Personally I would just embed a small single-page app/snippet instead where I need more interactivity, stitching together server-rendered HTML like this seems quite bad. React for example is such a small and easy to use library, you don't even need a compiler toolchain to use it (makes code nicer to read of course), just drop the JS bundle in your HTML and write your component in a script tag, it will still be much easier to understand, use and modify than this.
Different developers have different skill sets. The mental model of different URLs giving you different distinct resources might make more sense for some. :P
So am I the only person seeing htmx and tailwind together and feeling absolutely disgusted? Like a wall of run on sentences and no paragraphs. I can’t believe tailwind is a thing…
No, it's a hatred of CSS. CSS is a pain, tailwind is a balm. I use tailwind on everything, extend or modify tailwind as needed, and write very little CSS. I have also stopped having dreams of strangling css-grids to death since I started doing this, so something's working.
I'm not familiar with modern Sass. Has it evolved much in the last decade? I'm still using Less because I installed it 10 years ago and it still works great, but there's almost 0 features that haven't been adopted into CSS now so I really don't need at all.
There is 1 I guess. I wrote a loop somewhat recently because there doesn't appear to be a variable for DPI yet. `env(dpi)` doesn't exist or I could have did what I wanted: scale a <canvas> element to be 1.0 scaling regardless of the user's screen scaling.
I have personally never seen a easier way to style things than the modern css engine. Whether its Android, iOS, GTK or anything else. CSS is fast and extremely easy. Used to flexboxes in css. Goodluck enjoying others :)
When I first encountered Tailwind, I sincerely thought it was satire—that its authors were making a really clever and elaborate joke about the state of front-end dev.
Then, I encountered the raving fans. That's when I knew the shark had been jumped.
I moved away from using it but I guess you underestimate the intellectual capabilities of people using it.
How you want to write CSS is a tradeoff.
Traditional CSS without tools like Tailwind, styled-components or other "hacks" is especially bad at collaboration and evolving from prototypes to large sites or apps, in my experience.
They arent dismissing the users of tailwind's intellectual capacity.
They're attributing a cult like / social influence phenomenon to the popularity of it. That others use it because others use it; not on any perceived by them actual merit of tailwinds design.
I was basing my comment on the perceived assumption that this would be the only possible reason to use it.
I was convinced to try it by Adam Wathans initial blog post comparing it to BEM notation and "semantic" class names.
The arguments in that blog post still make sense, regardless if you think that tailwind is a good solution.
A cult like / social influence phenomenon is attributable to a lot of tech. Not sure if I'd call that "mass psychosis" though.
Sure, Tailwind tends towards lock-in, it also adds complexity in other places. It also will surely go out of fashion soon, or already has.
But it brought a concrete idea to the table, which worked for many people, and that was the reason for the "hype", in my opinion. Not "mass psychosis".
I never wanted to use it because of fashion. Maybe that was the reason I got to know about it though.
Also it influenced the way I write CSS, despite not using it anymore. In short: avoid being clever with the cascade, like the plague.
And I mainly stopped using it because I changed my job after 5 years. The projects we used tailwind for went well and it succeeded at avoiding the problems I wanted to avoid, especially when collaborating with a newly hired young colleague.
So yes, it is an example of a hype, might have been overhyped, but that's not "mass psychosis" to me.
I dislike tailwind too. Maybe I just use it wrong. But if I say have a number of similar-ish elements with many overlapping classes, when I need to make a change it affects numerous lines of code.
Traditional CSS? I’d update a style in a few specific spots and everything benefits.
You can still use normal css if you're styling multiple things. I think tailwind shines mostly when the css does not need to be reusable or is encapsulated in a component which is how it works in some modern web frameworks.
The reason why it is big is efficiency. Once people know those class names by heart, they get a "nice" (arguably) default style very quickly without jumping between multiple files. This matters more than one might think..
As a dev, I like Tailwind. As a consumer, it has stripped away a lot of how I learned to write websites in the first place. "View Source" is confusing now. Gone are the days of beautiful CSS selectors.
Tailwind sacrificed that for dev ux. The next generation will have a harder time learning about web primitives.
And htmx is not something I need for these days thankfully. I use phoenix liveview and get away with writing very little pretty dumb code. It's wonderful.
The whole "name it what its purpose is rather than what it does" like "alert-danger" rather than "giant-red-text" seems to have been thrown out with a lot of Tailwind. It prefers chaos but chaos is so much easier to adjust outliers. Those 2 divs have double the spacing between them? Just take the mx-5 off of one! It's hideous but so easy. Constant find/replace all.
I've tried building design systems into Tailwind config a few times and found it to lose a lot of the potential value of tailwind.
Markup is no longer portable without bringing the config with it and devs still need to learn the custom styles and classes we defined, meaning Tailwind knowledge alone doesn't get you up to speed right away.
To your example, recent Bootstrap has a mix of component and utility classes that lets you do both "alert-danger mx-0" or whatever.
I also avoids the giant size of Tailwind classes that requires that elaborate build/reduction process. You can just include Bootstrap from a CDN or whatever.
Yes DaisyUI is nice. Ironically, it convinced us not to move from Bootstrap, because we realized its components were almost 1:1 with Bootstrap. And that we actually don't want the infinite styling options that Tailwind offers, so that devs mostly use design system components. At that point, who cares where/what the CSS is?
I hadn’t really thought about that! I guess LiveView kind of does the same because often I’ll look at the network requests of a page to understand/debug stuff and you can’t really do that with LiveView because you just get the HTML updates over the socket.
I'm leading a large project right now, and I'm shocked at how well tailwind is working such that everything is consistent. I even hired a personal intern to build "headwindcss" that converts existing websites into tailwindcss templates using the computed style.
A future project of mine is to build a mini-browser of sorts, and I'm going to use tailwind as the minimal basis for getting the CSS to work. so... I'm enjoying it... like a lot.
I'm actually working on a project called "Failwind". It uses AI to figure out what you were trying to do with Tailwind, then rewrites your CSS using semantic classes.
You are not. As a dev I understand the temptation of Tailwind, but I don’t see the benefits really worth it in all cases where I see it’s used. Writing plain CSS just makes so much more sense in the long run.
I have opposed Tailwind to no end. But I gave it a try and the portability it brings to markup is beyond description.
You just move HTML from anywhere and it would just look exactly the same (subject to your overrides/customisations of course) so I don't think Tailwind is going away anywhere.
Rather, it now can be thought of as a mini language or notation built on top of CSS.
I personally don't like Tailwind. But I do see a lot of benefits of using utility classes for basic layout stuff.
So far UnoCSS works very well for me. It's like light-weight and customizable Tailwind.
Also for more complicated "components" I use css modules and refer to my theme values via directives (I think this is doable in Tailwind too?).
You are obviously entitled to hold whatever view.
I didn’t feel informed or enlightened by your comments.
I wish people move away from describing things they dislike as bad, horrible, dumpster fire. Describing the problem in a discussion site is always better
The pain or disgust is a strong hint that you're thinking about it wrong. If you have a bunch of repetitive CSS, how do you typically eliminate that? You create a class that bundles it all together and then just use the class name on the HTML.
But notice how you're then left with a bunch of repetitive HTML on which you apply those classes. If you bundle up the repetitive HTML into a reusable abstraction (like a component), then you're no longer repeating the CSS and so you don't need to bundle the CSS into classes anymore, thus reducing work. A type of inline styles, without the limitations, then gives you more direct control over styling on the bundled HTML itself. That's how you should use Atomic CSS/Tailwind.
It's great for influencers and beginners because of the ability to copy and paste examples plus the hype. The moment you put a scenario where there is no boilerplate available on the table, the utility of tailwind goes out the window.
As for Htmx, it's nothing new. I don't dislike it, but comparing it to web frameworks like React is missing the point. A lot of what it gives you (or doesn't) can already be achieved with a bit of vanilla js and, if you're feeling fancy, jQuery. Advocating for it as a replacement for something like React is sort of like recommending a bicycle to someone who drives. Yeah, it has its place, but it doesn't replace the utility of the car. Insisting it does indicate you don't know much about cars - or maybe bikes.
Anyway htmx uncomfortably reminds me of the MVC servers we use to write 15 years ago where the frontend always ended up being an unreadable unmaintainable mess after a few years because the frontend was treated as a random collection of assets for views to use.
HN guidelines suggest to not comment on the site itself, but I agree that the font immediately made me less excited to read this article even though I am interested about the topic.
It still feels wrong. I don’t know if I mean wrong as in “incorrect” or wrong as in “cheating/too easy.”
It gracefully makes sites work like it’s 2025 or 1999, but I have to design my markup like it’s 1999. I can never decide if this is good or bad.
My projects all depend on an API for automation. So by buying into this doctrine, and rejecting even content negotiation, I am at least doubling my endpoints.
It’s like being 12 years old, and falling in love with a “bad girl” who doesn’t go to church—and never shows up to class—but makes you remember a lot of basic truths.
Being less poetic. Installing python-multipart to do anything interactive with forms seems like a codesmell, but I don’t know what it is ;)
EDIT: my final comment was not a diss on htmx obviously. But the idea of using browser-consumable response data after the success of computer-readable encodings for web apps
(I guess I just mean hashmaps/dicts/json/object)