Three main approaches to web development
1 The classic approach (limited interactivity)
Most websites are built by simply having the server rendering pages one by one. In other words, when the user goes to mysite.com/about, the server receives a request to render the full about page and returns it; it returns the full HTML for it (including the menu, the footer, etc.).
2 The current (2023) accepted approach
For about ten years, many developers insist that having an API and separating the frontend and the backend is the way to go. Anyone building a website the “classic way” has become a moron who must ultimately change their mind or be eliminated.
On paper, the backend / frontend separation via an API is indeed beautiful. On one end, the backend deals with the database, the business logic, the permission, the caching… The backend exposes useful data and operations via an API (usually REST or GraphQL). The frontend application is completely separated and runs in the browser directly. The frontend application takes care of the design and the user interactions. It should not contain any business logic.
3 The htmx approach
The idea behind htmx is to complete HTML with what’s now missing. What’s missing is some interactivity - i.e. a way to load bits of data - not full pages (yes, this is an over-simplification). With htmx, the bulk of the work remains on the server side.
Here is the explanation copied from the original site:
To understand htmx, first lets take a look at an anchor tag:
This anchor tag tells a browser:
“When a user clicks on this link, issue an HTTP GET request to
/blog and load the response content into the browser window”.
With that in mind, consider the following bit of HTML:
<button hx-post="/clicked" hx-trigger="click" hx-target="#parent-div" hx-swap="outerHTML" > Click Me! </button>
This tells htmx:
“When a user clicks on this button, issue an HTTP POST request to ‘/clicked’ and use the content from the response to replace the element with the id parent-div in the DOM”
htmx extends and generalizes the core idea of HTML as a hypertext, opening up many more possibilities directly within the language […].Note that when you are using htmx, on the server side you typically respond with HTML, not JSON. This keeps you firmly within the original web programming model, using Hypertext As The Engine Of Application State without even needing to really understand that concept.
Separate frontend application VS htmx (approach 2 VS 3)
Having a separate backend and frontend generates lots of duplication. The same concepts must be coded twice. For an ecommerce site for exaample, both the backend and the frontend must have models for users, products, a cart, etc. With htmx, there is no code duplication.
With a separate frontend, full-stack functional tests are impractical to write. It’s possible to use tools like Cypress but that requires extra work. The developer writing the tests must be proficient in both stacks. Also, it’s important to note that Cypress tests are really slow. With htmx, since the backend returns HTML for both regular and htmx requests, full-stack unit-testing is trivial and relatively fast (obviously still slower than specific unit-tests).
Finally, with a frontend framework, you need to do extra work for SEO; again, this is not an issue with htmx.
htmx is good for basic interactions only. For more complicated UI, you would still need a separate frontend like React. Even for simple things; if you add lots of htmx tags everywhere, the code might get tricky to read. These are the only drawbacks I’ve found so far.
htmx will be enough for most websites / pages. You will need something else for specific widget and/or for full-on applications like graph editors.
Having a completely separate frontend often does not make practical sense as it takes three times more work. Instead of adding bits of React or JQuery in various screens when some interactivity is required; we can now use htmx and add these bits of interactivity directly in the HTML and in our usual backend code. This way takes less time, allows better unit-testing and keeps thing simple. I highly recommend you to try htmx.