Django + Alpine.js + htmx Ups & Downs with Karen Tracey

This video features Karen Tracey at DjangoCon US 2024 in Durham, North Carolina, USA.

Django + Alpine.js + htmx Ups & Downs with Karen Tracey
0:46:09
Published December 6, 2024
2,649 views

A few years ago we started to hear about the toolkits htmx and Alpine.js as a powerful combination that could be used with Django to enable development of web applications that offer user experience akin to a single page application without the overhead of adopting a heavyweight front-end framework such as React. We were excited by the promise and adopted these tools in a few projects. In this talk we'll cover:

The promise we saw in this tool combination
The upside: examples of exciting wins in ways of using these tools that we recommend continuing
The downside: some rough edges and areas of concern where we recommend caution
Our overall assessment and plans regarding continued use of this combination

This talk was presented at: https://2024.djangocon.us/talks/django-alpine-js-htmx-ups-downs/

LINKS:
Follow Karen Tracey 👇
On Mastodon: https://fosstodon.org/@kmtracey
On X: https://x.com/km_tracey

Follow DjangoCon US 👇
https://fosstodon.org/@djangocon
https://x.com/djangocon

Follow DEFNA 👇
https://www.defna.org/

Video production by Confreaks
Follow Confreaks 👇
https://confreaks.com
https://x.com/confreaks

Summary

Karen Tracey argues that Django, htmx, and Alpine.js form a useful middle ground between traditional server-rendered pages and large front-end frameworks. Django retains responsibility for templates, forms, validation, authentication, and routing; htmx adds richer server interaction by requesting and swapping HTML; and Alpine.js manages lightweight client-side state and interactions without requiring a full single-page application. This approach worked well for a greenfield project with complex forms and for incrementally improving existing Django applications, while also helping front-end and back-end developers share more responsibility. The costs are increasingly busy templates, difficult JavaScript and quoting, awkward component and template reuse, and uncertainty about how understandable the code will remain. Tracey considers the combination successful and plans to develop clearer Alpine conventions while investigating tools such as django-formset, django-template-partials, Django Components, and django-cotton.

Key takeaways

  • Django can continue handling server-rendered templates, forms, validation, authentication, and routing while htmx adds partial page updates and richer server interaction.
  • Alpine.js provides lightweight client-side state and interaction without requiring a large front-end framework or duplicating as much back-end logic.
  • The combination worked well for complex forms, incremental enhancements to existing projects, and sharing front-end and back-end work within small teams.
  • Combining Tailwind classes, htmx attributes, Alpine state, and templated JavaScript can make templates difficult to read, debug, and reuse.
  • Tracey plans to establish better Alpine component guidelines and explore django-formset, django-template-partials, Django Components, and django-cotton.

Summarised automatically from the transcript.

Chapters

  1. 0:00 Introduction and Roadmap Karen Tracey introduces the talk’s focus on Django, HTMX, Alpine.js, and the lessons learned using them together.
  2. 2:37 The Promise of Django An overview of Django’s core features and its value as a comprehensive backend framework.
  3. 6:32 Django’s Frontend Gap Why Django offers little guidance for building modern, interactive frontend experiences.
  4. 9:38 HTMX Server Interactions How HTMX extends HTML with declarative attributes for richer server interaction while continuing to return HTML.
  5. 11:15 Alpine.js Frontend State How Alpine.js adds lightweight client-side state and interaction without requiring a large frontend framework.
  6. 13:43 The Django, HTMX, and Alpine Combination The promise of combining these tools while retaining Django’s forms, validation, authentication, and routing.
  7. 14:30 Project Experience Experiences using the combination on a greenfield project, existing projects, and within cross-functional teams.
  8. 18:24 Tooling and Template Complexity The downsides of accumulating Tailwind classes, HTMX attributes, Alpine behavior, and templated JavaScript in HTML.
  9. 22:13 Template Reuse Challenges Why sharing and parameterizing templates becomes more difficult when presentation, server interaction, and client interaction are combined.
  10. 25:24 Assessment and Future Directions An overall positive assessment, along with plans to develop better Alpine practices and explore supporting Django packages.
  11. 29:21 Questions Audience discussion covering HTMX Boost, component reuse, project complexity, JavaScript alternatives, accessibility, Hyperscript, and Tailwind.

Transcript

6,906 words · auto-generated Show

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

0:20

Speaker 1: It's great to see everyone here. I'm very excited to be speaking at Django Khan. My name is Karen Tracy. I can hear myself echoing. That's interesting. I am a Django web developer. I work at Cactus, which is a web development shop right around the corner here. I have been using Django since 2007, I think, so a long time. Um and several years ago, maybe I think it was 2020. I started to hear about this tool called HTMX and then more recently about uh tools like Alpine JS and they were creating a lot of buzz in the community about

