Frontend frameworks sem JavaScript: HTMX e Phoenix LiveView

1. O paradigma do servidor-centrismo moderno

1.1 Por que eliminar o JavaScript do frontend? Performance, acessibilidade e simplicidade

O JavaScript moderno tornou-se um gargalo em muitas aplicações web. Frameworks como React, Vue e Angular exigem bundles pesados, carregamento assíncrono complexo e gerenciamento de estado no cliente. Eliminar o JavaScript do frontend não significa voltar ao modelo estático dos anos 2000, mas sim adotar uma abordagem onde o servidor é a fonte única de verdade para renderização e interatividade. Os benefícios incluem:

  • Performance: Redução drástica do tempo de carregamento inicial, pois não há download de bibliotecas JS pesadas.
  • Acessibilidade: Páginas renderizadas no servidor são naturalmente mais compatíveis com leitores de tela e mecanismos de busca.
  • Simplicidade: Desenvolvedores backend podem criar interfaces interativas sem dominar ecossistemas JS complexos.

1.2 A evolução do MPA para o hipertexto dinâmico

As Multi-Page Applications (MPAs) tradicionais recarregavam a página inteira a cada ação do usuário. Com o advento de tecnologias como HTMX e Phoenix LiveView, o MPA evoluiu para um modelo onde apenas fragmentos do HTML são trocados via requisições assíncronas. O hipertexto dinâmico permite que o servidor envie respostas parciais que atualizam seletivamente o DOM, mantendo a simplicidade do MPA com a fluidez de uma SPA.

1.3 Diferença fundamental: SPA vs. abordagem server-driven

Característica SPA (React, Vue, Angular) Server-driven (HTMX, LiveView)
Estado Gerenciado no cliente Gerenciado no servidor
Renderização Client-side (CSR) Server-side (SSR) com atualizações parciais
Complexidade Alta (bundlers, state management) Baixa (HTML + atributos declarativos)
SEO Requer SSR adicional Naturalmente otimizado

2. HTMX: HTML aumentado para interatividade

2.1 Atributos mágicos: hx-get, hx-post, hx-target e hx-swap

HTMX estende o HTML com atributos que transformam qualquer elemento em um gatilho de requisição AJAX. Exemplo prático:

<button hx-get="/api/mensagem" hx-target="#resultado" hx-swap="innerHTML">
  Carregar mensagem
</button>
<div id="resultado">Clique no botão para carregar</div>
  • hx-get: Define o método HTTP e o endpoint.
  • hx-target: Especifica o elemento que receberá a resposta.
  • hx-swap: Controla como o conteúdo será inserido (innerHTML, outerHTML, beforeend, etc.).

2.2 Substituindo AJAX e eventos JavaScript por requisições declarativas

Um formulário tradicional com validação server-side pode ser implementado sem JavaScript:

<form hx-post="/cadastro" hx-target="#mensagem" hx-swap="innerHTML">
  <input type="text" name="nome" required>
  <input type="email" name="email" required>
  <button type="submit">Cadastrar</button>
</form>
<div id="mensagem"></div>

O servidor retorna HTML puro contendo a mensagem de sucesso ou erro, que é inserida no #mensagem.

2.3 Casos de uso reais: formulários, paginação infinita e modais sem uma linha de JS

Paginação infinita:

<div hx-get="/pagina/2" hx-trigger="revealed" hx-target="this" hx-swap="afterend">
  Carregar mais...
</div>

Modal dinâmico:

<button hx-get="/modal/editar/123" hx-target="#modal-container" hx-swap="innerHTML" hx-trigger="click">
  Editar
</button>
<div id="modal-container"></div>

3. Phoenix LiveView: o backend como estado real

3.1 Arquitetura WebSocket + Elixir: estado síncrono entre servidor e cliente

Phoenix LiveView estabelece uma conexão WebSocket persistente entre o servidor Elixir e o navegador. O estado da interface é mantido exclusivamente no servidor, e as atualizações são enviadas como diffs de DOM (via morfing) para o cliente. Isso elimina a necessidade de APIs REST ou GraphQL para interações comuns.

3.2 Componentes reativos no servidor: Phoenix.LiveView e render/1

Exemplo de um contador simples em LiveView:

defmodule MeuAppWeb.ContadorLive do
  use Phoenix.LiveView

  def render(assigns) do
    ~H"""
    <div>
      <h1>Contador: <%= @contador %></h1>
      <button phx-click="incrementar">+</button>
      <button phx-click="decrementar">-</button>
    </div>
    """
  end

  def mount(_params, _session, socket) do
    {:ok, assign(socket, :contador, 0)}
  end

  def handle_event("incrementar", _params, socket) do
    {:noreply, update(socket, :contador, &(&1 + 1))}
  end

  def handle_event("decrementar", _params, socket) do
    {:noreply, update(socket, :contador, &(&1 - 1))}
  end
end

3.3 Eventos, bindings e atualização parcial do DOM sem JavaScript customizado

Bindings como phx-click, phx-change e phx-submit mapeiam eventos do navegador para handlers no servidor. O LiveView calcula automaticamente as diferenças entre o estado anterior e o novo, enviando apenas as instruções mínimas para atualizar o DOM.

4. Comparação técnica entre HTMX e LiveView

4.1 Modelo de conexão: HTTP puro (HTMX) vs. WebSocket persistente (LiveView)

Aspecto HTMX LiveView
Conexão Requisições HTTP curtas WebSocket persistente
Estado Stateless (cada requisição é independente) Stateful (mantido no servidor)
Latência Depende de rede e processamento do servidor Mínima (diferenças enviadas via WebSocket)

4.2 Latência, escalabilidade e overhead de rede

HTMX é mais leve em termos de conexão, mas cada interação requer uma nova requisição HTTP. LiveView mantém uma conexão constante, o que pode consumir mais recursos do servidor para milhares de usuários simultâneos. Para aplicações com muitos usuários concorrentes, HTMX escala melhor com balanceadores de carga tradicionais.

4.3 Curva de aprendizado: backend tradicional (HTMX) vs. Ecossistema Elixir (LiveView)

HTMX pode ser adicionado a qualquer stack backend (Django, Rails, Flask, Spring Boot) com mínima curva de aprendizado. LiveView exige conhecimento de Elixir, Phoenix e programação funcional, o que representa um investimento maior.

5. Integração com stacks existentes

5.1 HTMX com Django, Rails, Flask ou Spring Boot: plug-and-play

Adicionar HTMX a um projeto Django é tão simples quanto incluir a tag script no template:

<script src="https://unpkg.com/htmx.org@1.9.10"></script>

A partir daí, qualquer view que retorne HTML pode ser usada como endpoint para atributos HTMX.

5.2 LiveView como parte do ecossistema Phoenix: dependências e configuração

LiveView já vem integrado ao Phoenix 1.7+. Basta adicionar {:phoenix_live_view, "~> 0.20"} ao mix.exs e configurar o roteamento.

5.3 Substituindo bibliotecas JS (Alpine, Stimulus) por atributos HTMX ou bindings LiveView

  • Alpine.js: Pode ser substituído por HTMX para requisições assíncronas e por atributos HTML para interatividade simples.
  • Stimulus: LiveView oferece bindings mais poderosos e estado centralizado.

6. Limitações e quando evitar essas abordagens

6.1 Cenários que exigem estado offline, animações complexas ou WebGL

Aplicações que precisam funcionar offline (PWA), animações CSS/JS complexas ou renderização 3D (WebGL) ainda se beneficiam de frameworks JS tradicionais.

6.2 Problemas de SEO, acessibilidade e carregamento inicial em LiveView

LiveView requer JavaScript para estabelecer a conexão WebSocket. Se o JS falhar, a página não carrega. HTMX, por outro lado, degrada graciosamente para requisições síncronas.

6.3 Debugging e ferramentas de desenvolvimento ainda imaturas comparadas ao ecossistema JS

Ferramentas como React DevTools ou Vue DevTools são mais maduras que as oferecidas para HTMX e LiveView. O debugging de WebSocket em LiveView pode ser complexo.

7. Tendências e o futuro do frontend sem JavaScript

7.1 O ressurgimento do hipertexto: HTMX, Unpoly e Hotwire (Turbo)

Frameworks como HTMX, Unpoly e Hotwire (Turbo) estão revitalizando o modelo de hipertexto dinâmico, oferecendo alternativas viáveis ao SPA para muitos casos de uso.

7.2 LiveView como precursor de frameworks server-side reativos

Phoenix LiveView inspirou implementações similares em outras linguagens, como Laravel Livewire (PHP) e Hotwire (Ruby on Rails).

7.3 Impacto na escolha de frameworks para projetos de médio porte e times full-stack

Para projetos de médio porte com times full-stack, HTMX e LiveView reduzem a complexidade do frontend, permitindo que desenvolvedores backend entreguem interfaces interativas sem depender de especialistas em JavaScript.

Referências