Skip to main content
HTMX is a different approach to building web applications. Instead of SPAs with heavy JavaScript, HTMX lets you build dynamic applications with HTML and minimal JavaScript by extending HTML with custom attributes.

Comparison with Other Approaches

Quick Start

Create a new HTMX project with the CLI:
Visit http://localhost:3000 to see your app!

Why HTMX?

The Hypermedia Approach

HTMX embraces the original web model: server-rendered HTML with progressive enhancement. Instead of sending JSON over the wire and building UI in JavaScript, HTMX sends ready-to-render HTML fragments. Traditional SPA approach:
HTMX approach:

Key Benefits

  • Tiny: ~14kB minified and gzipped
  • No Build Step: Include via CDN or npm
  • Server-First: All logic on the server
  • Progressive: Works without JavaScript
  • Accessible: Built on web standards
  • Simple: Extends HTML with attributes
  • SEO-Friendly: Real HTML from server
  • Fast Development: No frontend/server coordination

When HTMX Shines

HTMX is perfect when you want:
  • Server-side rendering with dynamic interactions
  • Simple mental model (HTML in, HTML out)
  • No build toolchain
  • Progressive enhancement
  • Great SEO out of the box
  • Rapid development with familiar tools

Installation

Via CDN

Or use a specific version:

Via npm

Then import in your JavaScript:
Or with a bundler:

Architecture

Development Mode

Production Mode

Project Structure

Core Concepts

HTMX Attributes

HTMX extends HTML with attributes that enable AJAX, WebSockets, and Server-Sent Events directly in your markup.

HTTP Methods

Targeting

Control where the response gets inserted:

Swap Strategies

Control how content is swapped:

Swap Modifiers

Fine-tune swap behavior:

Triggers

Control what triggers the request:

Trigger Filters

Add conditions to triggers:

Headers

Request Headers

HTMX automatically sends these headers:

Response Headers

Control HTMX behavior from the server:

Indicators

Show loading states:

Validation

Client-side validation still works:
Server-side validation:

Advanced Features

Out-of-Band Swaps

Update multiple parts of the page from a single response:
Server response:
Multiple out-of-band swaps:

History and Navigation

Control browser history:
Handle history restoration:

Synchronization

Prevent concurrent requests:

Confirmation

Prompt before request:

Boosting

Progressively enhance regular links and forms:
With boost:
  • Links become AJAX requests that target body
  • Forms submit via AJAX
  • URLs are pushed to history
  • Works without JavaScript (progressive enhancement)

Preserving Content

Preserve elements during swaps:

Disable During Request

Disable elements while request is in flight:

Request Parameters

Include additional parameters:

Encoding

Control request encoding:

Common Patterns

Click to Load

Click to Edit

View mode:
Server returns edit form:
After save, server returns view mode again.

Inline Delete

Server returns empty response, HTMX removes the row.
Backend:

Infinite Scroll

Backend:

Lazy Loading

Load content when it becomes visible:

Polling

Auto-refresh content:

Progress Bar

Backend:
Template:

Bulk Operations

Backend:

Dependent Selects

Backend:

Typeahead / Autocomplete

Backend:
Template:

File Upload with Progress

Backend returns:

Optimistic UI

Show immediate feedback before server response:
If server request fails, HTMX will restore the original content.

Pagination

Tabs

HTMX Extensions

Server-Sent Events (SSE)

Real-time updates from server:
Backend (Go):

WebSockets

Preload

Preload content on hover:

Loading States

Response Targets

Target based on HTTP status:

Class Tools

Manipulate classes:

Complete Application Example

Let’s build a complete Task Manager with Mizu backend and HTMX frontend.

Backend Structure

app/server/app.go:
app/server/task_service.go:
app/server/handlers.go:
app/server/routes.go:

Frontend Templates

views/layouts/default.html:
views/pages/home.html:
views/partials/task-list.html:
views/partials/task-row.html:
views/partials/task-edit.html:
Note: The template needs a helper function for single task rendering. Add this to your handlers:
And add the route:
views/partials/stats.html:

Error Handling

Client-Side Errors

HTML5 validation runs before HTMX submits the form.

Server-Side Errors

Return appropriate HTTP status codes:

Global Error Handling

Security

CSRF Protection

Use CSRF middleware:
Include token in forms:

XSS Protection

Always escape user content in templates. Go’s html/template does this automatically:

SQL Injection

Use parameterized queries:

Rate Limiting

Performance

Caching

Cache responses:
Or use HTTP headers:

Compression

Lazy Loading

Load content only when needed:

Debouncing

Reduce server requests:

Testing

Backend Tests

Frontend Tests

Use tools like Playwright or Cypress:

Troubleshooting

HTMX Not Working

Check:
  1. HTMX library is loaded: <script src="https://unpkg.com/htmx.org@1.9.10"></script>
  2. Check browser console for errors
  3. Verify server is returning HTML (not JSON)
  4. Check HX-Request header is sent

Content Not Updating

Check:
  1. hx-target points to existing element
  2. hx-swap strategy is correct
  3. Server response contains expected HTML
  4. No JavaScript errors preventing swap

Form Not Submitting

Check:
  1. Form has hx-post or similar attribute
  2. Input fields have name attributes
  3. Server endpoint exists and accepts POST
  4. No validation errors preventing submit

History Not Working

Check:
  1. Using hx-push-url or hx-replace-url
  2. Handling history restore requests
  3. URLs are valid

Debug Mode

Enable HTMX logging:

Combining with Alpine.js

Alpine.js adds client-side reactivity to complement HTMX:
Example: Dropdown with HTMX actions:

When to Use HTMX

Perfect For

  • CRUD Applications: Forms, lists, updates
  • Admin Dashboards: Data tables, filters, actions
  • Content Sites: Blogs, documentation, marketing
  • Progressive Enhancement: Start with plain HTML, add interactivity
  • Server-Side Teams: Developers comfortable with backend rendering
  • SEO-Critical Apps: Need server-rendered HTML
  • Rapid Prototyping: Quick feedback loop

Not Ideal For

  • Desktop-Like Apps: Complex client-side state
  • Real-Time Collaboration: Multiple users editing simultaneously
  • Offline-First: Apps that work without network
  • Heavy Client Logic: Complex calculations or data processing
  • Mobile Apps: Need native feel with offline support

Hybrid Approach

Use HTMX for most of the app, add JavaScript where needed:

Next Steps

Alpine.js

Add client-side reactivity with Alpine.js

View Engine

Learn more about Mizu’s template engine

React Guide

Compare with SPA approach

HTMX Docs

Official HTMX documentation

HTMX Examples

More patterns and examples

Hypermedia Systems

Book on hypermedia-driven applications