Free to list, always.No paid rankings. Every recommendation explains its trade-offs.
OpenSourceChoice
DevOps

htmx 4.0: Pilot the Migration, Keep 2.x as Rollback

htmx 4 moves to fetch, explicit inheritance and new events. Pilot the migration, pin 4.0.0 and keep a tested 2.x rollback.

Last reviewed
Evidence
3 official sources
htmxhtmx 4JavaScriptHTML over the wirefetchmigrationhypermediaweb development
htmx 4.0: Pilot the Migration, Keep 2.x as Rollback

htmx 4.0 is a real stable release, not another beta, but the safest upgrade is deliberately uneventful. Pin 4.0.0, run the supplied checker, migrate one representative route, and keep the exact 2.x asset available until error responses, history, inherited security headers, extensions and event-driven integrations pass production-shaped tests.

OpenSourceChoice verdict: use htmx 4.0 for new server-rendered applications when current browser support and HTML responses already fit the architecture. Existing 2.x applications should migrate in a canary, not through an unversioned CDN URL or a package-range update. The software remains free and operationally light; the real cost is finding behavioral assumptions that were previously implicit.

This is a researched technical analysis of htmx 4.0.0, its tagged source, current documentation, npm distribution, migration tooling, security guidance, repository state and adoption signals observed on August 29, 2026. OpenSourceChoice did not migrate a production application, benchmark the library or independently test every browser, extension and proxy combination.

Executive verdict

QuestionOpenSourceChoice assessment
Best fitServer-rendered applications that already return safe HTML fragments, use mostly standard htmx attributes and can canary a pinned client asset
Poor fitTeams without template-level tests, applications dependent on custom 2.x extensions or XHR events, old browser fleets, and clients that treat arbitrary third-party HTML as trusted UI
Why it matters nowStable 4.0.0 shipped August 28 after an eight-month rewrite and immediately drew independent attention on Hacker News, Reddit and Lobsters
Current package channelsnpm served 2.0.10 as latest and 4.0.0 as next when checked August 29; install 4.0.0 explicitly
Real adoption costTemplate and JavaScript inventory, changed request and swap semantics, extension work, browser/proxy tests, observability updates and rollback rehearsal
Main riskA page can look normal while a formerly inherited CSRF header, renamed event, changed error swap or history behavior is no longer doing what the server expects
Parallel alternativeEvaluate Hotwire Turbo when Frames, Streams and a Rails-oriented integration model fit better; keep plain server rendering plus small JavaScript as the control
Adoption gateOne representative workflow passes success, validation error, authorization failure, timeout, back/forward, reconnect, accessibility and rollback tests in the supported browser matrix

Why this matters now

Version 4.0.0 was published on August 28, one day before this assessment. The project describes it as the result of eight months of work, with the internal request engine moved from XMLHttpRequest to fetch() and the public behavior intentionally kept close to 2.x where the maintainers judged that useful.

The attention is broader than one release post. The Hacker News discussion had reached 557 points and 138 comments, the r/programming thread 321 votes, the project subreddit thread 226 votes, and the Lobsters submission 49 points and 11 comments when checked August 29. These are discovery and adoption signals, not evidence of correctness.

The repository did not appear in the GitHub daily Trending list observed during this run. Product Hunt results concerned older tools built with htmx, while XDA and indexed X searches did not provide a comparable release-specific signal. The release, package publication, active repository and three independent technical communities still establish a stronger moment than a single viral post.

Duplicate screening found no OpenSourceChoice article about htmx, HTML-over-the-wire migration, the 2.x-to-4.x compatibility decision or the same rollback conclusion. Existing web-development coverage addresses other products and search intents.

What htmx does—and what it does not

htmx is a browser library that lets HTML attributes issue HTTP requests and replace selected DOM content with HTML returned by a server. Version 4 keeps that core model while adopting fetch(), standardizing events and expanding its extension set for morphing, Server-Sent Events, WebSockets, multipart streams, stricter CSP handling and small reactive behaviors.

