2 pontos por GN⁺ 2025-11-04 | 1 comentários | Compartilhar no WhatsApp
  • htmx 4.0 é uma grande versão de reconstrução que substitui completamente a arquitetura anterior baseada em XMLHttpRequest por uma estrutura assíncrona centrada em fetch()
  • O modo de herança de atributos mudou de implícito para uma declaração explícita com :inherited, melhorando a clareza do código e a manutenibilidade
  • O cache de histórico foi simplificado: em vez de salvar snapshots locais, agora usa um mecanismo de restauração baseado em requisições de rede, aumentando a confiabilidade
  • Vários novos recursos, como respostas em streaming, SSE, DOM morphing, a tag <partial> e fila de View Transition, foram integrados ao núcleo
  • No longo prazo, a meta é simplificar a base de código e melhorar a extensibilidade, com suporte contínuo também para usuários da versão 2.0

Visão geral do htmx 4.0

  • O htmx 4.0 reescreve completamente a estrutura existente, incorporando a experiência de desenvolvimento do fixi.js e lições de 5 anos de manutenção
  • As principais mudanças podem ser resumidas em três pontos centrais: adoção de fetch(), explicitação da herança de atributos e simplificação do cache de histórico

The fetch()ening

  • XMLHttpRequest foi substituído por fetch(), modernizando a infraestrutura Ajax
    • Na maioria dos casos de uso, o impacto é pequeno, mas o modelo de eventos muda para acompanhar a natureza assíncrona do fetch()
  • Essa transição fornece a base para simplificar o código e expandir funcionalidades no futuro

Herança explícita de atributos

  • Em vez da herança implícita anterior, agora usa-se o modificador :inherited para declarar isso explicitamente
    • Exemplo:
      <div hx-target:inherited="#output">
          <button hx-post="/up">Like</button>
          <button hx-post="/down">Dislike</button>
      </div>
      
    • Se hx-target não for declarado explicitamente, os elementos filhos não o herdarão
  • Para a maioria dos usuários, essa é a maior mudança de upgrade

Simplificação do cache de histórico

  • O cache local de snapshots do DOM do htmx 2.0 era instável por causa de modificações de terceiros, estados ocultos e outros fatores
  • No 4.0, isso mudou para um mecanismo de restauração via requisições de rede
    • A expansão de cache será oferecida como opção de adesão (opt-in)
  • Isso simplifica a base de código e melhora a confiabilidade do comportamento padrão

Elementos mantidos

  • APIs centrais como hx-get, hx-post, hx-target, hx-boost, hx-swap e hx-trigger continuam iguais
  • Com exceção da adição de :inherited, a maioria dos projetos deve continuar funcionando com o código existente
  • A manutenção de longo prazo e a estabilidade foram reforçadas

Política de upgrade

  • Usuários da 2.0 precisarão de um projeto de upgrade, mas a 2.0 terá suporte permanente
  • A 4.0 será distribuída em paralelo com a 2.x, e a mudança de latest é esperada para o início de 2027
  • Está prevista uma extensão para restaurar o comportamento da 2.0

Resumo dos novos recursos

Respostas em streaming e integração com SSE

  • Aproveitando o suporte a Readable Streams do fetch(), será possível fazer substituições parciais no DOM
  • SSE (Server Sent Events) foi reintegrado como recurso central, permitindo atualizações graduais de conteúdo

Morphing Swap

  • Com base no algoritmo Idiomorph, melhora a decisão de preservar ou remover nós durante a mesclagem do DOM
  • Os swaps morphInner e morphOuter passam a fazer parte do núcleo

Suporte à tag <partial>

  • Simplifica a sintaxe complexa do antigo Out-of-band swap
  • <partial> é um elemento de template que pode usar atributos padrão como hx-target e hx-swap
  • O Out-of-band swap volta a ser uma substituição simples baseada em id

Melhorias em View Transition

  • Introdução de uma fila de transição (queue) para evitar conflitos visuais
  • As transições CSS permanecem como antes, enquanto o runtime assíncrono é simplificado
  • Ainda não está definido se isso será ativado por padrão

Estabilização da ordem dos eventos

  • A estrutura assíncrona baseada em fetch() facilita garantir a ordem dos eventos
  • Foi introduzida uma nova convenção de nomes para eventos:
    htmx:<phase>:<system>[:<optional-sub-action>]
    • Exemplo: htmx:before:request

Mais extensibilidade

  • Com base em async, serão oferecidas extensões para preload e optimistic update
  • O ciclo de requisição/resposta/swap será aberto a desenvolvedores de extensões, inclusive com possibilidade de substituir a implementação de fetch()
  • Será possível implementar o comportamento desejado sem hacks

Melhorias em hx-on

  • A sintaxe padronizada hx-on:<event name> foi adotada
  • Com suporte à API assíncrona, torna-se possível fazer scripts simples de DOM
    <button hx-post="/like"
            hx-on:htmx:after:swap="await timeout('3s'); ctx.newContent[0].remove()">
        Get A Response Then Remove It 3 Seconds Later
    </button>
    
  • Funciona mesmo em ambientes com eval() desativado, embora com algumas limitações

Direção geral

  • O htmx 4.0 busca reduzir bugs e melhorar recursos mantendo uma experiência de uso semelhante à 2.0
  • Com simplificação do código, estrutura explícita e extensibilidade baseada em assíncrono, o objetivo é oferecer um htmx mais estável e moderno

