I built µJS because I wanted AJAX navigation without the verbosity of HTMX or the overhead of Turbo.
It intercepts links and form submissions, fetches pages via AJAX, and swaps fragments of the DOM. Single <script> tag, one call to `mu.init()`. No build step, no dependencies.
Key features: patch mode (update multiple fragments in one request), SSE support, DOM morphing via idiomorph, View Transitions, prefetch on hover, polling, and full HTTP verb support on any element.
At ~5KB gzipped, it's smaller than HTMX (16KB) and Turbo (25KB), and works with any backend: PHP, Python, Go, Ruby, whatever.
Playground: https://mujs.org/playground
Comparison with HTMX and Turbo: https://mujs.org/comparison
About the project creation, why and when: https://mujs.org/about
GitHub: https://github.com/Digicreon/muJS
Happy to discuss the project.
i have added it to the htmx alternatives page:
https://htmx.org/essays/alternatives/#ujs
Dead Comment
I just struggle to envision what application benefits from the efficiency that this or htmx offer, but from neither the ultra-interactive, nor the ultra-collaborative. Maybe updating stock ticker prices? Fast-service back-of-house ticketing displays?
I would love to feel called to reach for this library.
0. https://github.com/atlassian/pragmatic-drag-and-drop
1. https://github.com/yjs/yjs
Relying on server side as the source of truth inverts complexity. Suddenly 90% of the modern webs problems evaporate. Turns out building everything on top of a shadow dom in the client creates a boatload of unforced errors.
htmz is a minimalist HTML microframework for creating interactive and modular web user interfaces with the familiar simplicity of plain HTML.
htmz is a masterclass in simplicity. It’s gotta be the all time code golf winner.
There’s Artifex’s interpreter from muPDF. It’s also the basis of several JS related projects: https://mujs.com/
There’s also a lesser known interpreter: https://github.com/ccxvii/mujs
And IIRC, there was a CommonJS library of the same name.
µJS handles the AJAX call and swaps the fragment in the DOM. No JavaScript to write, no state to manage client-side. jQuery is more powerful and flexible, but that flexibility comes with complexity: you have to write the fetch call, handle the response, find the right DOM node, update it.
µJS does all of that declaratively via HTML attributes. It's not for every use case — highly interactive apps (think Google Maps or a rich text editor) still need proper JavaScript. But for the vast majority of web pages, server-rendered HTML fragments are simpler, faster to develop, and easier to maintain.
If you want something even more minimalistic, I did Swap.js: 100 lines of code, handles AJAX navigation, browser history, custom listeners when parts of DOM are swapped, etc.
https://github.com/josephernest/Swap.js
Using it for a few production products and it works quite well!
µJS now resolves URLs using the native URL constructor and compares origin against window.location.origin. This means all same-origin URLs are correctly recognized as internal: - Absolute URLs: https://domain:port/page - Relative URLs: ../page.html, page.html - Local paths: /page (already worked)
Hash-only links (#section) are intentionally left to the browser for native anchor scrolling.
I've done this previously with morphdom to AJAXify a purely server-driven backoffice system in a company.
I would love something even smaller. No `mu-` attributes (just rely on `id`, `href`, `rel`, `rev` and standard HTML semantics).
There's a nice `resource` attribute in RDFa which makes a lot of sense for these kinds of things: https://www.w3.org/TR/rdfa-lite/#h-resource
Overall, I think old 2015-era microdata like RDFa and this approach would work very well. Instead of reinventing attributes, using a standard.