kj-boost
Put kj-boost="true" on a container and its links and forms become AJAX requests that swap into body (or the inherited kj-target) and push the URL to history. Without JavaScript they still work as normal links — progressive enhancement for free.
Out-of-band swaps
Any top-level element in a response with kj-swap-oob="true" is pulled out and swapped into the element with the same id. Use a swap style (kj-swap-oob="beforeend:#log") to append instead of replace. kj-select-oob does the same from the requesting side, and $.hyper.oob(html) runs it from JavaScript.
The response is one line item plus two out-of-band elements.
View the source for this demo
<div class="row">
<button kj-post="/api/oob.php" kj-vals='js:{ item: "mug", n: +document.getElementById("oob-count").textContent }' kj-target="#oob-cart" kj-swap="beforeend">Add mug</button>
<button kj-post="/api/oob.php" kj-vals='js:{ item: "tee", n: +document.getElementById("oob-count").textContent }' kj-target="#oob-cart" kj-swap="beforeend">Add tee</button>
<button kj-post="/api/oob.php" kj-vals='js:{ item: "cap", n: +document.getElementById("oob-count").textContent }' kj-target="#oob-cart" kj-swap="beforeend">Add cap</button>
<span>Cart <span id="oob-count" class="badge">0</span></span>
</div>
<ul id="oob-cart" class="oob-cart" aria-live="polite"></ul>
<p id="oob-status" class="muted">The response is one line item plus two out-of-band elements.</p>Plain links — boosted into AJAX. Without JavaScript they would simply navigate.
View the source for this demo
<nav class="row" kj-boost="true" kj-target="#bo-panel" kj-push-url="false" aria-label="Boosted tabs">
<a class="btn" href="/api/tab.php?tab=core">Core</a>
<a class="btn" href="/api/tab.php?tab=hyper">Hyper</a>
<a class="btn" href="/api/tab.php?tab=pulse">Pulse</a>
<a class="btn" href="/api/tab.php?tab=motion">Motion</a>
</nav>
<div id="bo-panel" class="bo-panel" aria-live="polite"><p class="muted" style="margin:0">Plain links — boosted into AJAX. Without JavaScript they would simply navigate.</p></div>More examples
Server response with OOB elements
<!-- swapped into the request's target -->
<li>Mug — $12</li>
<!-- swapped by id, anywhere on the page -->
<span id="cart-count" kj-swap-oob="true">4</span>
<div kj-swap-oob="beforeend:#toasts"><p>Added to cart</p></div>API
How it goes in, with htmx's modifiers (View Transitions for transition:true).
Pick part of the response; swap extra pieces elsewhere; keep live elements.
Reference: kj-select →Programmatic access.
Reference: $.hyper →Migrating
hx-boost, hx-swap-oob and hx-select-oob behave the same as kj-boost, kj-swap-oob and kj-select-oob; responses written for htmx (with hx-swap-oob) also work.Related features
Targets & swaps
Control exactly where server HTML lands with kj-target and how it is inserted with kj-swap — innerHTML, outerHTML, beforebegin, afterbegin, beforeend, afterend, textContent or none..
Open →HyperHistory & deep links
Keep the address bar in sync with AJAX navigation using kj-push-url, and restore state on back/forward with a three-line popstate handler.
Open →HyperServer-Sent Events & WebSockets
Stream server updates into the page with kj-sse-connect and kj-sse-swap, or talk both ways with kj-ws-connect and kj-ws-send, using the jskjs.live.js add-on.
Open →