Cronograma de desenvolvimento

  • A versão alfa (htmx@4.0.0-alpha1) já está disponível
  • O lançamento oficial 4.0.0 está previsto para o início ou meio de 2026
  • A mudança para latest está prevista para o início de 2027
  • O andamento do desenvolvimento pode ser acompanhado no branch four do GitHub e em four.htmx.org

1 comentários

 
GN⁺ 2025-11-04
Opinião do Hacker News
  • No fim, ele mudou de ideia e decidiu lançar uma nova versão major do htmx
    Mas, para cumprir a promessa de que “não haveria 3.0”, a próxima versão será chamada de htmx 4.0
    Reagiu em tom de brincadeira, dizendo que tecnicamente essa é uma forma correta de expressar isso

    • É uma solução divertida, mas pode causar confusão para os usuários, como aconteceu com o extinto PHP 6
      Talvez não fosse melhor simplesmente assumir e lançar como 3.0
    • Fizeram a piada de já ir direto para htmx 4.1 e criar o “xhtmx 1.0”
    • Disseram que isso lembra Leisure Suit Larry 4: The Missing Floppies
    • Ainda bem que ele não disse “não haverá uma terceira versão”, comentando que isso deixou margem na formulação
  • O htmx 2.0 será suportado permanentemente, então não há nenhuma pressão para fazer upgrade
    Numa época como a de hoje, com mudanças frequentes de API, essa abordagem merece elogios

  • Há quem busque estabilidade e acabe tirando a lição errada disso
    Em vez de concentrar grandes mudanças de uma vez, como no Python 3.0, defendem que uma estratégia de releases graduais é melhor
    Por exemplo, introduzir mudanças em 2.1, 4.0, 5.0 etc. torna tudo muito mais fácil de gerenciar
    Recomendam um modelo como o do Django, mantendo etapas de compatibilidade ao longo de várias versões

  • A explicação do atributo hx-target parece confusa
    “inherited” soa menos natural do que “inheritable” ou “inherit”

    • Uma pessoa disse que leu aquilo como “os filhos herdam”, e sugeriu que algo como “pass-down” talvez fosse mais claro
    • Disseram que “inherited” é a palavra errada e que “inherit” é curto e bom
      Como brincadeira, acrescentaram que “bequeath” também serviria
    • Comentaram que estão pensando em várias formas de expressão e que aceitam sugestões
    • Também apareceram alternativas como “heritable” e “cascade”
  • Consideram a ideia do HTMX e a filosofia de Hypermedia muito boas
    Saíram do ambiente SPA e escolheram o Datastar, sentindo que ele oferece mais escalabilidade pelo investimento de aprendizado
    Passaram a enviar sinais diretamente do servidor para o navegador, removendo código de polling, e a complexidade caiu bastante
    Também eliminaram a dependência de Alpine.js, simplificando o código, e até a atualização completa de views baseada em streaming funciona de forma eficiente graças à compressão
    Se você vem de SPA, recomendam testar tanto Datastar quanto HTMX

  • A mudança para fetch() e o uso de Readable Stream parecem interessantes
    Já usaram bastante HTMX, mas hoje preferem o streaming baseado em SSE do Datastar, que consideram mais atraente

  • Ficam felizes em ver o HTMX evoluindo, mas sentem que o Datastar oferece uma API mais alinhada a padrões e mais flexível
    Dizem que um pacote pequeno reúne Fetch, SSE, declarative signals, DOM morphing e várias outras funções
    Por isso, levantam a pergunta: “por que eu deveria usar HTMX?”

    • Apontam que o Datastar Pro não é open source, o que traz um risco de confiança
    • Mencionam a ironia de que o criador do Datastar já tinha tentado colocar esse tipo de recurso no HTMX
    • Explicam que a força do HTMX está numa interface simples, otimizada para o paradigma de requisição/resposta
      O Datastar é centrado em event streams, então serve bem para dashboards em tempo real ou jogos, mas, para a maioria dos webapps, a simplicidade do HTMX é mais vantajosa
      Referências relacionadas: ensaio sobre Datastar, Less HTMX is More
    • O HTMX facilita o gerenciamento do histórico de URL no navegador, mas o Datastar teria restringido esse recurso à versão paga (Pro)
  • Criticam o fato de que, depois de dizer que era “perfeito e por isso não teria mais versões major”, acabou reconhecendo a necessidade de evoluir
    Citam a parte “agora vamos mudar o padrão de nomenclatura de eventos” e ironizam a tentativa de evitar JavaScript

    • Zombam dizendo que, no fim, ao tentar não usar JavaScript, acabaram interpretando sintaxe customizada com JS
      Ainda assim, reconhecem que expressar a intenção em HTML tem seu valor
    • Soltam a piada de que “agora sim esta deve ser a última versão de verdade”
    • Também encaram de forma positiva, dizendo que “ainda é melhor do que escrever JavaScript direto”
    • Perguntam qual é exatamente o problema de o autor ter mudado de ideia, apontando o tom excessivamente crítico
  • Disseram que o texto é muito claro e ensina bastante sobre filosofia de design de API

  • Criaram o xhr-fetch-proxy para usar fetch junto com HTMX,
    e acham que essa mudança vai abrir ainda mais possibilidades
    Link do projeto

    • No 4.0, o ciclo de requisição está totalmente aberto, então será possível trocar a implementação de fetch em cada requisição
      Acrescentaram que aprenderam essa ideia com o fixi.js