Django + HTMX: Patterns to Success

This video features Lucas Pires at DjangoCon Europe 2025 in Dublin, Ireland.

Django + HTMX: Patterns to Success
0:29:39
Published June 4, 2025
2,950 views

Talk: Django + HTMX: Patterns to Success by Lucas Pires

https://pretalx.evolutio.pt/djangocon-europe-2025/talk/W7NRA7/

Summary

Lucas Pires argues that Django and HTMX can deliver productive, maintainable applications without splitting work between a Django backend and a JavaScript SPA. He recommends server-rendered, independently loaded partials; class-based views and reusable components; semantic HTML; and clear strategies for keeping multiple UI sections in sync. HTMX is a strong fit for CRUD-heavy applications with server-side logic, while complex client-side state, offline use, real-time collaboration, or highly interactive widgets may call for Alpine, web components, or a hybrid SPA approach.

Key takeaways

  • Load dashboard sections as independent HTMX endpoints so each partial owns its business logic and can be reused across the application.
  • Use class-based views, custom mixins, and component-driven templates to reduce boilerplate and keep Django code and markup maintainable.
  • Build reusable generic components such as tables and toasts, then extend them with components tailored to particular models or use cases.
  • Keep dependent UI sections synchronized with larger swaps, out-of-band swaps, or dispatched events, depending on the complexity of their relationships.
  • Use semantic HTML, browser APIs, Alpine.js, or custom directives for progressively more complex client-side behavior rather than putting everything in inline JavaScript.
  • Choose a hybrid approach with web components or a frontend framework when the application requires substantial client-side state, offline support, real-time collaboration, or intensive DOM interaction.

Summarised automatically from the transcript.

Transcript

4,128 words · auto-generated Show

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

0:06

Speaker 1: Hello everyone. I'm here today about to talk about some patterns for developing with Django and HTMX. Uh the the inspiration for this talk was because there's a lot of tutorials and guides online, but there's not a lot of like uh Code snippets production based uh uh examples. So this talk tries to to give a bit of an insight of my experience in the last few years. Um We can start with that. My name is Lucas. I'm from Porto, Portugal. I currently work at CzechSec maintaining some uh Django applications. I've been working with Django for more than five years and three years with HTMX Besides my full-time work, I also developed some freelance

0:53

Speaker 1: applications for small companies built using Django and HTMX. And they've been a one developer job and always worked flawlessly with this tech. So, first, why did I embrace HTMX? So, three points: the simplicity. I've always worked at companies with small teams. Those teams usually need to look at the entire scope of the application And even if you bring a simple single play uh single page application with React Angular, it's gonna bring a lot of complexity to the to the global project. Next, because I and I think most of you like Django or love Django. Django includes all the features you need to build a complete app.

1:40

Speaker 1: But in modern days you usually need a bit more. Building an SPA means that you need to Take part of your time to use other tools that might not be such such good as Django. For example, using Django Forms, you're basically building SPA, might not use it as much, or template, for example. And finally, productivity. HTMX allows me to ship features and applications faster. Do proof of concept for higher management. iterate much faster than having a split back end and front end because I need to ask the front-end team to build an interface while using HTMX I can control both the business logic and also the presentation layer

2:28

Speaker 1: Uh another benefit is because I'm dealing with HTML directly, I can prototype uh various interf interfaces without using uh Figma or other design tools. So, first let's look at what HTMX brings to the Django developer experience. For my point of view, HTMX can be used to provide the small UX UI improvements to a regular MPA. Or you can implement the look and feel of a single-page application without the need of a single-page application framework such as React Angular Svelte. So that's basically the focus of maybe some of you already heard of hypermedia-driven applications. You try to maintain the most states on the server.

3:14

Speaker 1: And the API usually delivers both operations and data at the same time using HTML. So here's a uh a quick example of what kind of differences they have between single-page applications and upper media applications. Single-page applications usually need to maintain states on the business side and the UI. The API usually is serialized, JSON only provides data. They are great for high interactivity because you control everything on the client, but you require a serialization layer, which it's an extra step. An HDA usually maintains the business logic on the server. UI is maintained by simple JS libraries such as Alpine or HTML. And you provide with each request both the date and operations inside uh the response.

4:04

Speaker 1: And of course doesn't require serialization because it goes directly from the ORM to the templates. So here we are going to look at uh most of the sections of a Django application. The models maybe not so important for HTMX development, uh so we'll focus more on views and templates. So starting with the views , a good pattern is to create views as on-demand entities. So basically you load partials directly on the HTML There are several blog posts and tutorials calling this pattern lazy loading, trigger on load. But the idea here is that you build endpoints with separate sections, partials. And you load them directly on the HTML.