1:05

Speaker 1: using these tools and the excitement and the the power of these tools. And at Cactus we took that in and we started looking around at it and we started using some of these tools. And then this year I thought, well maybe it's time for a how's it going kind of talk and then you know what's working out and what's not working out with uh or what challenges might you be facing if you're using these tools. So that's what this talk is about. Um it's gonna Let's see. Oh, I can use this clicker thing. Yes. The roadmap for the talk is I'm going to start with talking about the promise that we saw in the comp in the in this tool combination, Django, HTMX, and Alpine. Uh both individually and in combination,

1:51

Speaker 1: which is probably a lot, you all may have heard some of this already. in other talks and then talk about some of our experience with using this tool combination, what we've done with it on new projects, existing projects. And then kind of switch gears and talk more about some of the struggles, some of the challenges you might face using this tool combination. And then finally wrap up with some assessment and future plans we have. uh for continued use of this. I don't need to walk over there. I can use this thing. I have interspersed some pictures in my uh presentation. to break up the walls of text. I enjoy vacationing in the Outer Banks here in North Carolina. So a lot of these, all of these pictures actually are from Nag

2:37

Speaker 1: 's head. And they're chosen to try and evoke the feelings and the or convey the concepts that I'm talking about in the slides. So they're not entirely random. And in this case, for example, this is A sunrise and a picture, maybe a promise of a of a great day to come. There are some clouds there as well, so maybe there are some maybe it won't be an entirely sunny day. So what is the promise? of Django. I'm kind of conflicted about how much I need to say about the promise of Django to this audience. Given you all probably use Django and know the promise of Django, so I feel like I shouldn't have to say much, but at the same time it is like the big thing. It is

3:22

Speaker 1: our framework of choice at Cactus. It was my framework of choice before I started at Cactus. So there's there's a lot in it and there's a lot of promise in it. It has a powerful ORM object relational mapper so you can access your database. from Python code in an intuitive fashion without having to learn SQL. It has support for migrations, so as your data schema changes over time, you can automatically get your database updated. It has a cool and powerful tool, Contrib Admin, that lets you see into your database. With minimal configuration, you can you can do some pretty powerful things with Django admin, and that's a uh a big

4:09

Speaker 1: Boost to your beginning a beginning any project to be able to just easily see what's in your database. It supports, it has a templating language. For HTML templating that supports reuse in a couple of different ways by extending from templates with defined blocks, or by including little snippets of reusable HTML in your templates. It supports authentication, so you don't have to worry about how to do that properly without introducing security flaws. It has a permissions framework. So you can manage permissions assigned with users, set associated with groups, put users in groups. There's URL routing that supports allowing you to name your meth your view functions

4:55

Speaker 1: so that you can sort of more intuitively. access them in your code. And also forms are a big portion. And there was a great talk yesterday by Josh Thomas, I think, about a modern take on Django forms. And if you didn't see that talk, I'd Strongly recommend you go see it. Forms support both rendering the form and the inputs uh at the HTML level and then gathering the data as it is posted by the form and validating the data. So there's it's a it's a It's a big piece that has some complexity to it because there is complexity involved in both rendering and validating data. Finally, where Django does not have something.

5:43

Speaker 1: Um there is a strong ecosystem of third-party packages that you can that you can take advantage of. One example So you might immediately think of is Django doesn't support a REST framework. So there's an external third-party rest framework package. There have been many actually. Anything that you need to do in your project that is sort of common, you can probably find a third-party package that does it. So the overall promise that I had saw with Django when I started using it and continue to see is it provides all the tools I need to do all the common things of a web development so that I can focus on the unique aspects of the project I'm working on that that are not not uh shared across a lot of different projects.

6:32

Speaker 1: There is one area of modern web development where Django is silent and does not provide. Much guidance, and that is the front end. Django has no opinion on what you do on your front end. You can use whatever CSS framework you like, you can use whatever JavaScript framework you like. It Django is a back-end framework. So it does not say you should use React or Vue or jQuery. You can use any of those things and they will work. So this provides this, this makes things a little hazy in cases where you're facing where you're wanting to do a modern Fancy progressive web

7:17

Speaker 1: application. Like how do you do it? You need more than just your basic HTML, full page reloads at form submissions and full page reloads no matter what you do. So you do need something on the front end, but Django doesn't provide that, got any guidance on on where you might want to go there. Um and over time I guess when I started, the most common thing I saw used was jQuery, which was fine. You could annotate, you could you know sprinkle some jQuery in your projects and get some user inactivity. But over time, more and more front-end web frameworks grew up that became bigger and bigger. uh

8:02

Speaker 1: sort of overlapped in what they did with what Django did. Like for example, the frameworks wouldn't expect the That instead of sending HTML, the server would be sending JSON. And then it would be the responsibility of the front-end framework to take the JSON and turn that into HTML. So you have a template engine from Django on the back end that you're not going to use because actually all your template, all your HTML generation is going to be on the front end. So there's this duality of function and then you face the choice of well which of those do I want to use? And are there cases where I want to use Django templating versus the front-end templating? So there's complications and confusions that can arise and duplication

8:52

Speaker 1: and also sort of a As the what as the front-end framework becomes bigger, there's more and more to learn, and there's less and less likely that a single developer can understand all of Django. and all of the front-end framework. So you get you wind up with teams who either you've got front-end specialists who can do the front-end, back-end specialists who can do the back end, and they dine they kind of don't don't share information. They can't share a lot. So that's where these tools, when we started to hear about them, offered a lot of promise, I thought. I'll start with HTMX. There was a great talk with HTMX with Chris May yesterday, and you mentioned the same thing I have first here on this slide, which is

9:38

Speaker 1: HTML out of the box offers two elements that you can interact with the server with, and that's the form and the anchor tag. And what HTMX provides is to say You can annotate your HTML with more attributes and indicate that this element, which is not a form or an anchor tag, is going to cause a request to the server when the user does this thing. So you can what HTMX provides is more rich server interactivity on your H with your HTML, accomplished by annotating your HTML with additional attributes defined by HTMX. HTMX itself is a JavaScript library that does all the JavaScript needed to do that so that you don't have to do it yourself.

10:26

Speaker 1: Paradigm expects that the server is going to be returning HTML and then you instruct HTMX via the attributes you add to your HTML where you want that returned HTML to go on your page. And it's a dependency-free library. It's really easy to add to a project and it's really easy to get started using it. I had a thought of something else I was going to say here and it went out of my head. I hate when that happens. It'll probably come back to me. It'll come back to me. Uh so HTMX offers More more flexibility. It's an ex it it's kind of an extension to HTML that allows you to interact with the server

11:15

Speaker 1: with more flexibility than than basic HTML. The piece that HTMX does not have is what Alpine JS offers. So with HTMX you can interact with your server. With Alpine JS, you can interact with your user and have data associated with your HTML components that maybe needs to get updated as the user interacts with the page, all without yet communicating anything to the server. So you can annotate your HTML similar to HTMX. You can annotate your HTML with additional attributes to say this div has this data associated with it. And as the user does things in that page, you might increment a counter, you might indicate that the user has chosen this option, and therefore we should show these other things.

12:05

Speaker 1: So it's more annotation of your HTML. And it supports the front-end state maintenance that you might need to keep track of as the user interacts with the page and as you want to change what they're doing. Oh, I know what I want to say on that previous slide. What HTMX offers takes you a long way towards making your web app look a lot more um modern. You can, you know, get server interaction just by scrolling or by uh clicking on something and the result can update just part of the page and that takes you a long way towards getting a a much more rich user experience than you get with out-of-the-box

12:54

Speaker 1: HTML. but it doesn't have this state management. You might need to keep track of state on the front end before you interact with your server. And that's what you can get with Alpine. js, which is Some more attributes you can add to your HTML, also some properties and methods, but it's not big, it's not a huge framework, it's more of a lightweight framework or I'm not sure if they call themselves a framework or a library. It's also lightweight and it's easy to add to a project. So with this combination of tools, I thought we would have a nirvana. Um in combination uh I was hoping we would be able to use all those features of Django that I talked about at the beginning

13:43

Speaker 1: and not like let the not like throw away pieces of Django as we migrated function to the front end. So we could use Django's form rendering and validation. That was always a big thing with me in front-end frameworks. Like you have to validate the data on the back end before you put it in the database. So you need to do something there. And if you need to do it on the front end as well. You're duplicating things if you're doing it, unless you're doing it. So that was always a big thing with me. So I I was really excited by the possibility of being able to use the back-end form framework from Django. that is very robust and allows you to hook in validation that is very sophisticated without having to duplicate all that logic on the front end and make changes in two places when you need it to update things.

14:30

Speaker 1: Similarly with user authentication and URL routing, I thought there's features in Django that I just saw were getting weren't getting used because the front-end framework was doing it and duplicating things. So um I guess in the last maybe it's two and a half to three years we've been using this. Um We had one fairly good-sized greenfield project where we used this combination. It was a project where we had initially thought we would be using React. But as we started to learn about these tools and as the client was interested in also possibly using these tools, he's fairly technical. um uh we decided to take you know take the leap and say, okay, let's try this

15:16

