From React to htmx on a real-world SaaS product: we did it, and it's awesome!

This video features David Guillot at DjangoCon Europe 2022 in Porto, Portugal.

From React to htmx on a real-world SaaS product: we did it, and it's awesome!
0:26:46
Published October 14, 2022
109,229 views

From React to htmx on a real-world SaaS product: we did it, and it's awesome! by David Guillot

We took the plunge and replaced the 2-year-of-work React UI of our SaaS product with simple Django templates and htmx in a couple of months. We’d like to share our experience with you, with concrete indicators on various aspects, and convince your CTO!

Summary

David Guillot explains how his team replaced React with Django templates, HTMX, and Django Components in a production B2B SaaS product. HTMX handles server-triggered updates by fetching and inserting small HTML fragments, while Django Components combine templates, CSS, and JavaScript into reusable UI elements; this supports rich interactions without duplicating application state in the browser. The migration improved first-load performance, reduced client memory use, enabled lists of thousands of items without lag, increased team and product agility, added tests and cleaner code, and removed about 15,000 lines of code. He argues that HTMX is a strong choice for small teams that value fast end-to-end feature delivery, while teams requiring strict front-end/back-end separation may prefer a different architecture.

Key takeaways

  • HTMX can support rich, responsive interfaces by updating targeted HTML fragments from the server without client-side application-state management.
  • Django Components package reusable templates, CSS, and JavaScript into isolated, testable UI components.
  • The migration improved first-load performance and client memory usage, and allowed the product to render thousands of list items without lag.
  • Moving away from React increased the small team’s ability to work across the full stack and ship features faster.
  • HTMX reduces separation between front-end and back-end code, so its suitability depends on a team’s preferred responsibilities and architecture.

Summarised automatically from the transcript.

Transcript

3,059 words · auto-generated Show

Automatically transcribed, so expect mistakes in names and technical terms.

0:00

Well hello everyone. I hope you can hear me. My name is David Guillot, I'm from France, as you can hear. I've been in the web industry for 15 years. I've been a Django developer for five years. I work at context. Yes, it's the French word for context. And I'm here to talk to you about uh an experiment we we've been running uh at my work It's about replacing React with HTMX on a SAS product that was already in production. And it's a good experience. So uh this talk is about uh realizing what is possible when it comes to

0:49

uh a modern UI, a rich UI. on the web. So I'll start by breaking some misbeliefs about front-end development. I will show you our UI, I will show you some code. Then I will tell you our story and finally I will share some thoughts and learning about all this. So um this is the the cover of HTMX Twitter account. Um it's Creative Commons, by the way. Um You've heard for too many years now that for a reach UX on the web

1:36

you need you have to go the React way. You have to To build an API and build a single page app and you will have everything you need. Uh probably the reality is it's a bit more open than that. Because what makes a UX rich? Probably there is something about making the user forgetting they are looking at a web browser. For example, when uh the user acts on your uh interface and uh they changes the the the application state. You want to react to this change and you don't want to reload a full page because it's so

2:22

20 uh05 Another part is you you want to have some beautiful UI elements, uh smooth, reliable, reusable, accessible, like the ones you've got on your phone. And you've heard that to get all this you need to go the JavaScript application framework way, like React or something else. But when it comes to reacting to application state changes, you You will hear that you need an application on the client side to to duplicate the application state on the client side to

3:12

be able to react very smoothly Probably there are other ways and HTMX is one of them. So HTMX, what is it? Basically it's listening to JavaScript events in order to fire some Ajax calls, getting some HTML fragment and inserting this HTML fragment into the DOM. That's it. When it comes to web components, because that's I will that's what I was talking about when when I said rich UI elements The best way, the the design pattern to get rich UI elements

3:59

is to build isolated reusable components that uh that are pieces of HTML code, CSS code, and JavaScript code. that will work together in order to get some beautiful UI element that you will be able to reuse anywhere in your application and even in other applications. And we were told that in order to achieve that, we need JavaScript application frameworks that force you to think component oriented. and to get web components. Now is it possible on the server side in Django world? Yes it is. This guy

