Small library, familiar HTML

batsignal.js is an alternative to htmx and datastar for developers who want plug-and-play interactions with clean, server-rendered HTML.

Lifecycle-aware handlers

Use on:load, on:click, and other native events directly in markup.

HTML responses

Links and forms fetch same-origin HTML and patch only the elements that changed.

Keep the stack simple

Pair it with your existing backend and CSS instead of maintaining a large frontend application.

Quick start

Load Idiomorph and batsignal.js immediately before the closing </body> tag.

<script src="https://unpkg.com/idiomorph@0.7.4/dist/idiomorph.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/jhthorsen/batsignal.js@main/batsignal.js"></script>

Then add on:load and an event handler to an element. The examples below are live, so you can see the behavior immediately.

Plugins

Plugins can add attribute-driven behavior to initialized elements. Explore the keyboard shortcut, outside click, copy to clipboard, debounce, shared store, persistent state, reveal, resize observer, timed visibility, form helpers, and form confirmation plugins.

Demo app

Submit a todo to fetch a tiny HTML response and append its table row without reloading the page. The input is remembered in localStorage, completed items update the count, and “Clear completed” removes them from the DOM. The empty-state row needs no JavaScript: CSS shows it only while it is the table body's only row.

The handlers use familiar, vanilla JavaScript, so you do not need to learn another framework. Together, batsignal.js and Idiomorph add only about 9 kB, compared with roughly 30 kB for Datastar and 50 kB for htmx 2.0.

Inspect the source to see how it works.

0 completed — Clear completed

No TODOs yet. Add one above.

on:click

Every interactive element includes on:load, which makes batsignal initialize it.

0

on:value

(empty)

ctx.listen

(waiting)

ctx.dispatch

(waiting)

$(parent, selector, [cb])

$() is a short alias for document.querySelector().

End-to-end test

Clicks the link and submits the form above, then verifies the resulting DOM patches.

Ready to run.