Speaker 1: this tool combination for this new greenfield project. And it had a It had a few phases and it's launched one version of it. But there were fairly sophisticated forms where users had to make choices, and based on the choices they made, other things got shown. And so there was a fair amount of front end sophistication to it. Sophistication sounds a little bit more um I don't know, maybe a little higher than we achieved, but um it was Uh it was a fairly this client was very focused on the UX of the user and making sure that their experience was good. So um we certainly needed something more than basic HTML. And we enjoyed using this combination of tools in building this thing from scratch.

16:06

Speaker 1: We've also added it to existing projects, both little CMS projects, not little CMS projects, but CMS projects with a adding a contact form or something where the H you could use HTMX to submit it and make it more user-friendly. And I've had some one project where I was adding a new feature, which was much like an old feature on another page that had been implemented with jQuery. So my initial thought was, well I'd just like redo the jQuery for this new feature in this new case where I needed to use it. or extend the jQuery that existed. And as I looked into it, I was like, mmm, this is ugly. So I tried doing it with just with Alpine and that worked out well.

16:51

Speaker 1: I the the thing I don't know yet is if I go back to it in six months, am I gonna understand it? Or am I gonna have the same reaction to that Alpine that I had to the jQuery that was there? Um so we'll see. But that was a positive experience for me. I enjoyed doing that. Um and the big thing that uh sort of on non-tangible benefit that I feel like we had as a result of using these tools is more of sharing and blending of knowledge and roles between people who are traditionally front-end and back end. We had s some people who didn't know Django when they joined Cactus and they were front end specialists and Through working with the templates, we kind of all came together in the templates and started to share more about how each of us viewed the world.

17:39

Speaker 1: And we got more with people who could um if you need to add a feature or a function you one person could do it and do the whole thing. Like you wouldn't have to have the back end person do the back end piece and the front end person do the front end piece and then kind of come together. You could have one of them do it and maybe the other one review it and the whole thing would come out better. So there was um more of a More of a sense in our team that this whole project is ours, not like just the back end part is mine and the front end part is someone else's. So I really enjoyed that. We have very small teams, two or three people. It's really hard if your roles are very strictly compartmentalized.

18:24

Speaker 1: So the sort of expanding of the um scope of abilities I thought was really good. Let's see how I'm doing on time. Okay. Um, so is everything bright and slimy? Maybe not. There are some challenges with this combination. Uh maybe I'll walk over here. Uh it's what are the downsides? That was maybe implying this is the downside side of the room. I'm sorry. I didn't mean to I didn't intend that. I just thought maybe I should speak from the other side.

19:10

Speaker 1: Um one downside I found here is uh particularly if you're using tailwind and putting bunches of classes in your javas in your HTML templates and you're adding HTMX attributes for your server interactivity and you're adding Alpine for your user interactivity and state management. That's a lot. It can get to be a lot. And it's particularly odd coming from a very long-term Django perspective where their templates are not intended to be, where you have a lot of logic. Like the Django template language I was taught was intentionally not very sophisticated and intentionally made things not really easy to do so as to force you to put your logic in your

19:55

Speaker 1: models and or your views, like your Python code. So There's a conflict there, I feel, that I'm getting over. But it is a lot. There's a lot of stuff that can end up in your templates. And I worry like going back to this code. Am I going to be able to look at it and say, oh, I know what all this is doing? Or am I going to be kind of confused? Like, what is this piece doing? And I worry about it from the aspect of new people coming onto a project, particularly junior people who maybe don't know all of these tools yet. Are they going to be able to know that this attribute is HTMX and this one is Alpine and this one is Tailwind? So I do worry about that a little bit.

20:41

Speaker 1: There's also some complexity of uh templated JavaScript. uh where you're supplying context variables to your template and including that in your JavaScript. And you kind of have to know that, okay, first the template is going to render this to to a text string that is going to be JavaScript. And how is that going to work? So you have to know how to quote things properly and use Escape. js to make sure that you you don't have weird JavaScript uh coming up where you you've got a that happens a lot with strings. If you've got special characters in your strings, it might work fine without them. And then you test with a few more things and all of a sudden everything's blowing up because you didn't escape the JS. What was a JavaScript parameter that was a string

21:27

Speaker 1: got terminated early. So there's some complexity there with templated JavaScript that you can get around. If you're putting a lot of JavaScript in your Alpine, you can extract it out into JavaScript files and reference it from your templates attributes. But That has its own downside of sort of obscuring what that's doing. We also ran into if you're putting your snippets of JavaScript in your in your HTML as attributes and those are necessarily quoted. So you have another set of quotes you can use inside that if you need quotes. But then if you need quotes within your quoted string inside your quotes What do you do? That can come up if you're using CSS selectors a lot of times. You need quotes within quotes.

22:13

Speaker 1: And you can use ampersand quote to do that, but it doesn't look very pretty. So What else? Oh, it's picture time. That's a lot of birds. A lot of birds doing different things. Making things confusing. Another aspect of this tool combination that I think is a bit of a challenge is reuse of templates. I'm a big proponent of reusing existing code or when I'm asked to do something new that's much like something I've done before, I'm like, well, let's start with this and parameterize it and pass something in so that it knows to do something different, rather than copy-pasting it and changing it. Because I always think, well, six months down the road, maybe I'm gonna be asked to fix a bug in that and I'm gonna

23:03

Speaker 1: am I gonna remember if it needs to get fixed in two places or one place? I think it's easier to have it in one place. It's a little harder when all of your presentation and all of your server interactivity and all of your user interactivity is all in the same place. sharing all you know sharing the same set of code, there's either a lot of parameterization going on, which introduces complexity, or You don't share it. So the ability to reuse your HTML templates I found to be a bit challenging in this tool combination. And a lot of times we we were using um a pattern of doing small snippets of HTML for

23:49

Speaker 1: the presentation aspects of inputs and um Anything that was sort of reused across the site for the styling aspects. But then in some places, if we wanted to have some alpine data associated with it in one case , But not others, then you might find yourself adding some alpine data to an enclosing component that included something. And then the include, you might update the include to say, okay, do this with this alpine data. But then other places where it's been used, you don't have that alpine data. So there's in there's both the problem that that introduces that it doesn't work because you you have get a JavaScript error 'cause you've got some reference to Alpine data that doesn't exist.

24:38

Speaker 1: And there's also the from the looking at the small included HTML template, there's no context for where did this this alpine data come from? So that can be confusing. And also if you're putting JavaScript in HTML files and you're not that proficient with JavaScript. You may miss having your editor highlight errors in your JavaScript code. Maybe that's just me. So Those are some of the struggles that I've ran into with this tool combination. And basically it can get messy. I ran across this one day at the when I was walking on the beach in the morning. I thought, wow, that's a lot of crabs that came out.

25:24

Speaker 1: I don't know where they all went. Um they made quite a mess on the beach. Overall, though, my assessment, our assessment, I think is this is a winning combination and it has a lot of promise. And we do continue to use it. To address some of the issues that I talked about in the struggle section, I think I'd like to come up with some ideas and better better guidelines for alpine component structure. Like when should you have the Alpine, the JavaScript in your template directly, or when you should extract it out into JavaScript files? Maybe you have some guidelines on that. And the other thing I think now that I've got some experience with the problems introduced by this tool combination

26:11

Speaker 1: is I can better understand and appreciate some other tools that exist that I'd like would like to start investigating maybe to use. And that's what I have on the next slide. I've heard about these tools. In some cases, I looked briefly at them, but having um I'm one who uh needs to understand the problem before I accept a solution. Like so if you tell me this is a solution to something that I haven't hit yet, I have a hard time understanding it. So these are several tools that I've heard of. And that now their descriptions speak to me in terms of that might solve a problem that I that I realized we had or an issue we had. One is Django Form Set

26:57

Speaker 1: Which is a package uh that provides better UX for Django forms. And My impression is, I haven't delved deeply into it, but my impression is a number of the things that we wrote from scratch to enhance the user experience of the inputs that we had on this project, this greenfield project we worked on. We maybe would not have had to do if we just used Django form set that I didn't know existed then. Like maybe we didn't need to handwrite all these Alpine components that we came up with. Because Django Forms Set provides a more general approach to enhancing user experience of Django Forms without having to write it yourself. Django template partials is another one that I've heard about.

27:42

Speaker 1: There's a pattern with HTMX that you end up if you're gonna render just uh part of a page. Without Django template partials, you wind up having to extract any of those little parts of pages into their tiny little tiny templates so you can render them. And that's a little bit odd at times. And I believe Django template partials would solve that for us. And then for the lot of stuff in templates and the reuse of templates, there's two things I've heard about. Django Components and Django Cotton that both offer uh ways to build components with Django templates or Extend Django templates. Like I said, I don't know these things yet, but there are two things that I have on my list to sort of dive into and better understand before I take tackle the next big greenfield project that uses these.

28:32

Speaker 1: So I think in wrapping up, this is the beach access, the end of the road where people leave their flip-flops. And I kind of feel like we're all on a walk on the beach using these new tools we've left our flip-flops behind and we may be stumbling across things other people have done on the beach like building sand castles and we're appreciating that. And I would like to encourage sharing the information we have gained about what works and doesn't work in this combination. So That is my talk. And I have plenty of time for questions, if there are any.

29:21

Speaker 2: Yeah, I'm I'm curious about your thoughts on um when to use HX Boost versus when not to use the HX Boost or if you should ever use Boost

29:39

Speaker 1: Remind me what HX Boost does. I have a vague recollection. It's been like

29:44

Speaker 2: Cool. I no uh

29:46

Speaker 1: been working on Django upgrades all summer.

29:48

Speaker 2: Yeah. Yeah. So um I probably should have let with that anyways. Uh so HX Boost is sort of like a um an attribute you can add to say the the body tag of of a page, right? And it'll basically say that every um call to the server whether it's a form action or uh an A -link.

30:18

Speaker 1: Using HTMX?

30:19

Speaker 2: Yes. And um and it avoids uh HTMX attribute overload. But can also come at a cost uh where it it it can take if especially if you use it on the body tag, it can take over everything and you'll have to eventually go back and say HX boost equals false. Um but you can I guess the The promise of it is is you can specify a generalized target want and As long as you have a j

31:05

Speaker 2: a generalized template, you can do everything with that and it makes that the HTMX side of things so much simpler.

31:21

Speaker 1: Obviously, based on my having to have a reminder of what Asia I had heard of it. I don't think we've used it. Honestly, I've had more overload from the Alpine than HTMX. So I haven't really encountered and I've been able to sort of better compartmentalize the HTMX into its own templates that can be reused. versus the alpine. So I don't I have not used it much. Um it might I don't know how if you have HX boost on the body, how do you know what URL it goes to? Where what path does it

32:08

Speaker 2: so

32:09

Speaker 1: Oh I guess well it would have to be hmm

32:13

Speaker 2: Yeah, so if you have HS, if you have it on the body, right? So that means every tag is as long as There is a href attribute set, right? It goes to that. And

32:25

Speaker 1: it's gonna use that.

32:26

Speaker 2: And then on the back end you just check to see whether the HX request header is set And then you serve the partial template. And then based on the target that you set on that body tag, that results in where it goes. And then you can set different uh targets for different things. So like for forms you can set uh a target for like say you have a form open in a in a modal, right? you can set the target on the form for the modal, right? And then once that um Once that form has been processed successfully, you can send another header

33:13

Speaker 2: that says, hey, let's retarget this back to the main content ID from the from the the body tag or the the main content that you were normally using. So it makes the update seems more seamless.

33:35

Speaker 1: Sounds like something to use. It it sounds like it may move some key information out of scope of what you might be looking at. So it might not make it real clear when you're looking at something what it's going to do. Um so I might be kind of careful in using it. But if it's a pattern that's established in a project, then it might be an easy w easy way to avoid having too many chtmx attributes all over the place. So It depends. I guess.

34:05

Speaker 3: That's usually a good answer. I'm curious, using your your analogy of walking on the beach, are there any really great shells you found along the way that you still keep on the mantle and admire on a regular basis with this tool set? Things that really made you, when you found them, made your eyes get big.

34:28

Speaker 1: If I can remember. Um I was really so this one Greenfield project we worked on, we did a whole bunch of stuff about it was moving uh moving potential participants in something through a bunch of states. And each time you did that, there was a different form and different information you had to supply. So they were these, and they're fairly sophisticated forms. So we had built all that out, and then in the second phase, something that we had to do. Was also allow for creation of these potential participants in whatever state. So Using a combination of um

35:13

Speaker 1: H Tmx Uh so the new thing was much like the old all the old forms, only at the top. You had to say what state this individual was going to be in when they were created. So you choose the state and then HTMX, you can grab the the the actual detailed form that you need to fill out. And we end up we ended up being able to, without change, entirely reuse the existing change state forms. by using HTMX to go fetch the new. And there's a combination of HTMX, so this, you know, you change the selector and the form underneath changes. and something on top needed to change as well, which you could do with, I think,

36:01

Speaker 1: this actually there's two ways you could do it. You could do it with HTMX out of band or you could do it with teleporting in Alpine and we ended up doing this teleporting in Alpine because using the HTMX, we were using the HTMX API there and it didn't support out of band. Um so it's just And a lot of places where I was using it like we hadn't you come across a new situation. say you'd been using HTMX, I think it was HTMX and identifying what you wanted to submit or replace or something by identifier and You wanted, you know, actually I would just want the closest form that I'm in. And you could do that. Like just looking at the documentation and finding that you didn't need to do anything special.

36:48

Speaker 1: It was supported out of the box by just reading the documentation. Um, so that kind of thing. I mean, we had a lot of good experiences with being able to do things very quickly. Um, but I don't know that there's one particular like there's just read the documentation. It's

37:06

Speaker 4: it

