[HN Gopher] Show HN: Mizu.js - Lightweight HTML templating libra...
       ___________________________________________________________________
        
       Show HN: Mizu.js - Lightweight HTML templating library for any-side
       rendering
        
       Hey HN,  I'd like to share a fun project I've been working on:
       mizu.js.  It's a js library that add functional attributes support
       into your html, designed to be a simple and flexible alternative to
       fully-fledged web frameworks (such as Vue, React, and Angular),
       while offering more capabilities than other lightweight options
       (like Alpine.js and htmx).  As it's written using modern ES
       features and due to its isomorphic nature, it can be run in both
       browsers and runtimes (Node, Deno, Bun) without any changes. This
       makes it ideal for client-side and server-side rendering, as well
       as static site generation, whichever environment you prefer.  Just
       include the script in any web page (or backend) to get started. You
       can template content, bind attributes, add interactivity, handle
       HTTP interactions, create custom components, and much more -- all
       out of the box, without any configuration, transpilation steps, or
       builds.  I hope you'll find mizu.js as exciting and useful as I do
       and I'd love to get your feedback! You can learn more about it at
       https://mizu.sh!  Online playground: https://mizu.sh/playground
       Custom builder: https://mizu.sh/build Code coverage:
       https://mizu.sh/coverage GitHub: https://github.com/lowlighter/mizu
       ## Motivation ##  Nowadays, setting up a complete environment and
       installing thousands of packages is often required just to create a
       simple "Hello World" page. Yet, with the current ECMAScript
       standard, vanilla JS has never been more powerful. It offers built-
       in custom HTML components, proxies for changes tracking, weak
       references for better memory management, and many new data
       structures and methods.  So why is web development still insanely
       complex?  mizu.js aims to avoid adding bloat on top of native
       features, and instead focus on providing convenience helpers. It's
       basically "glue" around all these native features with added sugar,
       a recipe for a lightweight yet powerful utility.  All evaluated
       expressions are interpreted as vanilla JavaScript, and you add your
       instructions directly into your HTML. So if you know already know
       about JS/HTML, then you're already 80% know of how to use mizu.js
       (add an extra 10% if you've used Vue, Alpine.js or htmx in the past
       as some syntax and concepts are inspired by it), the rest is
       basically just remembering the directive names. The learning curve
       is that small.  Also, you may have heard of https://matcha.mizu.sh,
       a CSS stylesheet to instantly make your web page stylized. Well,
       it's a great companion to mizu.js. With both of them, you can
       create MVPs for your projects super fast!
        
       Author : lowlighter
       Score  : 102 points
       Date   : 2024-12-19 18:25 UTC (4 hours ago)
        
 (HTM) web link (mizu.sh)
 (TXT) w3m dump (mizu.sh)
        
       | pvg wrote:
       | A related thread about half a year ago
       | https://news.ycombinator.com/item?id=40455944
        
       | corinroyal wrote:
       | I love the information architecture of this site. You jump right
       | in to demonstration code and a reference and only later the
       | marketing text. So refreshing. I can see at a glance what the
       | project is and what makes it different. Kudos!
        
         | lowlighter wrote:
         | Thanks! It's always hard to find a nice balance between
         | explaining your project and showing how it actually work
        
       | phplovesong wrote:
       | Feels like knockoutjs, i recall using it 10 years ago. It was all
       | so simple back then.
        
         | MortyWaves wrote:
         | I recently used it in a legacy site. I had forgotten most of it
         | but I remembered enough. Turns out knockout introduced
         | components, around 2015 or so.
         | 
         | Yeah, actual components like you'd encounter with any modern
         | framework/library like React.
         | 
         | It has some nuances but they are pretty much real components,
         | and I was able to make some pretty advanced functionality in an
         | otherwise typical spaghetti code disaster.
         | 
         | Even wrote unit tests for it. People were in disbelief any of
         | this was even possible.
         | 
         | Turns out that while modern patterns and tooling go a long way,
         | they you still need to put effort into making quality software
         | of any kind.
        
           | egeozcan wrote:
           | I used Knockout.js professionally for many years. It
           | definitely has its warts, but I was very productive with it.
           | 
           | Apparently, they even have a v4 reboot: https://www.tko.io/
        
           | spmurrayzzz wrote:
           | > People were in disbelief any of this was even possible.
           | 
           | Maybe my memory is that bad now in my old(er) age. But at
           | that point in 2015, React had been a thing for about 2 years
           | already. Ember had components even earlier than that in
           | 2011/2012. Using components generally was a pretty well-
           | accepted pattern from my recollection. The wars between the
           | frameworks were all centered around render performance rather
           | than APIs (i.e. which virtual DOM was best? do you even need
           | a virtual DOM? etc.)
           | 
           | Not taking anything away from knockout per se, more just gut
           | checking my own understanding/remembrance of that dark age.
        
             | recursive wrote:
             | I read it as "were in disbelief that this was even possible
             | [in knockout]".
        
       | alexchamberlain wrote:
       | The licence seems messed up. You can opt to use an MIT licence,
       | but only if you're noncommercial or you pay. The MIT licence
       | explicitly states that the software is provided free of charge,
       | and can be sublicensed, so anyone with an MIT copy, can give it
       | away for free.
        
         | benatkin wrote:
         | It's valid. It's not the MIT license, but it's not messed up or
         | confused either. It's just an unusual license.
         | 
         | It means you don't have to GPL your own code while your project
         | is non-commercial and you aren't paying for it. If you decided
         | to make your project comercial you could migrate away from it
         | or pay for it. It also seems to have a loophole if you
         | interpret it a certain way and transfer it, because the person
         | agreeing and the person receiving it under the MIT license
         | would be different people.
        
           | kube-system wrote:
           | Couldn't someone just download it from some third party
           | mirror and use it under the MIT license?
        
             | benatkin wrote:
             | Not unless they first removed the other part of the license
             | for this mirror, which to me it seems the MIT license
             | allows you to do. That said, I don't think most want to use
             | open source under a loophole. So such a mirror isn't that
             | likely to take off.
        
         | wccrawford wrote:
         | That alone makes me not want to use it. Licensing has to be
         | clean and clear for it to have any chance with me.
        
         | jraph wrote:
         | Yeah, you probably don't want to license under MIT for
         | proprietary use cases. You could take inspiration from the Qt
         | project for how they do this.
         | 
         | It takes one "non-commercial" project to release their code and
         | people can use the MIT licensed version without restriction.
         | 
         | The concept of non-commercial itself is shady: what if someone
         | releases something non commercially, and then someone else uses
         | it commercially?
         | 
         | You probably want to get rid of this, it's complex to
         | understand and to apply. You could have:
         | 
         | - an AGPLv3 version that open source projects will be able to
         | use (commercially or not, there are many successful commercial
         | open source projects)
         | 
         | - a custom proprietary license that someone can use only if
         | they pay, and de facto their project cannot be open source
         | 
         | Of course, this also means that your code can't be used by
         | projects that want to be released under the MIT license. People
         | will need to release under the AGPLv3.
        
         | lowlighter wrote:
         | Yeah maybe I'll look into a simpler licensing as it may indeed
         | be confusing and just drop the requirement, it's not like I
         | really planned to make money with it anyways.
         | 
         | While I doubt this project will ever reach the popularity of
         | projects such as docker, terraform, mondogb, wordpress, corejs,
         | and many others, I'd like to avoid having issues that they
         | encountered later due to their licensing.
         | 
         | Basically having companies that could afford to contribute and
         | help maintainers but that choose to not do it just for pure
         | greed, while keeping it free for everyone else that continue to
         | make open project or just non-profit/personal use case.
         | 
         | As I'm no legal expert, the intention may not have been very
         | clear in the wording though
        
       | TripleChecker wrote:
       | It reminds me of vue templates. I'd love to see some benchmarks
       | comparing it with react jsx and vue/nuxt, both for server-side
       | and client-side. Thanks!
       | 
       | Caught 1 typo and 1 broken link on the site in case you'd like to
       | fix: https://triplechecker.com/s/477573/mizu.sh
        
         | benatkin wrote:
         | Vue is still recognizable as HTML, and to me looks more like
         | HTML than JSX. This looks less like HTML to me than either Vue
         | or JSX. It reminds me of Marko. Marko still looks messy to me
         | after having tried to get into it, but YMMV.
        
           | lowlighter wrote:
           | It's because it's mostly based on the vue syntax short hands
           | (@ for event, # for slots and : for attribute bindings, ::
           | was also proposed at a time for model in vue too but it was
           | still being discussed last time i checked)
           | 
           | Rather than using a v- prefix like vue has, mizu uses *, but
           | it's essentially the same.
           | 
           | All in all, I feel like it's still pretty close to what vue
           | offers, at least when you plug it directly to your html page
           | without passing by the component/composition way of writing
           | vue.
           | 
           | I took a lot from vue (maybe more petite-vue at this point)
           | and alpine to make mizu actually
        
         | lowlighter wrote:
         | Thanks for catching this, I'll look into it!
        
         | leopoldj wrote:
         | I have created a templating system in Java that uses the Vue
         | syntax. Many of the common features are present. To minimize
         | dependency, I chose to use Java's built-in XML parser to parse
         | the template. Which means, the template has to be a valid XML.
         | I've been using it mainly to generate email content.
         | 
         | https://github.com/bibhas2/Zippy
        
       | malkosta wrote:
       | I have a 60 LOC [bash script][1] to do something similar to my
       | personal blog
       | 
       | [1]:
       | https://github.com/alexandremcosta/alexandremcosta.github.io...
        
       | spankalee wrote:
       | I love that this lets you create custom elements! I think that's
       | a big missing feature from HTMX (even though HTMX can already use
       | custom elements).
       | 
       | I'm working on a somewhat similar system called Heximal. It
       | focuses on adding full-fledged templating to the <template>
       | element, and full declarative component definitions to HTML, plus
       | some built-in custom elements like <h-var>, <h-out>, <h-scope>,
       | <h-include>, and <h-fetch> that make HTML more of a declarative
       | programming language.
       | 
       | A big difference from HTMX is that it doesn't rely on magic
       | attributes, but instead adds full data-binding with rich
       | expressions for any attribute or text content, and control flow,
       | to <template>. And component definitions include defining
       | properties, attributes, styles, etc.
       | 
       | These things are being proposed for HTML, so Heximal is somewhat
       | of a polyfill for HTML from the future. Or it's a bit like Tangle
       | or Curvenote.
       | 
       | https://github.com/elematic/heximal/
        
       | beders wrote:
       | We've been down this road before many times.
       | 
       | On adoption things are simple and clean.
       | 
       | Then your product becomes more complicated and your requirements
       | for data handling outgrow what a tool like mizu can offer.
       | 
       | Then you are facing a choice: Redo everything in a more scalable
       | and expensive (as in dev training, qe needs) framework/library or
       | stick with that you have?
       | 
       | Choose carefully.
        
         | jchw wrote:
         | My personal first experience with this was Riot.js. Ultimately,
         | I still enjoyed using it, but writing large applications in
         | micro frameworks is hard: it feels like either the micro
         | framework grows substantially and starts to lose its original
         | appeal, or your application grows framework-like limbs and
         | suddenly the appeal of using a micro-framework is somewhat
         | diminished.
         | 
         | I would guess the only real way out is to always carefully
         | constrain your scope and keep your application as simple as
         | possible. Easier said than done...
        
         | spankalee wrote:
         | Do you have specific reasons why this would be true of Mizu?
         | 
         | It's certainly possible to build sufficiently rich data
         | handling and modularization into HTML, and to make seamless
         | integration between HTML and components and JS.
         | 
         | The fact that plain HTML can be extended with custom elements
         | already means that just about any HTML system can be decomposed
         | so that the the most complex things are encapsulated behind
         | components.
        
         | lowlighter wrote:
         | I think rather the issue being new library popping up is more
         | about choosing the right tool for the right project.
         | 
         | If you know that your project is going to be small-scaled (a
         | MVP or POC, a blog, a UI for your home lab, a static website,
         | etc.) then mizu and tools alike may be a good choice.
         | 
         | If you know that you eventually want to have thousands of
         | customers, with hundreds of collaborators, then it might indeed
         | be not the best fit. Going with a more "common" framework like
         | the big name React and Vue is probably better.
         | 
         | Web dev nowadays offer a wide range of application, so everyone
         | needs is different so a one-size-fits-all framework/library is
         | almost impossible to achieve in my opinion
        
       | keb_ wrote:
       | I actually really love this, and have been wanting something like
       | this for a while. Excited to give it a try.
        
       | welder wrote:
       | I've been using React templating lately, then you get a lot of
       | cool features like Tailwind and can even use React for your email
       | templates:
       | 
       | https://react.email/docs/introduction
       | 
       | It helps me ship faster when I use the same stack everywhere. I
       | even ported my background task library to TypeScript so to keep
       | the stack the same:
       | 
       | https://github.com/wakatime/wakaq-ts
        
       | gwbas1c wrote:
       | > In summary, mizu.js is free for open-source and non-commercial
       | projects, while a small contribution is required for commercial
       | closed-source projects to support its development.
       | 
       | That's... weird.
       | 
       | I've evaluated front-end frameworks in the past and considered
       | both free (open source and no cost) against commercial. I can't
       | explain why, but the mandatory donation for commercial use just
       | rubs me the wrong way.
       | 
       | (And don't get me wrong, I've published my own basic HTML
       | templating library here:
       | https://www.npmjs.com/package/pogon.html)
       | 
       | Perhaps I can explain it this way: If I'm doing a hobby/learning
       | project, there's no obstacle to using Mizu. But, if I'm a rank-
       | and-file employee, _experimenting,_ setting up the $1  / month
       | donation is actually a huge obstacle. It's not the cost, it's the
       | actual act of handling money. Furthermore, Mizu will need a lot
       | of paying customers for the monthly donations to actually pay for
       | anything substantial.
       | 
       | Personally, I would think more carefully about how to derive
       | income from Mizu.
        
         | gavmor wrote:
         | Right, $1 / month is not worth the overhead to enterprise
         | customers. My understanding is that many would rather find a
         | $10,000 / month solution that has all the bells and whistles--
         | and a support contract!
         | 
         | Is there an uncanny valley between free and enterprise--or is
         | that actually a fertile long tail?
        
       | imiric wrote:
       | I like the focus on simplicity, but I really wish frontend
       | frameworks and libraries would stop abusing HTML.
       | 
       | Markup should only contain content and presentation. If it needs
       | to be templated, then that's best done using a separate syntax.
       | 
       | If we need functionality, then that's the domain of JavaScript
       | and programming languages.
       | 
       | We learned the importance of semantic HTML decades ago when we
       | stopped using style elements and left this exclusively to CSS.
       | 
       | Separation of concerns is important. Yet modern frameworks insist
       | on blurring these lines for some reason, and we end up with
       | bastardized syntax, writing JS inline in attribute values, and
       | cramming dozens of utility classes to style a single element
       | (Tailwind is an abomination).
       | 
       | I don't mind frameworks that embrace components while keeping
       | this separation clear. I think Svelte does a pretty good job at
       | that, or at least it does a good job at hiding the magic it does
       | to achieve this illusion from the developer. But from my limited
       | exposure to Vue, React and Angular, these are not frameworks we
       | should take inspiration from, and mizu looks even more jarring
       | than those.
        
         | skgough wrote:
         | Can you talk about why separation of concerns is useful? I like
         | it too, but I have a hard time trying to articulate why I
         | prefer it over keeping everything in the same file. I've
         | started working in a project that uses react and tailwind, and
         | I've gotten pretty comfortable, but (ideological purity aside)
         | it just isn't very enjoyable to use.
        
           | imiric wrote:
           | It's the contextual clarity for me. If I want to change the
           | content, I can keep a specific syntax in mind and focus only
           | on that. Same for JavaScript and CSS. I don't have to think
           | about all of these things at once, but only at the boundaries
           | where they interact with each other. Every component has a
           | separate responsibility and they're composed in a specific
           | way, but keeping them separate allows you to reason about
           | them easier. This is similar to the Single Responsibility
           | Principle.
           | 
           | Specialization is another aspect. Take this example from the
           | mizu docs:                 <div %http="https://example.com">
           | 
           | That is supposed to make a `fetch()` call. OK, great, so how
           | do I make a POST request? Oh, with a `.post` "modifier". OK,
           | great, so how do I specify the body? Oh, with a `%body`
           | directive. OK, great, but what if I want to use a different
           | encoding than the ones provided by the library? How about
           | binary data? How about sending a specific header based on a
           | condition, or interpreting the response in a specific way?
           | 
           | There are thousands of these questions and possible
           | limitations and pitfalls that just wouldn't exist if the
           | library didn't try to reinvent JavaScript in HTML. Just use
           | the right tool for the job that is already specialized for
           | what you're trying to do, and your task will be much easier.
           | 
           | BTW, I don't mind having components that contain JS, CSS and
           | HTML in the same file. Svelte does this and I enjoyed using
           | it. My problem is when these are mixed, or when CSS is
           | entirely abandoned in favor of thousands of micro utility
           | classes like Tailwind does.
        
       | gavmor wrote:
       | Slick looking website, novel and relatively intuitive DSL, solid
       | documentation!
       | 
       | Parsing the playground demo was a fun scavenger hunt! Too fun...
       | it took me several minutes to find `(coins += income)` at the
       | line break. For me, it's difficult to scan for "code" that's in-
       | lined as strings. That <progress/> eval, especially, is a doozy!
       | 
       | > Use this [eval] directive sparingly, prefer alternative
       | directives for better maintainability and security. This
       | directive is intended for edge cases.
       | 
       | Oh, and yet *eval is the heart and soul of the demo? In fact, it
       | looks like the principal action--creating buildings--is performed
       | by... the progress bar? That's low-cohesion and high-coupling if
       | I've ever seen it.
       | 
       | I would want to know: what are the Mizu ways of modularizing code
       | to increase cohesion and decrease coupling?
       | 
       | Anyways, thanks for sharing and congrats on launching.
        
         | CharlieDigital wrote:
         | > I would want to know: what are the Mizu ways of modularizing
         | code to increase cohesion and decrease coupling?
         | 
         | Ostensibly exactly what you would do with JavaScript.
         | 
         | Write a class or function closure similar to Vue composables.
         | 
         | It's not really the framework or library's job of making your
         | code more modular; _that 's your job_ by writing good code.
        
         | lowlighter wrote:
         | Yeah the playground is intended to show many directives to
         | display the capabilities, but I wouldn't recommend making
         | complex apps entirely with the iife version. It's mostly
         | intended for templating (like conditional, iterations, htmx-
         | like op).
         | 
         | The ESM version is better suited for small dynamic apps as you
         | can handle context in a better way, and define helper functions
         | rather than declaring them in a html attribute. It makes the
         | code more readable too and this how you'd be able to achieve a
         | more cohesive app.
         | 
         | As for the eval, it's true the doc advertise against, but maybe
         | I was a bit too harsh about it. The reasoning behind avoiding
         | it is the same as "eval()" in js. It's kind of a "god mode"
         | (like you could do *eval="this.remove()") and it may mess up
         | your final rendering as some internal reference may not be
         | properly cleared if you do niche stuff. If you know what you're
         | doing there's no particular issue with it
        
       | esco27 wrote:
       | I appreciate the no-build-step approach. It's refreshing to see a
       | return to simplicity, even if it feels cyclical--similar
       | libraries have come and gone, but that's how the web evolves. As
       | browsers continue to improve and embrace web standards, it makes
       | sense to lean into tools that trend toward minimalism and
       | simplicity. Great job!
        
       | err4nt wrote:
       | I wish it didn't require authors to practice doing the wrong
       | thing (writing invalid HTML) for to use the tool.
       | 
       | Authors are free to either create any data-* attributes they wish
       | for any purpose, so long as the custom attributes are prefixed
       | with "data-".
       | 
       | Authors are also free to create any (valid) HTML custom element,
       | and to invent custom attributes for those elements.
       | 
       | But this appears to require authors to write invalid HTML.
        
         | zamalek wrote:
         | You should be able to use qnames (foo:bar) for attributes, I
         | think? The problem with data-* is that it's misuse, template
         | directives aren't really data. E.g. something might actually
         | use data-if, which would probably collide with a template
         | directive.
        
           | lowlighter wrote:
           | Using qualified names is actually it good idea (similar to
           | svg there could be a custom namespace for mizu)
           | 
           | It'll kind of solve the previous commenter concerns about
           | with writing invalid html. While namespaces are more a xml
           | thing, there are probably many benefits to this approach like
           | querying all attributes from the namespace at once too.
           | 
           | I'll keep this in mind for future iterations!
        
       | xingwu wrote:
       | The site is well organized and the information flows smoothly,
       | nice job.
        
       | omtinez wrote:
       | Really cool work, congrats!
       | 
       | I built my own frontend framework for similar reasons:
       | https://github.com/fresho-dev/mancha. It was meant to adress the
       | lack of lightweight solutions that worked both on the frontend
       | and the backend. The main goal was to start with client side
       | rendering and, only if you reach the point where you need it,
       | switch to server side rendering. It also includes a drop in
       | replacement for TailwindCSS except it won't yell at you for doing
       | everything client side.
       | 
       | What I really wanted was a better maintained version of
       | PetiteVue. But that highlights another problem: I simply can't
       | trust anyone in the frontend JavaScript ecosystem, I've been
       | burned too many times. It took a while to get to the point of it
       | being usable, but now I know no one can pull the rug from under
       | me. I use only the most basic APIs possible, only 1-2 third party
       | dependencies, and as little hacks as possible.
       | 
       | It still has a few warts here and there but I hope to be able to
       | call it a 1.0 stable version soon enough.
        
       ___________________________________________________________________
       (page generated 2024-12-19 23:00 UTC)