4:44

implemented some library that m that allows you to to get uh web components within Django templating and I will show you some code about it. Now it's demo time. I will show you our UI in our product and production. It's a quite sophisticated screen that I will show you when it comes to UX. I will present it briefly first and then I will Dive into two features I want to show you to illustrate application state changes and UI elements

5:30

So there it comes. So this is a um a screen that is um quite central in in our user experience. At the top you've got a navigation timeline. So it's a series of steps when you Click on one of them, you get a beautiful animation, you get some stuff that reloads on the bottom of the page. I can close that for now. On the right column you get a text. It can be a huge text, but it's just text. The rendering is very quick. This text is split into articles. The articles can be seen

6:16

just when opening the table of contents. I can mark an article as favorite. When I close my table of contents, my article has been marked as the favorite here. Is it client-side application state management? No, it isn't. It's HTMX. It's just a JavaScript event triggering some very, very uh located uh reload On the left side you've got a list of items that are related to the text. This list of items can be quite huge. Here we have more than 1,000 items in this list. It's huge

7:02

and it works, it doesn't lag. And um this list can be filtered For example, by articles, there are two ten items related to article two. Easy HTMX stuff I can also search something. They all match. And let's reset. Now let's dive into one feature that illustrates quite sophisticated application state management.

7:48

that you you could think it is at least. So in this face set filter I have all my articles with uh counters of results And at the top of the of the filter I have a special bucket here which is all the articles I'm interested in. All the articles I marked as favorite. So for now I have only article one and article two as favorites So the counter is 127 results, because it's 117 plus 10. What happens if I'm not interested in article first anymore?

8:34

Just here, the counter has been updated. Is it some client-side application state management? No. Is there some JavaScript for achieving this? No. Zero line of JavaScript. This is just HTMX all the way. Do you want to see how it works? Let's dive in. So this is the jungle view for the watch button. I hope this is readable on big screen. Uh obviously I have a post method and uh when I build my HTTP response with the star uh becoming yellow or green according uh

9:19

uh uh according the post or delete method. Let's join this HTTP header, which is a special HTTP header that HTMX understands on the client side. Now my small counter here, actually it's the the whole line in my HTML template, which is here, it's just an empty div With a bunch of HTMX attributes, and this MTDiv is about to get its content from the server on page load and also

10:04

when an article is watched and when an article is unwatched. This is quite simple, isn't it? And then you have application state management without writing a single line of client-side code. The second feature I wanted to show you is about uh rich UI elements. Uh actually you've seen them already. It's these face ed filters. We have three of them It's actually a quite sophisticated UI element because it's a custom drop-down. You've already did probably uh such things. Um I can close it when I click anywhere, I can close it by hitting escape.

10:53

There is some internal search Oh, there is no article uh I mean not an article article one and article nine for example This is some JavaScript, of course, because it is client-side pure user interaction. But these elements are actually web components made on Django side. So I have a face set template which is a regular Django template that will uh uh take some input, uh the the the buckets, the values, uh

11:39

what the user selected, etc. And this face set, this HTML template is working with in my static folder, components, facet, I have some CSS code. And I also have some JavaScript, for example, to handle the internal search stuff. We use stimulus on JavaScript, but you can use whatever you want. And all of this is working together through Django components and Django components allow you to declare a component here that make

12:24

that bring together uh the template, the CSS and the JavaScript, and that makes you able to to pass some data into it. And this is how you achieve uh UI web components on uh server side with Django components. And how do you use it? I will open my base template again and here it goes we were there uh two minutes ago uh you have your component And so it's really completely reusable. I have another one here for another field in my data.

13:10

And uh I pass the the the buckets into it, I pass whatever you the user selected in order to to mark them This way and uh uh I have slots, slots allowing me to to do special stuff to Customize for example this filter you've got some color dotside the values aside the bucket names Here it goes, I have my slot and I have the possibility to to customize some stuff in there. So it's reusable, it's isolated.

13:58