37:06

Speaker 1: there's a lot that's provided without a whole lot of effort.

37:12

Speaker 4: Cool. And this one comes from uh Jeff Yen online. He's asking, uh do you feel that any of your current or future projects might approach a level of complexity which would be not well handled with HTMX and Alpine? And if so, what tools would you look at for that?

37:28

Speaker 1: I don't um We do CMSs and and a lot of forms. We don't do we haven't I I haven't had to participate in any projects which had like And even that I'm not even sure, like strong user interactivity, like the things that Chris May mentioned that might uh push towards using a a fully baked front-end framework. We just we don't really do that. I haven't had worked on projects like that. So For me right now. And if I were to think

38:15

Speaker 1: I wanted to use to have it like that whole app on the front end, I would probably question whether I should use Django on the back end or should I slim down the back end. to to to make it clearer that this is where this function is done. It's done on the front end and the back end is just an API server. And you shouldn't think about doing templating up there. So I might, if I were to have something that I thought needed a strong, a big front-end framework, I might question whether we should use Django for it or slim it down. I'd have a hard time giving up a Chango admin though. So

38:55

Speaker 4: Hi, thank you very much. This was very insightful. What

38:59

Speaker 5: I will say is that I'm relatively new to the community, but I have been catching up quickly. And one thing that I'm kind of curious about that I just don't seem to understand yet is why does the community seem to pivot towards you know HTMX and Alpine as opposed to just standard JavaScript files. It's um is it quicker for development or is there something more intuitive I'm not understanding?

39:30

Speaker 1: For me personally, um I was I came up before the the JavaScript any of them really were There weren't maybe there was backbone or something, but I learned back end development. So I had these tools that knew how to do things and I knew how to use them and then um As the front-end frameworks became more and more capable, functions moved to the front end. So for me, it was like I would rather use tools I already knew than learn a whole new set of tools.

40:22

Speaker 1: It seemed to me a lot of the the To me, it seems like a lot of the taking h taking jot JSON from the back end and turning it into HTML on the front end duplicates a lot of the things you could do more efficiently on the back end. So that's one aspect of it. Um and the overlap of function having the function I'd rather have it in one place and it like data validation needs to be on the back end. So That's why I gravitate more towards keeping the the logic and the advanced function on the back end versus writing JavaScript for it. That's that's probably mine. Did that answer your question?

41:06

Speaker 6: We have a couple more minutes.

41:08

Speaker 7: Hi Karen. I'm curious whether the any of the projects you've worked on so far have had any accessibility requirements or whether you've noticed anything in terms of meeting like accessibility standards with this particular combination, whether it was easier, harder

41:26

Speaker 1: um we have not had any strong accessibility requirements on any of these projects. We have Tried as we are developing to include uh accessibility helpers. Um area labels and stuff as as you use things that maybe are you're creating tabs with divs or something. I mean as to indicate, yeah, we've tried, but we have not had we have not had um any requirements from clients to meet any particular standards or do anything. So we haven't rigorously validated that what we've done is actually working very well. I have not noticed it's any harder to do with this set of tools than with

42:14

Speaker 1: just bare Django or bare JavaScript. But I I don't know what kind of support you have with JavaScript libraries. Maybe they offer more than I'm aware of. So I've been going going on about this all day yesterday and today, but I'll shut up eventually. Have you seen Hyperscript? I have looked at it and decided to go with Alpine.

42:40

Speaker 8: Okay.

42:42

Speaker 1: And I also heard What is his name? Carson Gross talk about it and sort of how he spoke of it kind of warned me off using it. Even though he's the one who's building it, right?

42:55

Speaker 8: I I have used it in a couple of projects I find it really nice. It uses fewer attributes than Alpine does.

43:03

Speaker 1: Okay.

43:03

Speaker 8: Which makes me happy.

43:05

Speaker 1: It uses more of a natural language syntax.

43:08

Speaker 8: Yeah. It's he's described it as hypercard for the modern web. And I think it's really slick. But

43:16

Speaker 1: I think I think my worry about it and my reason not for going down that path was lack of clarity around What exactly something is going to do when it's not so clear based on the syntax of whatever? Um but I don't have any experience with it.

43:34

Speaker 8: Thanks. Um good talk. One thing that is kind of annoying about Tailwind is the really, really, really, really long classes that come out of it. So how there are different ways to to deal with that. What's what do you do?

43:49

Speaker 1: Tailwind?

43:51

Speaker 8: Yeah. It's part of that like uh is it something that you deal with? If it's not, then no stress.

44:00

Speaker 1: My own inclination is to go back to extracting out those long strings of classes and put more uh symbolic names around what it is I want this thing to be. But that I feel like I have not yet uh had the courage to um