4:52

Speaker 1: So for example, the usage here is that you do hx target this , trigger load, and you will load the endpoints directly on that HTML element. So we have here an example. We have a section that loads the list of projects. The list of projects will only fetch the necessary UI for that. That way you can have multiple uh UI sections just by duplicating that HTML uh section And your code is isolated. Your in this case this is a project list, so the responsibility and the business logic of listing the projects

5:37

Speaker 1: will always be respected because you're just loading that view with that section. So here's the example. Basically, the idea is to build your views so that you only load the necessary HTML to display it. But how would you build a complex page? This is a good example. We have a dashboard. Where we want to display the latest uh project from a customer, the stats of the customer, and the project uh list. Instead of building partials and combining them into a single view, each view is loaded directly on the HTML, and each section has its own business logic, so it won't break unless you modify them internally.

6:29

Speaker 1: Okay, so here is an example. Uh the main dashboard will just load each partial. as the page is rendered. So basically you have independent endpoints instead of building a view that uh uh reacts to actions in partials. Each section will have its own responsibility, its own business logic. Uh and you can replicate it easily be uh along your application just by repeating those sections. But you can use div or anything else. It's this is a 30-minute built example of how it would look. Very simple, not very pretty. But each card is loaded by a separate endpoint. So

7:14

Speaker 1: each each endpoint has its own responsibility and you can use it along the side the app without any problem. Next um I like to favor uh class-based views over function-based views, especially because you have a lot of boilerplate code uh on the internal mixings of Django, so context mixing, single object mixing, that you can compose and create. Views suited for your project. Also, because they are internals of Django, it's easy to spread the information, is easy to spread uh knowledge between team members and if used correctly by knowing how they work it can uh give you huge productivity boosts by removing boilerplate

8:00

Speaker 1: Building custom mixings from the ground up can be also useful for permission checking that you can spread between all your views, contacts injection, and other types of common actions. So use a lot of composition on class-based use. At the same time, crude is uh a simple operation when used with HTMX because you can do delete actions in a form or an anchor So it works like a DRF view set. Uh you can build your own uh crowd view or you can use external package uh such as Neapolitan. So next, let's look at some uh templates templating uh tips. Uh HTMX pairs very well with component-driven design.

8:45

Speaker 1: So the idea here is not only to use partials, but components. So components can be unitary and reusable self-contained elements, very simple elements that you can repeat alongside your app. Product item, table, toasts, paginators. Using components usually makes templates easier to read, allows you to replicate uh uh partials or in this case components very easily. And there are a lot of packages that address this limitation. Partials. We can think of partials as composed UI sections. So sections that have other other partials or other components, such as a profile menu, a related product sidebar, action sidebar.

9:33

Speaker 1: So it's basically a type of UI that you can aggregate and give it semantic value. Right now there are a lot of component packages Uh there's cotton slippers Django components. Django five point two also introduced the simple block tag My go-to option right now is Django Cotton because it uses a very similar uh feel to HTML, so it blends right into the into our templates It supports a lot of features that the regular include tag doesn't. So you can pass a lot of complex objects. You can have multiple named slots. And you can even uh do dynamic component inclusion. So if you have a variable that

10:20

Speaker 1: translates to a component name, you can uh dynamically introduce it. That's good to build like custom fields, forms with custom fields, where you don't know beforehand what type of fields are you going to render on the template. Next, after we have a solution for the lack of components, we can look at the structure. Uh having a well-mantained structure is uh a good a good advice. Helping uh helps consistency. standardizes styling and maximizes reusability. Uh a good way of having a a good structure, I would say, is to have a two-tiered component structure, a very uh a bit similar to how views, generic views work. where you have generic components such as a table or a menu

11:06

Speaker 1: or a toast. They have a layout template with where you can fill slots with uh specific data models or specific data use cases um that are filled by specific components where you can create them as is or extend from the base components uh and create a component for a specific use case, data model, etc. Examples are the use table, the user table, the error toast, etc. But maybe that's easier by looking at this example. This could be a generic component where you customize the table as you see fit. You describe the slots you want to fill and the a concrete or specific component will be a table bound to a data model, in this case a product a project table.

11:57

Speaker 1: This is the result. Here we can see a good way to determine what can be partials on your application and what can be components. If you look at your UI and you have uh the smallest components that are repeatable, usually the leaves here on the graph, are should be components and all the others should be partials. So next, uh we can look at some tips to improve HTMX inside your Django codebase. Try to use the closest uh attribute. The closest attribute uh swaps the most close parent That you specify.

12:42

