IdioMorph Algorithm: Preserving Focus, Scroll, and Audio State During Swaps
- Last updated
- Prerequisites:
- HTMX hx-swap strategies
- DOM tree mutation algorithms
- htmx
- idiomorph
- dom-morphing
- morph
- focus-preservation
- swap
Read at your depth
The practical view
Idiomorph is a DOM morphing algorithm used in HTMX via `hx-swap="morph"` or `hx-ext="morph"`. Unlike standard `innerHTML`/`outerHTML` (which tears down and re-creates DOM nodes, resetting input focus, active text selection, and playing video/audio), morphing diffs the live DOM tree against the incoming HTML and mutates only changed attributes and text nodes in place.
The same idea in other frameworks
React Virtual DOM reconciliation preserving focused input instances across renders.Angular `@for` track-by DOM node reuse during list re-evaluations.Vue 3 Virtual DOM patch algorithm reusing existing DOM elements.`hx-swap="morph"` with `idiomorph` extension.Legacy vs modern
Destructive outerHTML Swap vs Non-Destructive Idiomorph Morph
Standard `outerHTML` resets cursor position and destroys focus; `morph` preserves active typing state during live server updates.
<div hx-get="/search" hx-swap="outerHTML"> // ❌ Destroys input element and drops focus<form hx-ext="morph" hx-swap="morph:outerHTML"> // ✅ NEW: Focus and cursor preservedInterview gotchas
Context
Interviewers test your knowledge of DOM morphing algorithm evolution.
The mechanical answer
Idiomorph was created specifically for HTMX to address edge cases in `morphdom`. `morphdom` struggled with morphing disconnected subtrees, multiple top-level sibling nodes, and morphing between different tag types (e.g. `<div>` to `<section>`). Idiomorph handles multi-root fragments, morphing into `body` or `head`, and explicitly preserves custom web component shadow roots and form control states.
Trap
Do not assume `morph` is as fast as a raw `innerHTML` replacement; morphing adds a small CPU diffing pass, so only use it where preserving client focus/state is necessary.
Context
Checks understanding of element pairing heuristics during DOM diffing.
The mechanical answer
Idiomorph uses **ID matching as its primary anchor**. If an element in the incoming HTML has an `id` matching an element in the existing live DOM, Idiomorph pairs them together and morphs them in place, even if their position or parent container in the DOM hierarchy has moved. Elements without IDs fall back to soft structural matching (tag name and class matching).
Trap
Duplicate IDs in the same document will confuse the morphing algorithm and cause elements to jump to the wrong positions.