Lifecycle-aware handlers
Use on:load, on:click, and other native events directly in markup.
HTML-first interactivity
Add polished interactions to server-rendered pages without adopting a full-stack JavaScript framework.
batsignal.js is an alternative to htmx and datastar for developers who want plug-and-play interactions with clean, server-rendered HTML.
Use on:load, on:click, and other native events directly in markup.
Links and forms fetch same-origin HTML and patch only the elements that changed.
Pair it with your existing backend and CSS instead of maintaining a large frontend application.
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 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.
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.
Every interactive element includes on:load, which makes batsignal initialize it.
$() is a short alias for document.querySelector().
Clicks the link and submits the form above, then verifies the resulting DOM patches.