The 4.0.0 npm package contains browser bundles, an ES module build, optional extensions, editor metadata, upgrade scripts and agent guidance. It declares no runtime package dependencies. There is no htmx server or official container to operate: the application backend, templates, authentication, authorization, data store, queues and deployment remain yours.

That boundary is the attraction and the constraint. htmx can remove a JSON-to-client-state translation layer for many interactions, but it does not design the domain model, protect an endpoint, escape user content, resolve concurrent writes or make a fragmented backend easier to operate.

The upgrade is small in size, broad in semantics

The visible syntax remains familiar, but 4.0 changes several defaults that can cross security, data and navigation boundaries.

ChangePractical consequenceTest before promotion
fetch() replaces XMLHttpRequestXHR progress hooks and custom interception no longer apply; abort, credentials, errors and streaming use a different browser primitiveSlow requests, cancellation, authentication expiry, upload/download behavior and every supported browser
Attribute inheritance becomes explicitAncestor attributes no longer reach descendants unless marked :inheritedCSRF headers, confirmation, targets, includes and boosted navigation on nested templates
All responses except 204 and 304 swap by default4xx and 5xx HTML can now replace the targetValidation, forbidden, expired-session and internal-error responses, including secret and stack-trace leakage
hx-delete stops including enclosing form valuesA delete flow can lose identifiers or anti-forgery values it previously sentEvery destructive form and server-side authorization check
History stops caching pages in localStorageBack navigation re-fetches and swaps the page by defaultDraft forms, scroll, filters, expired sessions, offline behavior and server load
Main swaps precede out-of-band swapsDOM dependencies can run in a different orderNotifications, counters, modals and any OOB target created by the main response
hx-trigger queueing moves to hx-syncRapid inputs or repeated clicks can use different concurrency behaviorSearch-as-you-type, autosave, destructive double-clicks and request cancellation
Default timeout becomes 60 secondsLong jobs that previously waited indefinitely now failReports, exports, slow upstreams and streaming setup
Events, request headers and extension hooks changeAnalytics, error capture, CSRF injection, custom extensions and server branching can silently miss their old integration pointListener coverage, emitted telemetry, header contracts and every private extension

The official upgrade-check scans common template and script extensions and reports file-and-line findings for inheritance, removed attributes, old event names and extension changes. Its release example specifically catches an inherited CSRF header that would otherwise stop reaching a nested delete button. Treat the checker as inventory, not certification: generated templates, runtime strings, framework components and server assumptions still require tests.

Do not let the package channel choose the architecture

The maintainers intentionally left htmx 2 on npm's latest tag and published 4.0.0 on next so that non-versioned CDN users would not be forced across a major boundary. They expect that arrangement to continue into early 2027.

That is a sensible safety measure and a warning about floating references. A production application should use an exact asset:

<script src="/assets/htmx-4.0.0.min.js"></script>

or an exact package dependency such as htmx.org@4.0.0. Self-hosting removes a third-party runtime request and makes rollback a file or deployment change. If a CDN is retained, pin the version and integrity value from the tagged release rather than using an unversioned URL or @next.

For existing applications, keep the previous 2.x asset and deployment manifest until the canary has survived real traffic. A rollback that begins with rediscovering the old file is not a rollback plan.

Use the compatibility extension as scaffolding

The bundled htmx-2-compat extension restores old event names, implicit inheritance, hx-ext activation and other 2.x behavior. It is useful for separating two questions: whether the new fetch-based core works in the application, and whether the application has completed the semantic migration.

Load it only as a documented, temporary phase. If it becomes permanent, the team owns a hybrid contract that future maintainers must understand. Instrument its use, remove one compatibility dependency at a time, and run the same suite after the final removal.

Custom extensions deserve their own workstream. Version 4 replaces callback-oriented extension points with registered event hooks, and the SSE and WebSocket extensions change connection, message and swap behavior. A green page-load test says little about reconnects, ordering, backpressure, authentication expiry or proxy buffering.

Operational cost: still small, no longer zero

Basic htmx 4 adds no mandatory service and no license fee. A traditional request/HTML-response application can reuse its current compute, database, reverse proxy and monitoring. The operational cost comes from behavior and from the richer features a team chooses to enable.

