HTMX no Django: Ajax com menos JavaScript

Em muitos projetos Django, a maior parte da aplicação já está resolvida pelo servidor: o Django recebe a requisição, executa a regra de negócio e devolve HTML renderizado. Mesmo assim, algumas telas precisam atualizar uma parte da página sem recarregar tudo.
Tradicionalmente, eu resolveria isso escrevendo JavaScript para capturar eventos, montar uma requisição Ajax, interpretar a resposta e alterar o DOM. Funciona, mas pode gerar bastante código para uma interação simples.
O HTMX veio para facilitar justamente esse tipo de situação. Ele permite adicionar comportamentos de requisição diretamente aos elementos HTML usando atributos. Nos meus projetos Django, isso tornou muito mais prático trazer recursos de Ajax sem precisar escrever muitas linhas de JavaScript.
O que é o HTMX
O HTMX é uma biblioteca JavaScript que permite fazer requisições HTTP a partir de elementos HTML e substituir partes da página com a resposta recebida. A configuração costuma ficar nos próprios atributos do elemento que inicia a ação.
Em vez de criar um arquivo JavaScript para cada botão, posso indicar no HTML qual URL deve ser chamada, onde a resposta deve aparecer e como a troca deve acontecer.
Um exemplo simples é um botão que carrega um resumo dentro de um elemento:
<button
hx-get="{% url 'painel:resumo' %}"
hx-target="#resumo"
hx-swap="innerHTML">
Atualizar resumo
</button>
<div id="resumo">
O resumo ainda não foi carregado.
</div>Ao clicar no botão, o HTMX faz uma requisição GET para a URL do Django. O conteúdo devolvido pelo servidor é inserido no elemento #resumo. Não precisei selecionar o botão no JavaScript, registrar um listener ou escrever código manual para trocar o HTML.
O Django continua no controle
O HTMX não substitui as URLs, as views ou os templates do Django. Ele apenas muda a forma como o navegador solicita e aplica uma resposta.
Uma view pode continuar simples:
from django.shortcuts import render
def resumo(request):
dados = obter_dados_do_resumo()
return render(request, "painel/_resumo.html", {"dados": dados})Nesse caso, o template _resumo.html contém somente o fragmento que será colocado dentro do alvo. Essa separação combina bem com a forma como o Django já trabalha com templates e deixa claro que a resposta não precisa renderizar a página inteira.
Atualizando partes da página
Os atributos do HTMX descrevem a interação. Alguns dos que mais uso ou considero importantes são:
hx-getehx-postdefinem o método e a URL da requisição.hx-targetinforma qual elemento receberá a resposta.hx-swapdefine como o conteúdo será substituído.hx-triggerpermite escolher o evento que dispara a requisição.hx-selectpode selecionar apenas uma parte da resposta recebida.
Com essa combinação, uma tela pode carregar uma tabela, atualizar um contador, abrir um formulário ou substituir uma mensagem sem que cada comportamento precise de um módulo JavaScript próprio.
Também posso disparar uma requisição quando um campo muda ou quando um formulário é enviado:
<form
hx-post="{% url 'tarefas:criar' %}"
hx-target="#lista-de-tarefas"
hx-swap="beforeend">
{% csrf_token %}
<input type="text" name="titulo" placeholder="Nova tarefa">
<button type="submit">Adicionar</button>
</form>
<div id="lista-de-tarefas">
<!-- novas tarefas podem ser adicionadas aqui -->
</div>O servidor continua validando os dados e tomando a decisão sobre o que deve ser retornado. O navegador apenas atualiza o trecho indicado.
Por que ficou prático no Django
O Django já favorece uma arquitetura em que o servidor entrega HTML. Por isso, o HTMX se encaixa naturalmente em aplicações que usam templates, formulários e views tradicionais.
Eu não preciso transformar uma tela inteira em uma aplicação de página única só porque um componente precisa ser atualizado de forma assíncrona. Posso manter a renderização no Django e adicionar interações Ajax apenas onde elas realmente melhoram a experiência.
Isso também reduz a quantidade de estados duplicados. Em uma abordagem mais pesada, o JavaScript pode precisar conhecer regras que já existem na view, no formulário ou no modelo. Com o HTMX, o servidor continua sendo responsável por processar a operação e devolver o HTML correspondente.
HTMX não elimina todo o JavaScript
O HTMX não é uma promessa de que nunca mais será necessário escrever JavaScript. Aplicações com editores avançados, gráficos complexos ou interações muito específicas ainda podem precisar de código no navegador.
A vantagem é escolher a ferramenta de acordo com o problema. Para atualizar um fragmento, enviar um formulário ou carregar conteúdo sob demanda, os atributos do HTMX costumam ser suficientes. Para comportamentos que realmente exigem lógica no cliente, posso continuar usando JavaScript sem abandonar o restante da aplicação.
Essa simplicidade também ajuda na manutenção. Quem lê o template consegue enxergar a URL, o alvo e a forma de troca no mesmo lugar em que o elemento está definido.
Cuidados importantes
Mesmo com pouco código no cliente, a aplicação continua precisando dos cuidados normais de um sistema web. As views devem validar permissões, os formulários precisam ter proteção contra CSRF e as respostas não devem expor dados para usuários que não têm acesso.
Também é importante pensar no comportamento quando o JavaScript estiver desabilitado ou quando uma URL for acessada diretamente. Sempre que possível, mantenho uma resposta HTML útil e uso o HTMX como uma melhoria progressiva da interação.
Minha conclusão
O HTMX deixou mais simples levar Ajax para meus projetos Django. Em vez de escrever muitas linhas de JavaScript para cada atualização parcial, consigo declarar no HTML qual ação deve ocorrer e deixar o Django continuar renderizando a resposta.
Para aplicações que já usam views e templates, essa abordagem é direta, fácil de entender e suficiente para muitas interações do dia a dia. Ela não tenta substituir todo o frontend, mas resolve muito bem o espaço entre uma página totalmente estática e uma aplicação que exigiria um framework JavaScript completo.