Understanding the htmx Swap and Settle Pipeline: 8 Stages Explained

The htmx swap and settle pipeline is an 8-stage deterministic process defined in src/htmx.js that transforms server responses into DOM updates, handling out-of-band content, element preservation, lifecycle events, and optional View Transitions in strict sequence.

The bigskysoftware/htmx library relies on a sophisticated DOM manipulation sequence to update web pages without full reloads. At the heart of this system lies the htmx swap and settle pipeline, which governs exactly how HTML fragments are processed, inserted, and finalized after a server request completes. Understanding these stages enables you to debug complex interactions and extend the library through its extension points.

What Is the Swap and Settle Pipeline?

The pipeline orchestrates every DOM mutation triggered by an htmx request through discrete, pure functions that receive a SwapOptions configuration object. Each stage runs in a deterministic order—Delay → Swap (including OOB) → After-swap events → Settle → View Transition—ensuring that extensions can hook into specific lifecycle points via ext.handleSwap or makeAjaxLoadTask.

The 8 Stages of the htmx Swap and Settle Pipeline

Stage 1: Prepare the Swap

Before any DOM insertion occurs, htmx resolves the target element and builds a DocumentFragment from the server response. In src/htmx.js (around lines 1880-1904), the resolveTarget and makeFragment functions handle parsing, while the focus preservation logic stores the current active element state to restore it later. This stage ensures the incoming content is sanitized and ready for insertion without disrupting the user's current context.

Stage 2: Out-of-Band (OOB) Handling

Elements marked with hx-swap-oob (or data-hx-swap-oob) are extracted and swapped before the main content insertion. The findAndSwapOobElements function (lines 1856-1869) scans the DocumentFragment for these markers and applies their updates immediately. This allows server responses to update multiple, unrelated parts of the DOM simultaneously while maintaining the pipeline's atomic nature.

Stage 3: Normal Swap Execution

The core DOM insertion happens through swapWithStyle (lines 1799-1819), which delegates to style-specific implementations like swapInnerHTML, swapOuterHTML, swapBeforeBegin, and swapAfterEnd. Based on the hx-swap attribute value—innerHTML, outerHTML, afterbegin, beforeend, etc.—htmx selects the appropriate low-level function to graft the new content into the target element.

Stage 4: Preserve and Restore Elements

To prevent element state loss, htmx identifies elements with hx-preserve before the swap and preserves them in memory. The handlePreservedElements function (around line 1450) marks these nodes, while restorePreservedElements (lines 1453+) re-inserts them into their original positions within the new content. This mechanism maintains video playback, Canvas drawings, or form inputs across DOM updates.

Stage 5: Fire Events and Restore Focus

Immediately after DOM insertion, htmx dispatches the htmx:afterSwap event and restores the previously saved focus and selection states. This stage also updates the document.title if the response includes a <title> tag. According to the source code around lines 1980-1984, this event signals that the DOM is stable but not yet fully settled, giving developers a hook to run pre-settle JavaScript.

Stage 6: Settle Phase

The doSettle function (around lines 209-218) executes post-swap tasks such as loading external fragments and initializing third-party libraries. Once complete, htmx fires the htmx:afterSettle event, indicating that all side effects have finished and the page is in its final state. Extensions often use this phase to attach event listeners to dynamically inserted content.

Stage 7: View-Transition Integration

If the browser supports the View Transition API and it is enabled, the entire swap sequence is wrapped in a document.startViewTransition call (lines 228-245). This provides smooth, animated transitions between the old and new DOM states, with the browser handling the visual interpolation while htmx manages the content replacement.

Stage 8: Delay Handling

Finally, the pipeline respects timing controls from the swap specification. The swapDelay and settleDelay values (processed around lines 249-254) introduce asynchronous pauses using timer logic, allowing for CSS animations or user confirmation before the swap or settle phases execute.

Hooking Into the Pipeline with Events

You can intercept every stage of the swap and settle pipeline using htmx's event system:

document.body.addEventListener('htmx:beforeSwap', function(evt) {
    console.log('About to swap:', evt.detail.target);
    // Modify evt.detail.serverResponse here if needed
});

document.body.addEventListener('htmx:afterSwap', function(evt) {
    console.log('Swap finished for', evt.detail.target);
    // DOM is updated but not yet settled
});

document.body.addEventListener('htmx:afterSettle', function(evt) {
    console.log('All settle tasks done');
    // Safe to query for new elements and attach listeners
});

Programmatic Control and Customization

For advanced use cases, you can trigger swaps manually using the internal API:

htmx.swap('#content', '<p>Programmatic HTML</p>', {
    swapStyle: 'innerHTML',
    swapDelay: 0,
    settleDelay: 0
});

In src/htmx.js, the SwapOptions object passed through each stage allows extensions to override default behaviors by implementing handleSwap or registering custom settle tasks via makeAjaxLoadTask.

Summary

  • The htmx swap and settle pipeline in src/htmx.js processes all server responses through 8 deterministic stages.
  • Out-of-band swaps occur before normal content insertion, enabling multi-target updates.
  • Element preservation via hx-preserve and the handlePreservedElements function maintains state across DOM mutations.
  • Lifecycle events (beforeSwap, afterSwap, afterSettle) provide precise hooks for custom logic.
  • View Transitions wrap the entire pipeline when enabled, offering smooth visual animations.
  • Delay controls (swapDelay, settleDelay) allow timing customization for animations or user feedback.

Frequently Asked Questions

What is the difference between swap and settle in htmx?

Swap refers to the physical DOM insertion of new HTML content, which happens in stages 1-5. Settle refers to the cleanup and initialization phase (stage 6) that runs after the DOM is stable, where external resources load and the afterSettle event fires. The swap phase changes the DOM; the settle phase finalizes it.

How do I preserve input focus during htmx swaps?

Add the hx-preserve attribute to any element you want to survive the swap. According to the source in src/htmx.js, the handlePreservedElements function stores these nodes before the swap and restorePreservedElements re-inserts them afterward, maintaining focus, scroll position, and element state automatically.

Can I delay the swap or settle phases?

Yes. The pipeline respects swapDelay and settleDelay values specified in the hx-swap attribute or passed via the SwapOptions object. As implemented around lines 249-254 in src/htmx.js, these values introduce asynchronous timers that postpone the respective phases, useful for coordinating with CSS transitions.

How does htmx handle View Transitions?

When enabled, stage 7 wraps the entire swap sequence in a document.startViewTransition call (lines 228-245). This creates a visual snapshot of the old state, performs the DOM updates, then animates to the new state. If the browser does not support the View Transition API, htmx falls back to the standard immediate swap behavior.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →