Background
htmx 4.0.0-beta3 (now on main after #1770) ships a new hx-live extension that introduces a small DOM-reactivity layer plus a richer JS surface inside hx-on. From the upstream changelog and docs:
hx-live="..." — a JS expression that re-evaluates whenever any DOM input/change/mutation event fires on the page
q(selector) — a jQuery-like proxy over a set of elements: supports next/prev/closest/first/last selectors, '.foo in .bar' scoping, set-property forwarding (q('.x').value = 'y' writes to all), array methods (map/filter/reduce), and chainable mutators (.trigger, .insert, .take, .toggle)
- Sigil-syntax
toggle(...specs) — toggle('.class'), toggle('@attr'), toggle('@x=on|off'), toggle('*display=none|block')
- Per-element
debounce(ms[, fn]) — closure form (channel-keyed by fn.toString()) and promise form (cancellation via async rejection)
htmx.live namespace exposes the same primitives outside expression scope: htmx.live.q, htmx.live.take(target, className, source), etc.
- Breaking:
htmx.takeClass and htmx.forEvent moved out of htmx core into this extension
Upstream extension docs: https://four.htmx.org/extensions/hx-live/
Why this is worth a separate evaluation
The original beta3 review flagged this as the one new feature that required a stack-shape decision rather than a doc-or-config tweak. Adopting hx-live would change the way we think about client-side reactivity in vibetuner apps — currently we either round-trip to the server for state changes (htmx core) or write inline hx-on: handlers for very local UI state. hx-live sits in between, and it overlaps with what people would otherwise reach for Alpine.js or stimulus-style controllers to do.
What this issue should produce
- A short experiment: pick 2-3 representative interactions in our showcase apps (e.g. live-validating a form field, syncing two paired controls, optimistically updating a counter) and implement them with
hx-live + q()/toggle()/debounce()
- A take on whether
hx-live should be:
- (a) Recommended as a default-on import in
vibetuner-template/config.js
- (b) Documented as an optional tool with example patterns
- (c) Avoided in framework recommendations
- If we adopt it, identify any framework templates that should be rewritten to use it
- Capture the upstream-documented rough edges (
.self.once / .outside.once edge case in hx-on, hx-config config restrictions, etc.) so we don't get blindsided
Non-goals
- Migrating off htmx-core for state we currently round-trip to the server —
hx-live is for client-side reactivity, not a replacement for server-rendered partials
- Replacing existing
hx-on: handlers wholesale
Related
🤖 Filed via Claude Code from the htmx beta3 review thread.
Background
htmx 4.0.0-beta3 (now on
mainafter #1770) ships a newhx-liveextension that introduces a small DOM-reactivity layer plus a richer JS surface insidehx-on. From the upstream changelog and docs:hx-live="..."— a JS expression that re-evaluates whenever any DOMinput/change/mutationevent fires on the pageq(selector)— a jQuery-like proxy over a set of elements: supportsnext/prev/closest/first/lastselectors,'.foo in .bar'scoping, set-property forwarding (q('.x').value = 'y'writes to all), array methods (map/filter/reduce), and chainable mutators (.trigger,.insert,.take,.toggle)toggle(...specs)—toggle('.class'),toggle('@attr'),toggle('@x=on|off'),toggle('*display=none|block')debounce(ms[, fn])— closure form (channel-keyed byfn.toString()) and promise form (cancellation via async rejection)htmx.livenamespace exposes the same primitives outside expression scope:htmx.live.q,htmx.live.take(target, className, source), etc.htmx.takeClassandhtmx.forEventmoved out of htmx core into this extensionUpstream extension docs: https://four.htmx.org/extensions/hx-live/
Why this is worth a separate evaluation
The original beta3 review flagged this as the one new feature that required a stack-shape decision rather than a doc-or-config tweak. Adopting
hx-livewould change the way we think about client-side reactivity in vibetuner apps — currently we either round-trip to the server for state changes (htmx core) or write inlinehx-on:handlers for very local UI state.hx-livesits in between, and it overlaps with what people would otherwise reach for Alpine.js or stimulus-style controllers to do.What this issue should produce
hx-live+q()/toggle()/debounce()hx-liveshould be:vibetuner-template/config.js.self.once/.outside.onceedge case in hx-on,hx-configconfig restrictions, etc.) so we don't get blindsidedNon-goals
hx-liveis for client-side reactivity, not a replacement for server-rendered partialshx-on:handlers wholesaleRelated
vibetuner-docs/docs/htmx-migration.md🤖 Filed via Claude Code from the htmx beta3 review thread.