Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

After reading some HTMX criticism, there's one point people seem to miss. Making HTML your application interface does *not* prevent you from having a JSON (or something else) API. If anything, it probably forces you to split your functions better. e.g:

  def get_user_data(user_id: int) -> Dict (JSON-looking data):
      ...

  def render_user_view(user_id: int) -> HTML:
      user_data = get_user_data(user_id)
      render_template("user_detail_view.html", context=user_data)
If you need the user data in a JSON API, nothing prevents you from exposing `get_user_data` as a JSON endpoint. You can also use WebViews in a mobile app.

People tend to overestimate the "interactivity" needs of their apps and underestimate what they can achieve by just swapping HTML. HTMX also lets you swap "Out of Band" [0]. This makes it easy to model more complex interactions (like "reactions"), for example, updating a counter somewhere else in the app when a form is submitted. Reactive frameworks can also become a Rube Goldberg machine if an app is not properly designed from the beginning. Then you start fighting rendering loops, build dependencies, components' side effects, etc.

Personally speaking, HTML-driven apps are not just about easy vs. hard development, it's also about your users [1]. Maybe a big React app runs fine on 8 CPU cores and 32 GB of RAM, but very often, your users just want to read some content, maybe submit a few forms, and leave. They may not want to download 2 MB of JS so that the page can render boxes with text, even more if your browser can already do that if you give it some HTML.

[0] https://htmx.org/attributes/hx-swap-oob/ [1] https://shkspr.mobi/blog/2021/01/the-unreasonable-effectiven...



Big +1 on all of this. I have terrible rural internet, and just recently tried developing my first app with HTMX (wasn't aware of Alpine.js), and _man_ is it fast. For city slickers with their symmetrical gigabit connections it may be unnoticeable, unfortunately. Not saying SPAs have to be bloated, it just seems like most sites that turn into SPAs are bloated.

All that said, trying to push everything server-side if you've been working in a heavy client takes some getting used to. In my real life job I've seen feature flags shipped as an API so the client queries whether a feature flag is enabled - this is something that always struck me as silly, the server serving the front end already knows if the feature flag is enabled. While that might be justifiable in some cases, it is definitely not so much in the on-prem-only product I worked on.


Not only in rural areas. I was commuting for 3 years and i had to deal with the German network coverage every day. Every single time i though "great, i can start reading", the page went blank, because it couldn't load "click_my_fancy_newsletterbox.js" in time. That's why i try to make sure, that my crappy hobby project is also able to load without fancy js.


I've been in exactly the same boat, and I feel like anyone could be if they run out of mobile data. When I get to the point where even HN won't load, I know it's time to put the phone away. The other one that really gets my goat is the page looking like it has loaded, going to click on something, and some frontend nonsense loads the instant before clicking and now I'm off to an ad or a completely different page than intended.


Haven't used django for a year or 2 but used to use django-rest-framework's negotiation to get both json and html responses (was using inertiajs not htmx) and it worked pretty well. You can use decorators on the api methods to set things like templates. Here's an example:

  @inertia("User/List")
  @api_view(["GET"])
  def get_users(request,  **kwargs):
    // ...
    return Response(data={"users": users})
This can return JSON or HTML with the data injected.


THIS! So well put, especially the functional separation aspect.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: