How to Enjoy Debugging in Production with Karen Tracey
Published October 23, 2025
This video features Karen Tracey at DjangoCon Europe 2024 in Vigo, Spain.
Talk: Django + Alpine.js + htmx Ups & Downs by Karen Tracey
https://pretalx.evolutio.pt/djangocon-europe-2024/talk/HRRDK9/
Karen Tracey argues that Django, HTMX, and Alpine.js form a practical alternative to a large front-end framework. Django provides the core server-side features—templates, forms, validation, authentication, routing, and permissions—while HTMX adds partial-page server interactions without requiring much JavaScript and Alpine.js handles browser-side state and interaction. Her team has used the combination successfully for new and existing applications, including sophisticated forms, and finds that it lets developers share more responsibility across the front and back ends. The trade-off is that templates can become crowded with Django logic, HTMX attributes, Alpine expressions, and CSS classes, making them difficult to understand, debug, and reuse. Tracey is still committed to the combination, but says teams need clearer conventions for structuring Alpine components, deciding whether JavaScript belongs in templates or separate files, and making reusable template components more maintainable.
Summarised automatically from the transcript.
Automatically transcribed, so expect mistakes in names and technical terms.
Speaker 1: So now we are having Django Alpine and HTMX uh ups and downs with uh Karen Tracy. Thank you Karen.
Speaker 2: Hello, can you hear me? I will try to remember to stand close enough that you can hear me with the microphones. I'm excited to be here and talk about this tool combination of Django, AlpineJS, and HTML. That I started to hear about several years ago now and started using two and a half, three years ago. I'm curious how many of you are using this tool combination. Number, not everyone. How many of you are waiting on the sidelines, have heard the hype, but are thinking like, uh this is probably not for me. There's probably I see at least one handout there, yeah. Like waiting to hear what people are feeling about it after using it a few years.
Speaker 2: So hopefully this talk will give some idea of that um sort of experience with using it, what I really enjoy about this tool combination and what uh what challenges or or or um road not roadblocks but challenges and and things that may come in if you start down this path of using this tool combination versus a more traditional front-end framework. What I'll be talking through, I first want to talk about the promise that I saw in this tool combination, both individually in the individual libraries and frameworks, and then as a combination as to what I really hoped to see out of using this tool combination. I'll talk briefly about the upside. I feel like there's been a lot of upside talks and how great it is, so I'm I'm gonna focus mainly on
Speaker 2: uh you know high-level upside. Uh and then a little bit more on some of the downsides, some of the some of the challenges of this tool combination perhaps. And then finally talk about the assessment I have, we have, and some future plans we have for continued use of this tool. combination. I have interspersed photographs in my talk to keep people awake uh and engaged. Uh these I am fully aware given the name Alpine and ups and downs. really be from my ski vacation, but I didn't take a ski vacation. So these are from my beach vacation. Uh and they are, while they're all pictures from my uh vacation, they are chosen to try to reinforce some of the concepts that I am
Speaker 2: hoping to talk about. So this is a picture of a sunrise which is intended to convey a promise of a beautiful day. You can see there's uh pretty colors. There is also here though some clouds, so perhaps it won't be such a beautiful day. So that's part of uh that's the intent of my pictures. Uh hopefully they come through and convey what I'm intending. Uh oh one last thing I should mention. I had intended when I first proposed this talk, I thought I'd get like into some coding and show some code. As I was preparing for a 30 minute talk, I realized that was going to be way too much to cover both the details of some code and all this other stuff that I just mentioned. So this is going
Speaker 2: Stay pretty high level. Uh he's not gonna get into deep coding and there's not gonna be code on the slides. Um, but I'm happy to talk about specifics of code later on if you see me, whatever. So let's start with Django. Since I'm at Django Conference, I'm not sure. I'm expecting I don't need to convince you all that Django is a great web framework, but I do want to highlight what drew me to Django and what drew Cactus, the company, at least I believe this is what drew Cactus to using Django, which is the company I work for and have worked for for a over 10 years. We're a web development shop. We build custom applications for whoever wants it. So Django is our web framework of choice and largely we love Django. because of all the built-in
Speaker 2: features. The got the access to the database via the object relational mapper, it has now database migrations, so you can update your database schema without a lot of effort. Admin, the killer app that lets you easily see your data in the database and that maybe update it, support for creating HTML in a templated fashion, authentication for users, a permission framework that you can also customize to be Like broad it's it's broad to begin with, but you can customize it to be object-oriented if you want it you know per object permissions if necessary. It's got URL routing, it has support for forms and both the rendering of the forms and the accepting of the data coming in. And validating that it's all good
Speaker 2: and support for showing user error messages. So there's a whole lot of stuff that's included in Django. And then there is a very strong ecosystem of third-party packages that provide all sorts of other things that you might. need as well. There are multiple CMS frameworks or packages to choose from if you want to create a a site that non-technical administrators can create fancy websites. There's all sorts of small things as you know allowing you to use S3 storage buckets as your back-end file storage. Um so there's a whole ecosystem of third party packages. So if Django does not provide what you are looking for Um you can probably find it in a third-party package if it's any sort of reusable, commonly needed thing.
Speaker 2: And this is what drew us to Django and keeps us with using Django. Of Django that is misty and is uh not necessarily straightforward or not not clear how to address, and that is the whole front end. Django is a back-end web framework. It does not have any opinion about what you should use for the front end. It doesn't have a JavaScript preference, it doesn't have a CSS preference. So you're kind of uh you're all on your own there to figure out how to do that. And over the years as the front end of web applications has become more and more advanced and fancy, it has it had has become more and more common to use front
Speaker 2: end web frameworks that end up duplicating a lot of that stuff that Django provides, like JSX instead of HTML template rendering, um authentication via web tokens versus session authentication that Django provides. So as time went as time progressed, I saw I it felt like there were more and more people who were using Django just for a REST API backend that you could um easily add with Django REST framework or other REST frameworks that Django has in the third party ecosystem or um So they were using less and less of the built-ins of Django because they were using the front-end web framework. And it that felt to me very duplicative, and that's what excited me about these other tools
Speaker 2: that I'll get into now. Because they my hope was. they would l allow for less duplication on the front and the back end of uh duplication of handling concerns. So the first one I'll talk about is HTMX. And what HTMX promises is rich server interactivity Um without having to write a lot of JavaScript. So HTMX asks the question why is it that just a form and an anchor link, those are the only two elements that have are defined to have interactivity with the server? Why can't you add HTML attributes attributes to your HTML to say when the user does this, go get fetch a page from this server and update this part of the page, just
Speaker 2: a small part of the page. Which Which gets around the whole, it gets you past the whole having to reload a full page when you submit a form, which is very clunky nowadays for your web applications. It keeps the server, generally speaking, in a HTML so that your views can continue to return HTML and you don't have to instead return JSON that then the front end turts the JSON into HTML. And it's a dependency-free library that is very easy to add to your project. So um It's it was very attractive and very exciting when I first heard about it. But it only deals with the client browser interacting with the server. And there's another aspect to
Speaker 2: a modern user-friendly web application that is the interaction between the user and the client browser and what happens there. And that's where our Alpine JS comes in. And what Alpine JS does is um it It provides the ability to manage data on the front end with associated with your HTML elements and supports rich user activ user interactivity. So you may have some data that starts out on the page as a Django very variable, template variable, and then it is part of your it is rendered in a way that is included in your JavaScript and then as the user does something, clicks something, adds something, you may be changing that data on the front end
Speaker 2: to, you know, maybe Maybe you're working through a form, and based on certain answers, you get shown other questions that you then have to answer. So it can support rich front-end user interactivity. It is also lightweight and it's easy to add. a project and it is 15 attributes, 6 properties, and two methods. So it's it like HTMX is also learnable. It doesn't come with a lot of concepts that you have to wrap your head around in order to start using it effectively. So overall, these three things seem to provide all the things you need to write a modern, user-friendly web application with great user experience. And this is the promise
Speaker 2: of this tool combination, which is a little brighter than the first one, um and but still a few cause. Uh so the promise of the combination, just to reinforce, is to be able to utilize all this features that Django provides without duplicating concepts on the front and the back end. I want to be able to use Django's form rendering, which you can hook into and customize for your yourself and the validation which you can hook into and customize for your application's needs. I want to be able to use Django's user authentication and Django's URL routing. I want Django which provides all these things to be the basic, the the main thing that's providing all the heavyweight concepts that I'm using and not have to duplicate a lot of that on the front end or figure out, okay, we're gonna do JSX over here
Speaker 2: to do the rendering of this stuff from JSON. So I just didn't want to have to get into all that, you know, deciding where to put the function. And I just want to be able to rely on Django to do it. And with the help of these other tools. So how's that worked out? What our experience has been, I'd say we started using We started on a brand new green tilt project that had nothing. So and we chose we had been thinking before we saw these tools that we would go down the path of React for the front end of this because it had some fancy fancy forms and in user interactivity that we thought we would need something like React. We heard about these tools and the client was interested in pursuing these tools.
Speaker 2: So we started that project I'd say two and a half years ago and our client had a client who needed it launched within six months. So which what they needed was could be accomplished by a slimmed down version of the overall product that our client is working on, I'd say. So we did launch one version of that six months later, so about two years ago now. And that one is in production for that client. It was sort of a slim-down tailor to their particular need. And then over the last few years we've continued to add features to that and it grow out this product that our client is looking to build. And it's that's been successful. We continue to use these tools. We don't have any React. We don't have any other front-end framework. And we've been able to do sophisticated forms
Speaker 2: with choices that you make influencing the path you go down. Just managing the participants in this application where you have to add. Um they have emails, they have addresses, they have phone numbers, so those are form sets, and being able to use Django's facilities for form sets married with a list. little bit of Alpine JS and a little bit of HDMX is very it's been very easy to use. Um we have also over the last few years, um as we continue to maintain other projects that existed long before um we started using these tools, we started adding HTMX and Alpine individually or together to existing projects. Um I recently had to add
Speaker 2: some bulk action on a on a list kind of thing to a project that had jQuery as the only JavaScript it used. And I was initially gonna just keep doing the jQuery thing, but I eventually decided this would be easier to do in Alpine, so I've taken the step of going ahead and starting to introduce Alpine into that project. Um Um and overall I'd say both Alpine and HTMX are quick to learn and um we've had a number of people come in. tools. They're both well documented as well, as as is Django. The main thing that I really enjoy about this
Speaker 2: tool combination is the increased sharing and the blending of knowledge between the front and the back end developers. In our company we have a lot of very small teams, maybe just one or two, two or three developers. Um so to have a very hard line between or a very bright line and a lot of knowledge needed to work effectively. in the back end as well as the front end had had been leaning towards a a a a real difficulty of being able to handle, of having a developer on a project be able to s sort of feel like they could own the whole scope from the front end to the back end. Um I know I as a back end developer felt couldn't be effective on the front end with React.
Speaker 2: I couldn't learn that on top of everything else I was doing. So I feel much more effective and much more able to both simply review things from front end focused developers using these tools all the way to being able to implement things myself on the front end if that's the path we need. So the increase ability to sort of have a team that see that sort of owns the whole scope of the application I find um really great about this tool set. And am I doing time-wise? Not as well. But so everything's sunshine and light. Maybe there are a few things I am aware of that I
Speaker 2: uh areas of challenge that I'd like to talk about. So that's Indicated by some cloudy days. The first one I talk about, this slide is focused mainly on the complexities that can start to appear in your templates. You've brought in HTML. attributes for HTMX, the server interaction, you brought in HTML attributes for Alpine. js. If you're using something like Tailwind, you probably have a long string of classes on a lot of things. So you it can get to be really overwhelming to look at some of these templates. And it can be kind hard to say what is this doing? So that's just something to be aware of and something to figure out how to address. Um
Speaker 2: it can be overwhelming. And I worry I worry for new developers. who are learning all of these things at once in looking at one of these templates, are they even going to be able to know, oh, this is an Alpine thing versus this is an HTMX thing or this is a CSS class from Tailwind? So the the you've got um And I saw a tweet thread on this as I was traveling here. You've got you've got CSS presentation things, you've got server interactivity things, and you've got user interactivity things all coming together in the same place. And that can that can just be overwhelming. Um another thing that that is some it can be confusing and complex is the thinking through the complexity of
Speaker 2: you've got a template rendering time when you have access to your your your um Django context variables and you've got um template tags and filters that you can pass in these variables but they may then turn their their their scope of life then becomes a JavaScript variable and then that can get get updated in the as the JavaScript runs in the browser. And sometimes that can be a little tricky to think through exactly how how that works. And how do how do you um How do you keep track of what is going on? And then there's just this other thing that is kind of annoying. You know, using HTML attributes to define some JavaScript in your alpine, and then inside
Speaker 2: your JavaScript you may need a coded string. Then inside that coded string you may need a coded string. And it's like, whoo, how do I do that? Uh and you may need that, particularly if you're influencing the styling using the CSS selector often you're going to need a coded string within a coded string. And One way I found to do that is to use the ampersand quote uh semicolon construct, but that's really ugly. So it's just like I don't know, that just feels to me like in uh maybe we're doing too much. in one place here. And one one thing you can do to alleviate this complexity is with Alpine, you can not put your JavaScript necessarily in your
Speaker 2: HTML attributes, but you can extract it out into JavaScript files and then just reference some higher level names that you define in your JavaScript. So you can do that, and then you're not putting so much JavaScript right in your templates. trade-offs there because then you get your your when you have the JavaScript right there you can see what it's going to do and you can wrap your head around it. You extract it out and you refer to it via some name you've defined. It isn't as clear. You have to then go check the JavaScript file for what What exactly does this do when it runs? So complexity in the templates uh is one area that I find a little bit troubling about this tool combination. And coming from a long-term Django history. I've been using Django for
Speaker 2: going on two decades. Um I remember learning early on, or being told early on that the Django template language was intentionally limited and intentionally uh uh not very complicated because that's not where you want to put your complexity. Django's philosophy was you should have your business logic complexity in your Python code, either in your views or in your model methods, and you really shouldn't have a lot of complexity in your templates. So coming to this tool combination and starting to see a lot of complexity appearing in templates kind of makes me say, hmm, is this is this a good direction? And it's so it's just a lot. Here's my picture of a lot, uh a lot of birds. on the on the beach doing all sorts of things
Speaker 2: and starting to fly off because I was getting too close to them. The second area uh I want to talk about of downside is reuse of these templates that you're building that include CSS and server interaction and um user interactivity. So I am a big fan of reusing code. If I start to do s pretty much the same thing, only a little bit different in Python, I will straw I will easily say, okay, we can abstract out this bit of it, and this is a parameter that gets passed in, and then this is the base code, and based on what is passed, it does something slightly different. Um, so I want to do that kind of thing in HTML templates as well.
Speaker 2: It's a lot harder when you've got all these things coming together. Um You can you can break out bits of HTML and have those included in your templates. So Django does offer the ability to include one template inside of another, but it is entirely unstructured and there is no support. for like this template requires these these variables and so if these aren't in the context, you know, something should blow up and say, hey, um , shouldn't do this. So that it's unstructured and there's there's no good support that I have found for um doing that in a way that that makes it clear to someone reading it or looking at it that, oh, um, I'm looking at this included template, it references some Alpine. Where did that come from? Like it's just it can be difficult to figure out how to reuse.
Speaker 2: And then just another little knit, uh if you've got your JavaScript in your HTML template, a lot of times your editor isn't going to recognize it as JavaScript. So if you're used to your editor guiding you in terms of syntax color, And when you've made a typo, it doesn't recognize something. You're not going to get that in your HTML. Usually I at least my editor doesn't highlight my JavaScript errors in my HTML. So that can be another little roadblock. So this is my picture of what a template may end up looking like. It's complicated and kind of messy and what the heck is going on here? Um that's a lot of crabs, sand crabs were in the same place and came out and made little mounts. Um so that's
Speaker 2: those are the two main things I want to focus on is the complexity that can come up in templates and then the how do you go ahead and reuse those things. Um how you you facilitate reuse. And here I come to my my assessment and plans. I still think this is a winning combination. I'm still intending to continue to use these tools. Um I do think I need we need to be aware of uh complexities and the the reuse issues and come up with a plan of how to deal with that. As I said, I there is one project I work on that has jQuery and I I do hope over time to migrate from using jQuery on that app to using Alpine JS. I do think
Speaker 2: one of my one of my goals moving forward is to come up with a better guideline for myself and my team. Or how to build Alpine components and how to structure your Alpine components and guidelines around when you want to put the JavaScript in the templates or when you want to extract the JavaScript out of the templates and have them be in JavaScript files. I don't yet have a good feel for that. But I do feel like making that step and coming up with some guidelines there would be a way to make this tool combination more sustainable over time and more maintainable over time. So that is my talk. One minute I think for questions.
htmx enables rich server interaction by adding HTML attributes that can fetch content and update part of a page without a full reload. It lets Django views continue returning HTML instead of requiring a JSON API and frontend rendering layer.
Discussed at 7:17Alpine.js manages frontend data and user interaction directly alongside HTML. It supports behaviors such as conditionally revealing form questions and updating data in the browser without requiring a large frontend framework.
Discussed at 8:49The combination lets Django remain responsible for forms, validation, authentication, URL routing, templates, and other substantial concepts, while Alpine.js and htmx add modern interactivity. This avoids duplicating Django functionality in a separate frontend framework.
Discussed at 10:20Yes. The team launched a production application with this stack, continued adding features, and built sophisticated branching forms and formsets without React or another frontend framework. They have also introduced Alpine.js and htmx into existing applications.
Discussed at 11:06Templates can become difficult to understand because CSS classes, htmx server behavior, and Alpine.js browser behavior are all mixed together. It can also be tricky to track values as they move from Django template variables into JavaScript and then change in the browser.
Discussed at 15:37They are harder to reuse than ordinary Python code because the template combines markup, CSS, server interaction, and client interaction. Django includes can share fragments, but they are unstructured, do not clearly declare required context variables, and can make the source of Alpine behavior difficult to follow.
Discussed at 20:14The speaker still considers it a winning combination and plans to keep using it, including replacing jQuery with Alpine.js in an existing project. She wants clearer team guidelines for structuring Alpine components and deciding when JavaScript belongs in templates versus separate files.
Discussed at 22:37Note: 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.
Published June 13, 2025
Published June 13, 2025
Published June 13, 2025
Published June 13, 2025
Published June 13, 2025
Published June 13, 2025