Show HN: µJS, a 5KB alternative to Htmx and Turbo with zero dependencies (mujs.org)
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.
40 comments
[ 2.5 ms ] story [ 57.9 ms ] threadi have added it to the htmx alternatives page:
https://htmx.org/essays/alternatives/#ujs
htmz is a minimalist HTML microframework for creating interactive and modular web user interfaces with the familiar simplicity of plain HTML.
Sorry if I need to use existing APIs I cannot change.
As someone else mentioned, having your own server backend act as an intermediary between your front end and the API that serves JSON is probably the most straightforward solution to keep everything HTMX-y.
I mean if the devs and the users are all telling you it doesn't make sense, maybe it really doesn't make sense. Not everything is supposed to be able to do everything. Some things are targeted and focused on specific use cases.
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.
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.
Is there a mechanism for loading HTML partials that require additional style or script file? And possibly a way to trigger a JS action when loaded? For example, loading an image gallery.
I'll be checking this out. Any chance you (or anyone) has had a run with this lib + web components? I'd love to hear about it.
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!
Could you please add all sources as tabs? For example in Form (GET) I would really like to see /demos/search-results.html and the same goes for other examples.
Thanks!
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
As of now you don't need any frameworks for this. The new command and navigation apis, would just do the same trick.
One gripe with the name though is that I’m used to uTorrent’s and uws’s use of “u” for the “µ” character. So, my first guess would be to look for uJS to find this project, not muJS.
Also, perhaps the CDN script snippets in the getting started page should include the integrity attribute.
µ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.