Streaming changes the capacity model. SSE and multipart responses hold HTTP connections open; WebSockets add bidirectional connection state. Measure concurrent connections, proxy buffering, idle timeouts, reconnect storms, per-user authorization, cancellation and deploy draining. A library feature does not configure the load balancer or make a stateful connection free.

Morphing and hx-live can reduce hand-written client code, but they also expand the state that must survive a DOM update. Test focus, selection, unsaved values, third-party widgets, assistive technology announcements and cleanup of listeners. Adopt each extension because it removes a measured problem, not because it ships in the distribution.

Privacy and data flow

In the default architecture, the browser sends normal HTTP requests to application-controlled routes and receives HTML for the current user. htmx 4 defaults fetch mode to same-origin, and element-level configuration cannot silently widen that global request mode. No htmx cloud account receives application data.

Privacy still depends on the deployment:

  • a third-party CDN sees asset requests unless the library is self-hosted;
  • the application server sees form fields, URLs, headers and cookies required by each interaction;
  • streamed responses may stay open and accumulate proxy or application logs;
  • analytics listeners can capture element identifiers, URLs or response context;
  • HTML fragments can reveal data that a broad JSON response would also leak, even if the UI hides it.

Map each request and response, minimize logged form values, use TLS, scope cookies, and keep authorization on every server route. Returning HTML instead of JSON changes representation, not access control.

Security: the server remains the trust boundary

The project's security guidance is direct: call routes you control, use an auto-escaping template engine, keep user content out of dangerous script/style/attribute contexts, and secure authentication cookies. htmx processes HTML as executable document structure; untrusted HTML is not inert data.

Version 4's same-origin fetch default is a useful boundary, and the optional hx-csp extension adds nonce gating, Trusted Types integration and a safer evaluation path for strict Content Security Policy deployments. It is not a switch to add blindly. Nonces must be generated and propagated correctly, partial responses need compatible policy handling, and the application still has to prevent stored and reflected injection at the template boundary.

The tagged repository includes a vulnerability-reporting policy that lists 4.x, 2.x and 1.9.x as supported and directs reporters to GitHub's private reporting flow. No public repository advisories were listed when checked August 29. That is not evidence that the release has no vulnerabilities.

Before production, require at least:

  • auto-escaping for every dynamic fragment and explicit sanitization for permitted rich HTML;
  • server-side authorization and anti-forgery validation on every state-changing route;
  • safe public error fragments for 4xx and 5xx, with no traces or secrets;
  • a CSP appropriate to the application's actual use of inline behavior;
  • same-origin requests unless each allowed cross-origin endpoint is intentionally reviewed;
  • security tests after removing 2.x compatibility behavior.

License, maturity and lock-in

htmx 4.0.0 uses the Zero-Clause BSD license. It permits use, modification and distribution without a copyleft obligation or a mandatory commercial fee, while providing no warranty. The package and tagged license agree on that current license.

The project is active rather than archived. The repository was updated on August 29, and 38 pull requests had merged during the preceding 30 days when observed. The release notes show work distributed across a team and outside contributors, although a small group authored much of the 4.0 implementation. That is a reason to watch maintenance concentration, not enough evidence for a precise bus-factor number.

License lock-in is low. Technical lock-in depends on application design. Normal URLs, full-page responses and standard forms preserve a strong exit path. Fragment-only routes, htmx-specific headers, custom extensions, hx-live expressions and streaming message formats create deeper coupling. Preserve non-JavaScript navigation for critical flows where practical, keep server contracts documented, and test a full-page fallback.

The maturity risk is concentrated in the release boundary. Beta-era issue reports about preload behavior, programmatic aborts, custom elements, multi-target swaps and Alpine integration remained open during this review. They do not prove the stable build is broken; they identify features that should receive targeted tests rather than trust by association.

What to evaluate in parallel

OptionPrefer it whenMain trade-off
htmx 2.0.10The current application is stable and has no 4.0 requirementDelays the new fetch, streaming, CSP and explicit-behavior model
htmx 4.0.0New work or a controlled migration benefits from the cleaner contract and current extensionsFresh major release; semantic and extension migration cost
Hotwire TurboFrames, Streams, Drive and especially Rails integration match the productMore opinionated navigation and stream conventions; a different migration, not a drop-in swap
Plain server rendering plus small JavaScriptThe application needs only a few focused interactionsMore local glue as interaction count grows, but the smallest dependency and clearest fallback

Turbo is the most useful parallel evaluation for teams already committed to server-rendered HTML. Its Frames isolate page regions, Streams encode common DOM actions, and its Rails integration is mature. htmx remains more attribute-level and backend-agnostic. Compare one real workflow in both rather than debating abstractions.

A practical migration plan

1. Freeze the 2.x baseline

Record the exact htmx file or package, extensions, integrity value, browser support policy, server headers and proxy behavior. Capture success, validation error, forbidden, expired-session, timeout, back/forward and double-submit behavior for a representative route.

2. Inventory implicit contracts

Search templates and scripts for inherited attributes, old event names, hx-disable, hx-disabled-elt, hx-ext, hx-vars, hx-params, hx-prompt, XHR events, request headers, response headers, custom extensions, OOB swaps and trigger queue modifiers. Run the tagged upgrade checker and review every finding manually.

3. Pin 4.0.0 with compatibility enabled

Change only the client asset and load htmx-2-compat. Run the baseline in the supported Chromium, Firefox and WebKit/Safari versions. Fix request-engine or browser failures before changing application semantics.

4. Remove compatibility by behavior group

Migrate inheritance and security headers first, then error swaps, history, events, request headers and extensions. Keep each change small enough to bisect. Add contract tests at the server boundary, not only DOM snapshots.

5. Canary one representative workflow

Choose a route with a form, validation, authorization, navigation history and observability. Deploy it behind a reversible flag or bounded cohort. Measure error rate, timeouts, duplicate actions, server requests, client exceptions and back-navigation failures.

6. Rehearse rollback

Restore the pinned 2.x asset and compatible server behavior without reverting unrelated application work. Verify cached assets, service workers and CDN invalidation cannot leave clients on a mixed version.

7. Add new features separately

Only after semantic parity, evaluate morphing, SSE, WebSockets, multipart streams, hx-live or hx-csp. Each changes a different operational or security boundary and deserves its own decision record.

Measurable adoption criteria

Promote htmx 4.0 only when all of these are true:

  • every upgrade-check finding is resolved, accepted or covered by a test;
  • inherited authorization and anti-forgery data reaches the correct nested controls;
  • 4xx and 5xx responses render safe, intentional fragments;
  • success, timeout, cancellation, duplicate-submit and expired-session cases match the approved contract;
  • back/forward navigation preserves or deliberately discards state as designed;
  • custom events, analytics and error monitoring receive the new event names and context;
  • all required extensions pass reconnect, ordering, cleanup and compatibility tests;
  • the supported browser matrix has no blocking failure or accessibility regression;
  • the old pinned asset and server behavior can be restored within the agreed rollback time;
  • one canary survives at least ten working days without a release-blocking workaround.

Defer the migration if the application cannot identify its htmx version, relies on unowned custom extensions, sends security data through implicit inheritance without tests, or cannot prevent internal error pages from becoming swap content.

Final recommendation

For a new server-rendered application, htmx 4.0 is the sensible line to evaluate. Pin the stable release, self-host the asset when practical, keep same-origin defaults, return escaped HTML, and use ordinary links and forms as the baseline before adding reactive or streaming extensions.

For an existing 2.x application, there is no need for a release-day fleet upgrade. Version 2 remains the npm default and is still covered by the project's security policy. Start the migration now if 4.0 solves a real problem, but separate the fetch-engine change from the semantic cleanup with the compatibility extension and a canary.

The strongest reason to adopt htmx 4 is not novelty. It is a clearer contract: explicit inheritance, standardized events, native fetch and a more coherent extension system. The strongest reason to wait is equally concrete: your application may depend on behavior it never documented. Make that behavior visible, then choose the version.

Sources

Turn research into an architecture

Build a stack for this use case.

Answer nine practical questions and compare three transparent architectures with costs, free limits, lock-in, and migration paths.

Build my stack