| name | htmx-devtools-extension |
| description | Browser DevTools extension for debugging HTMX applications with request inspection, element tracking, event timeline, swap visualization, and error detection |
| triggers | ["debug my htmx application","install htmx devtools extension","inspect htmx requests and responses","track htmx element attributes","visualize htmx dom swaps","monitor htmx events timeline","troubleshoot htmx errors","set up htmx debugging tools"] |
HTMX DevTools Extension
Skill by ara.so — Devtools Skills collection.
Overview
HTMX DevTools is a browser extension that provides a comprehensive debugging interface for HTMX applications. It captures the full request lifecycle, tracks DOM elements with htmx attributes, visualizes swaps, monitors events, and surfaces errors. Supports both htmx 2.x and htmx 4.0 alpha with automatic version detection.
Key Features
- Request Inspector: Full lifecycle tracking with timing breakdown, headers, and event trace
- Element Inspector: Live DOM tree filtered to htmx elements with click-to-inspect
- Event Timeline: Filterable timeline of all htmx events with category color coding
- Swap Visualizer: Before/after snapshots with LCS-based diff view
- Error Panel: Automatic detection of HTTP errors, target not found, timeouts, and swap errors
Installation
Installing the Extension
From Source (Development):
git clone https://github.com/atoolz/htmx-devtools.git
cd htmx-devtools
npm install
npm run build:chrome
Chrome/Edge/Brave/Arc:
- Navigate to
chrome://extensions
- Enable Developer mode (toggle in top right)
- Click Load unpacked
- Select the
dist/ folder from the cloned repository
Firefox:
npm run build:firefox
- Navigate to
about:debugging#/runtime/this-firefox
- Click Load Temporary Add-on
- Select
dist/manifest.json
Verifying Installation
- Open a page with htmx loaded
- Press
F12 or open DevTools
- Look for the HTMX tab in the DevTools panel
- The version badge (blue for 2.x, purple for 4.0) should appear automatically
Using the Extension
Request Inspector
Monitor all HTMX requests with detailed lifecycle information:
Key Information Displayed:
- HTTP method, URL, status code
- Trigger element and target element
- Visual timeline: Config → Send → Wait → Swap → Settle
- All
HX-* request and response headers
- Request and response bodies
- Correlated event trace
Controls:
- Record (●): Capture new requests
- Pause (❚❚): Stop capturing while preserving current data
- Clear (🗑): Remove all captured requests
Example HTMX Request:
<button hx-get="/api/users"
hx-target="#user-list"
hx-swap="innerHTML">
Load Users
</button>
<div id="user-list"></div>
When clicked, the inspector shows:
- Method:
GET
- URL:
/api/users
- Target:
#user-list
- Swap:
innerHTML
- Timing breakdown for each phase
- HTTP headers including
HX-Request: true, HX-Target: user-list
Element Inspector
Explore the live DOM tree filtered to htmx-relevant elements:
Features:
- Auto-refreshing tree view showing element hierarchy
- Click any element to see:
- All
hx-* attributes
- Resolved target selectors
- Internal htmx data
- Request history for that element
- Element Picker (🎯): Click to select any element on the page
- Hover over tree nodes to highlight elements on the page
Example Element Tree:
<body>
<div hx-boost="true">
<form hx-post="/api/contact" hx-target="#result">
<input name="email" hx-validate="true">
<button type="submit">Submit</button>
</form>
<div id="result" hx-swap-oob="true"></div>
</div>
</body>
Inspector displays:
▼ body
▼ div [hx-boost="true"]
▼ form [hx-post="/api/contact", hx-target="#result"]
• input [hx-validate="true"]
• button
• div#result [hx-swap-oob="true"]
Event Timeline
Filter and explore all htmx events with expandable details:
Event Categories:
- Init:
htmx:load, htmx:configRequest
- Request:
htmx:beforeRequest, htmx:afterRequest
- XHR:
htmx:xhr:loadstart, htmx:xhr:progress
- Response:
htmx:beforeSwap, htmx:afterSwap
- Swap:
htmx:beforeSwap, htmx:swapError
- OOB:
htmx:oobBeforeSwap, htmx:oobAfterSwap
- History:
htmx:historyRestore, htmx:pushedIntoHistory
- Transition:
htmx:beforeTransition, htmx:afterSettle
- Error:
htmx:responseError, htmx:sendError, htmx:targetError
Example Event Flow:
Click any event to expand event.detail JSON payload.
Swap Visualizer
Record and analyze DOM changes with before/after comparison:
Controls:
- Record (●): Start capturing swaps
- Pause (❚❚): Stop capturing
- Click any swap entry to view details
Views:
- Response HTML: Raw HTML received from server
- Before: DOM state before swap
- After: DOM state after swap
- Diff: Line-by-line comparison with add/remove highlighting
Example Swap:
<div id="content">
<p>Old content</p>
</div>
<p>New content</p>
<p>Additional paragraph</p>
<div id="content">
<p>New content</p>
<p>Additional paragraph</p>
</div>
Diff view shows:
<div id="content">
- <p>Old content</p>
+ <p>New content</p>
+ <p>Additional paragraph</p>
</div>
Error Panel
Automatically surfaces HTMX failures grouped by type:
Error Types Detected:
- HTTP Errors: 4xx and 5xx responses (even in htmx 4.0 where they swap by default)
- Target Not Found:
hx-target selector doesn't match any element
- Network Timeouts: Request exceeds timeout threshold
- Swap Errors: DOM swap operation fails
Example Error Detection:
<button hx-get="/data" hx-target="#missing-element">
Click Me
</button>
<button hx-get="/nonexistent" hx-target="#output">
Load Missing
</button>
Errors appear with:
- Badge count per error type
- Click to jump to associated request in Request Inspector
- Full error details and context
Architecture
Extension Components
Page Script (MAIN world)
↓ postMessage
Content Script (isolated)
↓ chrome.runtime.sendMessage
Service Worker (background)
↓ chrome.runtime.sendMessage
DevTools Panel (Preact UI)
Page Script (src/page-script/index.ts):
- Runs in page's JavaScript context via
"world": "MAIN"
- Listens to all
htmx:* events (both 2.x and 4.0 naming)
- Serializes element data and tracks requests
- Batches messages every 50ms
Content Script (src/content-script/index.ts):
- Bridges page and extension contexts
- Relays messages via
window.postMessage and chrome.runtime.sendMessage
Background Service Worker (src/background/index.ts):
- Manages per-tab state
- Tracks request lifecycles
- Maps 2.x and 4.0 event names to canonical format
- Synthesizes HTTP errors for 4xx/5xx
- Routes data to DevTools panel
DevTools Panel (src/panel/):
- Preact + Signals UI (~55KB)
- Five tabs: Requests, Elements, Timeline, Swaps, Errors
- Real-time updates via message listeners
Version Detection
The extension auto-detects htmx version and adapts:
| Feature | htmx 2.x | htmx 4.0 |
|---|
| Event names | htmx:configRequest | htmx:config:request |
| Request tracking | XHR WeakMap | ctx object WeakMap |
| Detail structure | detail.elt, detail.xhr | detail.ctx.sourceElement, detail.ctx.response |
| Error events | 10 separate events | Unified htmx:error + synthetic |
Development
Build Commands
npm run dev
npm run build
npm run build:chrome
npm run build:firefox
npm run typecheck
Project Structure
htmx-devtools/
├── src/
│ ├── page-script/ # Injected into page context
│ ├── content-script/ # Bridge between page and extension
│ ├── background/ # Service worker for state management
│ ├── panel/ # Preact UI components
│ │ ├── components/ # UI components for each tab
│ │ ├── store/ # Signal-based state management
│ │ └── utils/ # Helper functions
│ └── shared/ # Shared types and utilities
├── public/ # Static assets (icons, manifests)
├── test/e2e/fixtures/ # Test server and demo pages
└── dist/ # Build output
Local Test Server
Start a local test server with comprehensive htmx examples:
node test/e2e/fixtures/test-server.js
Open http://localhost:3456 in your browser.
Test Scenarios Covered:
- GET/POST/PUT/DELETE requests
- Error scenarios (404, 500, timeout)
- All swap strategies (innerHTML, outerHTML, beforebegin, etc.)
- Out-of-band swaps
- Polling with
hx-trigger="every 2s"
- Search with debounce
- Click-to-edit pattern
- Todo list CRUD
Adding Custom Test Cases
Create HTML files in test/e2e/fixtures/ directory:
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/htmx.org@2.0.0"></script>
</head>
<body>
<button hx-get="/api/test" hx-target="#result">
Test Button
</button>
<div id="result"></div>
</body>
</html>
Access at http://localhost:3456/my-test.html
Common Patterns
Debugging Request Issues
Problem: Request not showing up in inspector
console.log(window.htmx);
const el = document.querySelector('[hx-get]');
console.log(el.getAttribute('hx-get'));
Problem: Target element not updating
<button hx-get="/data" hx-target="missing">Load</button>
<button hx-get="/data" hx-target="#content">Load</button>
<div id="content"></div>
Check Error Panel for "Target Not Found" errors.
Tracking Element State
Use Element Inspector to verify attribute resolution:
<div id="parent" hx-boost="true">
<a href="/page1">Link 1</a>
<a href="/page2">Link 2</a>
</div>
Element Inspector shows:
- Both
<a> elements inherit hx-boost behavior
- Click either link to see request in Request Inspector
- Request history shows all requests triggered by that element
Monitoring Swap Behavior
Enable Swap Visualizer before triggering swaps:
<button hx-get="/content" hx-target="#out" hx-swap="innerHTML">innerHTML</button>
<button hx-get="/content" hx-target="#out" hx-swap="outerHTML">outerHTML</button>
<button hx-get="/content" hx-target="#out" hx-swap="beforebegin">beforebegin</button>
<div id="out">Original content</div>
Swap Visualizer shows:
- Response HTML received from server
- Before/After DOM snapshots
- Diff highlighting exact changes
- Swap strategy and target info
Filtering Event Timeline
Use category filters to focus on specific event types:
Troubleshooting
Extension Not Appearing in DevTools
Issue: No HTMX tab in DevTools
Solution:
- Verify extension is installed: Check
chrome://extensions
- Ensure extension is enabled
- Reload the page after installing extension
- Check browser console for extension errors
- Try refreshing DevTools (close and reopen)
No Requests Being Captured
Issue: Request Inspector shows "No requests captured"
Solution:
console.log(window.htmx);
document.querySelectorAll('[hx-get], [hx-post], [hx-put], [hx-delete]');
const testBtn = document.createElement('button');
testBtn.setAttribute('hx-get', '/test');
testBtn.textContent = 'Test';
document.body.appendChild(testBtn);
htmx.process(testBtn);
testBtn.click();
Element Inspector Not Showing Elements
Issue: Element tree is empty
Solution:
- Verify page has elements with
hx-* attributes
- Click the refresh icon in Element Inspector
- Check if elements are dynamically loaded (wait for
htmx:load event)
- Use Element Picker (target icon) to directly select elements
Events Not Appearing in Timeline
Issue: Timeline shows "No events captured"
Solution:
document.addEventListener('htmx:afterRequest', (e) => {
console.log('Request completed:', e.detail);
});
Version Detection Issues
Issue: Wrong version badge or features not working
Solution:
console.log(htmx.version);
Performance Issues with Large Applications
Issue: DevTools panel becomes slow
Solution:
- Use Record/Pause controls to limit data capture
- Clear old requests periodically
- Filter Event Timeline to specific categories
- Disable Swap Visualizer when not actively debugging swaps
- Use search to narrow down large request lists
Extension Updates
Issue: New version available but not updating
Solution (Development Mode):
git pull origin main
npm install
npm run build:chrome
Browser Compatibility
- Chrome: 88+ (Manifest V3 support)
- Edge: 88+
- Brave: Latest
- Arc: Latest
- Opera: 74+
- Firefox: 128+ (Manifest V3 support in Firefox 128+)
Resources