Speaker 1: This is useful for if you have, for example, a delete button on a table and you want to swap the entire table. It's easier to do close a table and it's more clean than doing something like Specific ID because a specific ID is can be error errored and having a syntax like this is more generalized and less error-prone Next is uh an obvious one, but always try to feed to provide feedback to the user. So use the HX indicator. Uh display page transitions to show that requests are in flight. Display errors by overriding the HTMX response error JavaScript event.

13:28

Speaker 1: That's easily achieved by just displaying a model saying that there was a request error. And finally uh use tooling improved to uh use tooling design to improve developer experience. So use Django HTMX. It's a great package to streamline your HTMX usage inside Django. And as stated before, use component and partial packages to overcome limitations on templates. Next, we can look at some ways of maintaining the state in sync. Since when developing with Django and HTMX, you need to address state management on the server It can be a bit trickier because you need a different mindset

14:13

Speaker 1: than from building apps with front-end frameworks. So a very common pattern is to have uh multiple uh multiple partials with uh independent states. And certain user actions or operations can translate into actions that uh, or in this case states that affect multiple UI sections, not only the one that you swapped. So looking at a very simple example, if we submit a form that edits the product's name and we only swap the form, we're going to get stale states on the list. Because we changed the product name, but the list on the side didn't have any way to know that you changed the product name So basically this creates a state dependency. There are a lot of ways to approach this.

15:00

Speaker 1: I'm gonna present some, but uh feel free to add. The first and more simple one is to just extend the swap area. So we'll swap both the list and the form. This is useful if you have closely related partials. If you can deduce or calculate easily the context of the other partial, or you can load it on demand. You can also add the business logic of the list context into the edit view, but that breaks the single responsibility. So you want each partial to be fed by different uh endpoints so not giving more than one um feature in this case

15:46

Speaker 1: function to to the same endpoint The second option is to use out-of-band swaps. So for those who don't know, out-of-band swaps is an HTMX feature that allows you to Target different DOM elements in the same response. It's useful when you have partials that are not related and you can final uh easily deduce the dependencies on their context. Finally, there's the the option of dispatching an event to other partials. This is a bit trickier because it requires you to uh implement event management. But it's good when you have complex dependencies and a lot of unrelated partials.

16:31

Speaker 1: Next we can look at some ways of improving HTML templates. Try and use semantic HTML tags. Those tags are easy to target or swap instead of having complex naming. Using tags such as uh header, a footer, uh aside, etc. It's easier to target those than have complex naming. Use the dataset property and data attributes to stores uh information on your HTML. Favor web APIs over JavaScript libraries, it's uh just adding another layer of complexity. And uh like the semantic HTML, try to use modern HTML elements for small UI instead of relying on JavaScript libraries.

17:20

Speaker 1: So for example, dialogue instead of adding a bootstrap model. uh details input type search it gives some small UI improvements uh that can be beneficial. Next would be to s to know how your client-side interactivity should be presented on the template. So try to avoid inline scripting. Use lows low overhead frameworks in this case libraries such as Alpine. js and Dyperscript. When using external JS libraries Uh wrap them in a declarative way so your your uh templates maintain consistency. And when using very high interactivity or reactivity, um

18:06

Speaker 1: Move them to a custom Alpine directive or abstract them using proper tooling. This means uh implementing a web component using React, Svelts, Angular that you just can drop in inside the the template and it reduces uh a lot of verbosity and helps maintaining the the template easy. Once again , scalar interactivity, so low interactivity alpine statements, medium interactivity custom directives And finally, high interactivity, scale it to web components. This is uh a bit of a correlation with the balance between two two points, the locality of behavior and separation of concerns.

18:53

Speaker 1: HTMX tries to favor a lot of locality of behavior, but a lot of the times in complex projects it cannot be the best option. It needs to be a balance between those. So we favor locality of behavior by reducing verbosity on complex elements, complex state management, complex uh data. We try to maintain the most functionality possible without requiring multiple files, but at the same time we try to favor sec uh favor separation of concerns by moving Complex interactivity that's not easily apparent on the file to a different file. js statements scale, move them to its own declarative custom directive.

19:40

Speaker 1: And if you really need a lot of state management, client-side state management, uh migrate it to a proper tool like an SPA framework and export it as a web component. So is Hinmax a good fit for your project? I think so. Most cases, yes. If you have a very crude-heavy application, you don't need a lot of complex business logic on the client side, but you have on the server side, that's no issue. And you don't need a lot of DOM manipulation, it's perfect. But if you if you need real-time collaboration, a lot of JS libraries. offline functionality and every client side state, it may not be the rest of the best uh

20:26

Speaker 1: platform to to work on But you can still use it. You can use a hybrid approach where you limit certain scopes of your application into islands And you build them using a web component and you communicate via JSON API or REST API. This is very similar to front-end islands in the front-end realm. Uh you build the entire app using HTMX and limit certain pages to use uh or load the view into a framework, uh front-end framework. And you can also use polling and server-side events for with HTMX to build more interactive UIs. So finally,

21:11

Speaker 1: what does HTMX can bring together with Django? You can use other similar ideas with Django. There's Data Star, Django Unicorn, and On Poly, and they work very well with Django. Uh try to use Vue Transitions API. That's uh a recent API that allows you to make SPA transitions without CSS just by enabling Uh configuration and all the swaps with HTMX will have transitions. If you need some kind of heavy state uh swapping The Ajax preserve through option. It's a very recent addition. Allows complex elements to move to be moved

21:57

Speaker 1: uh along the DOM without losing state. So if you have a YouTube video with and you try to move it with this option on, it will move the video and continue playing where it was while before it wouldn't. It will start from the beginning. But this is a very complex use case and it's not implemented on all browsers. And finally, uh I wanted to give a shout out to a point by creator by the creator of HTMX that is stability as a feature. HTMX is trying to maintain itself the same from now on so that all projects using it will not need a lot of maintenance or no maintenance at all.

22:42

Speaker 1: And work the same way as they work now in five, ten, fifteen years, which for some some projects might be a relief. So thank you for listening and have a great job of gun.

23:07

Speaker 2: Um you said that you would um that you could do almost every application uh with HTMX uh whatsoever. Let's say your task would be to write a date range picker Would you use HTMX or some other technology?

23:25

Speaker 1: For a date range picker.

23:27

Speaker 2: Date range speaker.

23:29

Speaker 1: I'll probably use uh Alpine. js for that. Uh I would probably sorry. I'll probably use Alpine. js for that. Okay It seems to be to have very little logic. Uh it might have some tricky edge cases, but mostly with a few statements and some clever JavaScript, I think. It would be a good option.

23:53

Speaker 3: Thank you for your talk. I enjoyed it. Around the question of building your going back to the views and loading a bunch of partials. Can you give me any warm fuzzy feeling that this is not going to end up with loading it and having a spinner and a spinner and a spinner that you have to wait for like Is it faster in your experience than you see with the JavaScript things? There's so many things I use nowadays, these spinners, and all I see is

24:20

Speaker 1: Like um if you have uh a lot of uh background, so let's say if you load on databases, it's gonna have some spinners, right? But from my experience here I've seen a lot of front-end applications where you get the data and it's still rendering and it still has a lot of spinners or shadow transitions. So I end up it It's more of like scale fast.

24:44

Speaker 3: Okay.

24:45

Speaker 1: But with caching and other I think other tricks where it can be improved or combining views into one If it's a common used page.

24:54

Speaker 4: Okay, I like uh HTMX when uh everything is on the same server, but what about if the data are on another site and you have to fetch them I tried it and it worked but it really felt clunky because you always have to adapt the URLs or do you have any trick uh how that can be made easier?

25:15

Speaker 1: So you're you're talking about fetching directly on the template from another

25:20

Speaker 4: from another website, from another Django project. Both are Django projects, but we have to display it on one CMS website, but the data

25:29

Speaker 1: You're giving me a website and iFrame iframe nightmares. Uh I never had to to do something like that. But uh Okay

25:39

Speaker 4: in the end I thought uh Svelte is better I do did a similar project.

25:50

Speaker 1: to build uh wrappers or small web components.

25:55

Speaker 5: Hi, thank you for the interesting talk. Uh were we talking about the code base size itself when you compare the same app using Django and HTMX versus Django let's say React do we tend to write a lot more code with HTMX?

26:10

Speaker 1: You'll you'll tend to write a lot more Python But even if you add the Python in my previous use cases, uh we've tr uh we've tested the LOCs and uh ends up being way smaller than having the React and the DRF. But you tend to write more Python, a lot more. Yeah

26:33

Speaker 6: Um do you have a link to the slides? Because uh they contain quite a good

26:39

Speaker 1: I I can share after the talk.

26:40

Speaker 6: Okay, sure. Thanks.

26:42

Speaker 7: Hi. Thank you for the talk. Um I have more like a business kind of question. Um how do you find uh clients? Because Ishtimec is like uh three, four years old or something. Um how do you find like uh

26:56

