Django + HTMX: Interactive UIs Without Building a SPA
Modern users expect instant feedback: live search, inline validation,
modals, and infinite lists. For years the default answer was “spin up
React.” For many Django products, HTMX is a better fit—especially when
your domain logic already lives in forms, permissions, and the ORM.
What HTMX actually does
HTMX (~14KB) extends HTML with attributes like hx-get, hx-post,
hx-target, and hx-swap. The browser issues an AJAX request; your Django
view returns an HTML fragment; HTMX swaps it into the page. No JSON
contract, no client-side router, no duplicate validation rules.
That is why the Django survey shows HTMX climbing so quickly: it restores
the hypermedia model Django was built for, with 2020s UX expectations.
Minimal setup that works in production
- Include HTMX (CDN or the vendored script from
django-htmx). - Add
HtmxMiddlewareso views can branch onrequest.htmx. - Put the CSRF token on every HTMX request:
<body hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'>
- Prefer partial templates (or Django 6 template partials) for responses
that only refresh one region of the page.
def search(request):
q = request.GET.get("q", "")
results = Post.objects.filter(title__icontains=q)[:20]
template = (
"blog/partials/search_results.html"
if request.htmx
else "blog/search.html"
)
return render(request, template, {"results": results})
<input
type="search"
name="q"
hx-get="{% url 'blog:search' %}"
hx-trigger="keyup changed delay:300ms"
hx-target="#results"
hx-swap="innerHTML"
/>
<div id="results"></div>
Patterns that pay off immediately
- Inline forms: post a form with
hx-post, return the row or error
markup, swap the form region. - Delete with confirm:
hx-confirm+hx-deletekeeps UX sharp without
a modal library. - Optimistic polish: pair HTMX with small CSS transitions on
hx-swap. - Local state only: use Alpine.js for tabs, dropdowns, and
client-only toggles that never need the server.
Guardrails
- Do not return a full
base.htmlfor HTMX requests—ship fragments. - Keep authorization checks in the view; HTML swaps are still HTTP.
- For complex client graphs (canvas editors, offline-first apps), a SPA
may still win. HTMX is not anti-JavaScript; it is anti-unnecessary
JavaScript frameworks.
Why this fits a portfolio stack
If your site already uses Django templates and Tailwind, HTMX lets you
demonstrate modern UX without maintaining a separate Node toolchain for
every interaction. Recruiters and clients see ship speed; you keep one
test suite and one deployment.
Start with search, pagination, or a comment form. Once those feel native,
you will rarely reach for a full SPA for content-driven products again.