44:19

Speaker 8: delve into it.

44:20

Speaker 1: to go forward with proposing we need to stop putting this these long strings of tailwind classes in all our HTML. And it seems like it's counter to Yeah. The prevailing thought. We we we this has nothing to do with Alpine and HTMX, but it does have to do with Tailwind. Like we have a project that needs uh It's whole like it provides reusable things that need can need to be styled differently depending on which site it's on. And so we have in that project extracted out all of the uh tailwind into ACSS files that get built. Um and we use higher class names on on the on the HTML so that you can easily restyle it with just a different style sheet.

45:06

Speaker 1: But that seems to go against how people want to use tailwind. And like so Personally, I think that might be an easy win for getting a lot of the complexity out of the templates, but uh like I said, I haven't had the courage to go forward with proposing that. You and I together we can 't.

Questions this talk answers

What does HTMX add to a Django application?

HTMX lets ordinary HTML elements trigger richer server requests by adding attributes, while the server continues returning HTML that HTMX inserts into the page. It provides this behavior through a lightweight, dependency-free JavaScript library.

Discussed at 9:38

What does Alpine.js add that HTMX does not?

Alpine.js handles client-side interaction and state without immediately contacting the server. Its HTML attributes can track data, respond to user actions, and show or hide parts of the page.

Discussed at 11:15

Why combine Django, HTMX, and Alpine.js?

The combination preserves Django’s server-side strengths—especially forms, validation, authentication, and URL routing—while adding partial-page updates through HTMX and local interactive state through Alpine.js. This avoids duplicating as much logic in a large front-end framework.

Discussed at 13:43

How has using Django, HTMX, and Alpine.js worked in real projects?

The team used the combination on a greenfield project with sophisticated, dynamic forms, and added it to existing CMS and contact-form features. They also found that it encouraged back-end and front-end developers to share knowledge and own features more collectively.

Discussed at 14:30

What are the main downsides of using Django, HTMX, Alpine.js, and Tailwind together?

Templates can become overloaded with Tailwind classes, HTMX attributes, Alpine state, and interaction logic, making them harder to understand and maintain. Templated JavaScript and nested quoting also introduce escaping and debugging problems.

Discussed at 19:10

Why is template reuse difficult with HTMX and Alpine.js?

Presentation, server interaction, and client-side interaction often become coupled in the same template, so reuse requires complicated parameterization or is abandoned. Alpine state supplied by an enclosing component can also be invisible in an included template and cause errors when reused elsewhere.

Discussed at 22:13

What improvements or tools could make this Django front-end approach easier to maintain?

Karen wants clearer guidelines for structuring Alpine components and deciding when to extract JavaScript into separate files. She is also considering Django Formset, Django template partials, Django Components, and Django Cotton to improve form UX, partial rendering, and template component reuse.

Discussed at 25:24

When should you use HTMX Boost?

HTMX Boost can reduce attribute overload by applying HTMX behavior broadly to links and forms, but it can also hide important behavior and require opt-outs for individual elements. Karen has not used it much and would use it cautiously unless the project already follows a clear pattern.

Discussed at 31:21

Can HTMX and Alpine.js reuse existing complex Django forms effectively?

Yes. In one project, HTMX fetched the detailed form appropriate to a selected state, allowing the team to reuse existing state-change forms without modification. Alpine’s teleporting was used to update another part of the interface when HTMX out-of-band updates were not available in their setup.

Discussed at 34:28

When does a project outgrow HTMX and Alpine.js?

Karen has not worked on projects with the level of front-end interactivity that would clearly require a full front-end framework. If a project did need a substantial front end, she would question whether Django should remain a templating back end or instead be reduced to an API server, although she would find it difficult to give up Django admin.

Discussed at 37:28

Why use HTMX and Alpine.js instead of writing standard JavaScript files?

For Karen, these tools build on familiar Django and HTML patterns instead of requiring developers to learn a large new front-end stack. They also keep more logic and validation on the back end, avoiding duplication involved in turning JSON into HTML on the client.

Discussed at 39:30

Does using HTMX and Alpine.js make accessibility harder?

The projects did not have formal accessibility requirements, though the team tried to use labels and other accessibility helpers. Karen had not noticed the combination being harder than plain Django or JavaScript, but the work was not rigorously validated against a specific standard.

Discussed at 41:26

How can you reduce long Tailwind class strings in Django templates?

Karen’s preference is to replace long utility strings with higher-level symbolic class names and extract the Tailwind styling into CSS files. Her team has used that approach where reusable components need different styling across sites, though she noted it differs from the prevailing Tailwind style.

Discussed at 44:00

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 by Karen Tracey

More videos from DjangoCon US