We can unit test it if we want, we can upgrade it, add some features independently from its usage in our application. And that's the whole point of web components. So that's the end of the demo part. Um I hope at this point you are convinced that Yes, our UI is quite quite rich, offers a rich user experience, and uh no our code is not spaghetti code because we don't have code. HTMX does everything, almost everything for us. Now, about our experience at context. The road wasn't always like this. The project

14:44

this project started in uh 2017. Um it's a quite complex project, uh especially on the back-end side. There are many um domain uh complex domain stuff. But on the front-end side, in 2017 we were a very very small team. It was our first SaaS product. And we asked around us, how do we do that? And everybody told us the same thing. It's 2017 guys, uh go the React way uh build an API, uh build an SPA, and uh you will achieve uh client-side application application state management, you will get um separation of concerns

15:30

uh between your back end and your front end, you will get uh web components. It's the modern way to go. So we tried it. We hired a JavaScript developer. I was in charge of the API among other things. And It was quite of a kind of okay. Uh we were able to to to deploy it to production. But the UI vas was very, very slow. Because the API contract was not uh optimal because the the dumb tree uh was way too deep and as as you

16:15

as you have seen we have lots of information to to put into the browser And uh we had very very low team velocity and that was a big problem because we were trying to launch a product. Uh we were trying to to have people buy our product so we needed so to to to be agile about it. And uh there were no code quality on the front end side because the JavaScript developer was alone and he was overwhelmed with all the complexity of making an SPA. So when I heard about

17:02

Phoenix LiveView in the Elixir world, when I heard about Hotwired in the Ruby world, when I heard about Unpoly HTMX I had an idea, I created uh a proof of concept, uh I duplicated our UI, which was all React, I duplicated it with uh several rendered Django templates and just a bit of HTMX. In one month of work, the code was ugly as hell, but the proof was there. It it was working, the performances were good. Let's refactor it. One month later we had web components, we had uh code quality, we had

17:48

we even had tests that we didn't have before on the on the React world. So Consequences on the UX were there some negative consequences on the UX? No, we we made no trade-offs. I can't think of a of a feature we used to have and we don't have anymore And it open it even opens some new possibilities, some new opportunities. For example, on the the the left column you've seen earlier, which has many, many, many items Uh on the React world, uh the the dumb tree was so deep and so heavy uh that This column

18:34

was able to display only 50 items at a time and so you had to scroll, to display, to replace the 50 items, etc. It was terrible. Now that we have a quite clean and uh as light as possible dumb tree We are able to display thousands of elements and no lags. What about webperf? We measured time to interactive On three scenarios, Django and React, Django API and React on first load, then on second load. And with HTMX. HTMX is

19:21

at least as fast as the React second load. On first load is way faster. And it happens that in our use case, users often get to our UI through a diplink that they receive by email. So the first load is really important to us And React was just not the right fit for it. The memory usage on the client side is also very lower, much lower. So this is good news because we will We will stop hearing our users crying for a new laptop every six months, which is good for the planet. What happened to the team?

20:07

Obviously, uh the JavaScript developer left because we didn't need here anymore. But the other two, uh we were quite stuck in our backend only role. Uh the The the most beautiful demonst demonstration I did after each sprint was an API endpoint with JSON. Now we are full stack and we are able to collaborate with designers. and also obviously continue working on our compli complex uh back end issues

20:53

but um We have a much wider scope and this is much more exciting as as a developer, at least from my perspective. And this allowed also us to explore new project management methods because we are now able to make the developer uh in charge of uh a feature from the beginning to the end uh by uh exploring data, by uh exploring uh user scenario, working with the developers It's great. I don't even need to comment this slide, I let you enjoy it.

21:38

That this is uh these are lines of code in our code base. We deleted fifteen thousand lines of code Now, um when it comes to you uh because I'm a bit here to convince you but uh I'm here to to to give you all the keys all all the keys uh I think you need to make your own decision You need to ask yourself what do we need more as a team, as a as a business? Because

22:24

in the beginning of this presentation I told you that people who recommended React to me uh talked about uh reacting to application state management. Okay, this is over. They talked to me about web components. Okay, this is handled. They talked to me about separation of concerns and from that perspective with HTMX we have uh less separated uh code base and um to me it's a good thing because i like to be uh a a full stack developer but If your team is is used to separation, uh heavy separation of concerns between back-end and front

23:09

end, maybe HTMX is not the best way for you. But uh what HTMX gave us is product agility. We are now able to ship much faster, much, much faster. uh we we have no more uh endless debates about API contracts etc uh so if product agility is uh A big thing for you. Maybe you should consider HTMX. Another question is, what is front-end development? Uh if some of you hate CSS, maybe

23:57

maybe you should consider um an architecture that allow you to focus on the back end and let other people work on the front end. But that doesn't necessarily mean uh React or JavaScript application framework. But if you think that front-end development is about taking some data from the database and exposing exposing the data to the user in a beautiful way, make the users interact with your data. and saw store the data into the database, maybe HTMX is the way to go. I'm I think I'm done almost. Um here are the key takeaways for m

24:43

for you. The first one if is if you had some doubts about HTMX, does it work on a real project, a real product? Yes, it works. People are paying for the UI that you've seen earlier, so it works. Um for a small team like us, uh on a B2B SaaS product It makes us very happy. So if you're in the same position or in if you're in a similar position, maybe it would make you happy. And the most important thing is that with HTMX, with Django components as well, now you're able to make your own choice

25:29

about What architecture will we implement for our front end? This time I'm really done Uh I would like to give a special thanks to my colleagues at Context. Uh I'd like to to tell you that uh this awesome company gave me the the opportunity to work on this presentation in my working time my my working time so this is great And the people you see here gave me feedback about the presentation. They helped me rewrite it three times but it was great. And the girls of the tech team took care of

26:14

our tech stuff while I was working on this presentation. So this is good. And thank you for your attention. You can't find me anywhere else than on GitHub. I have no social network. And I have one more thing. uh if there are if there are some French here. Uh we are hiring so let's meet later

Questions this talk answers

Can HTMX deliver a rich user experience without React?

Yes. HTMX can respond to events with Ajax requests, receive HTML fragments, and update only the relevant part of the page, while Django components can provide reusable rich UI elements.

Discussed at 1:36

How can HTMX manage application state without client-side JavaScript?

The server returns the updated HTML, and HTMX swaps it into targeted elements. For example, counters and favorite states are refreshed through HTMX requests with zero custom JavaScript.

Discussed at 8:34

How do you build reusable web components in Django?

A Django component combines a template with its CSS and JavaScript, accepts data and slots, and can be reused in different parts of the application. Components can also be isolated, unit-tested, and upgraded independently.

Discussed at 10:53

Why did this SaaS product replace React with HTMX?

The React version had slow UI performance, an overly deep DOM, low team velocity, and front-end code-quality problems. A Django-and-HTMX proof of concept worked well, and the team later refactored it into a cleaner component-based implementation.

Discussed at 15:30

Is HTMX faster and less memory-intensive than React?

In their measurements, HTMX was at least as fast as React's second load and much faster on the first load, which mattered because users often arrived through deep links. Client-side memory usage was also much lower, and the UI could display thousands of items without lag.

Discussed at 18:34

What effect did moving from React to HTMX have on the development team?

The remaining developers became full-stack developers who could collaborate with designers and own features end to end. The migration also eliminated about 15,000 lines of code and enabled faster product delivery.

Discussed at 20:07

What are the tradeoffs of using HTMX instead of React?

HTMX provides less separation between the back end and front end, so it may not suit teams that strongly prefer separate codebases or responsibilities. In return, it reduces API-contract debates and can significantly improve product agility.

Discussed at 22:24

Does HTMX work for a real production SaaS product?

Yes. The speaker's company runs a paying B2B SaaS product with a rich HTMX interface, and the team considers the approach successful and well suited to a small team.

Discussed at 24:43

Presenters

Note: We understand that names change, people change, and bodies change. We respect each individual's journey and privacy. If you have any concerns about a video or need us to remove content, please don't hesitate to contact us. We will handle your request with care and promptly address any issues.

More videos from DjangoCon Europe