Speaker 1: In freelance uh usually in freelance uh jobs I had the the the the choice of being able to to use HMX in work uh I guess I've been lucky. And I've always worked at small companies, so small teams, even if their products are huge And there was a an option I think or a use case that most people I think might come one day is that uh front end takes a lot of time and we need an alternative. And I always have had that luck, I guess, to end up on places where I could use HMX.

27:38

Speaker 8: Hi, thank you for the talk. Um I know that you can use uh template partials uh inline rendering. So uh how complex is to get the SEO right in this case? I know that you've been talking a lot about uh rendering dashboards and everything, but for uh simple pages, well, that can get not simple in the long run.

27:59

Speaker 1: So we're talking about template partials?

28:01

Speaker 8: How complex in your experience was actually using inline rendering?

28:06

Speaker 1: Inline rendering?

28:07

Speaker 8: Yeah, of template partials. Because

28:10

Speaker 1: it's it's just uh like I showed it's you have an endpoint, you delimits uh what you want to show with with it, and the HTMX loads uh the partial. By loading it inline. So it's just that

28:26

Speaker 6: okay. Thank you. Hi. Thank you for the presentation. I just have one uh question regarding HTMX. Is it possible to swap multiple things at once with out-of-band swaps? Because uh when I tried a few years ago it was only possible to swap one additional thing by ID, right?

28:43

Speaker 1: Yes, it's multi uh what out of band swaps It's a feature from HTMX that allows you to swap not only the main target, but other other elements inside your response.

28:55

Speaker 6: Thank you.

28:56

Speaker 8: Thanks for the talk. I was just wondering how do you know like when to actually escape into like a React or s uh

29:04

Speaker 7: Svelte for web components?

29:06

Speaker 1: Uh when you have a lot of client-side state. even when using low overhead libraries such as Alpine, uh when you have a lot of uh moving parts uh When you need proper state management, you see that the UI is becoming clunky, then it's when you scale it to a front-end tooling.

29:29

Speaker 8: Thank you, Lucas, for your presentation.

Questions this talk answers

Why use HTMX with Django instead of React or another SPA framework?

HTMX keeps the application simpler for small teams, preserves Django’s forms and templates, and lets one developer control both business logic and presentation. The speaker also finds it faster for prototyping and shipping features.

Discussed at 0:53

How should I structure Django views for HTMX partials?

Build views as independent, on-demand endpoints that return only the HTML needed for a particular page section. Each section then keeps its own responsibility and business logic, making it reusable across the application.

Discussed at 4:04

How do you build a complex dashboard with Django and HTMX?

Load each dashboard card or section from its own endpoint directly in the page, rather than combining many partials in one view. This gives each section independent business logic and allows the sections to be reused elsewhere.

Discussed at 5:37

How should I use components and partials in Django templates?

Use small, repeatable UI elements such as tables, toasts, and paginators as components, and use partials for larger composed sections. The speaker recommends a two-tier structure with generic base components and specific components bound to a use case or data model.

Discussed at 8:45

How do I show loading and error feedback with HTMX?

Use an HTMX indicator to show that a request is in progress, and handle the HTMX response-error event to display an error message or modal. Page-transition indicators can also make navigation feedback clearer.

Discussed at 12:42

How can I keep multiple HTMX partials in sync after an update?

You can expand the swap area to update related sections together, use out-of-band swaps to target several unrelated elements in one response, or dispatch events when dependencies are more complex. The choice depends on how closely related the partials are and how complicated their state dependencies become.

Discussed at 15:00

When is HTMX a good fit, and when should I use a frontend framework instead?

HTMX works well for CRUD-heavy applications whose complex logic is mainly on the server and that do not require much DOM manipulation. Real-time collaboration, offline support, extensive client-side state, or many JavaScript libraries may call for a hybrid approach or a frontend framework island.

Discussed at 19:40

What should I use to build a date range picker with Django and HTMX?

The speaker would use Alpine.js rather than HTMX because a date range picker generally involves a small amount of local client-side logic, with only a few statements and some JavaScript for edge cases.

Discussed at 23:29

Does using Django and HTMX require more code than Django and React?

It usually means writing more Python, but in the speaker’s experience the combined codebase is still substantially smaller than a Django REST Framework backend paired with React.

Discussed at 26:10

Can HTMX out-of-band swaps update multiple elements at once?

Yes. Out-of-band swaps let one response update the main target and additional DOM elements, so multiple elements can be swapped in a single request.

Discussed at 28:43

How do I know when to move part of an HTMX application to React or Svelte?

Move to frontend tooling when the client-side state has many moving parts and the UI becomes awkward even with a lightweight library such as Alpine.js. Proper client-side state management is the signal that a web component or frontend framework may be more appropriate.

Discussed at 29:06

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