mizu.js

Peaceful island in an ocean of bloats.
Coming soon.

Some 🍵 matcha.css while waiting?

@lowlighter

mizu.js is a JavaScript library designed to provide a simple and efficient way to create dynamic web pages without the need for a complex framework.

Ideal for fast prototyping, generating static HTML pages, and developers seeking to streamline their workflow without the need of setting up a fully-fledged environment.

🌊 Fun Fact: This very page is generated using mizu.js!

mizu.js is still in development.

While no public release is available yet, you can still take a look at what mizu.js will offer by browsing the documentation below. Note that it is subject to change.


Text directives

This set of directives allows you to manipulate the content of HTMLElements.

*text="content"

Set element's textContent.

<p *text="'...'">
<!--...-->
</p>
Empty value defaults to ''
HTML content is escaped.

*html="content"

Set element's innerHTML.

<template *html="'<p>...</p>'">
<!--<p>...</p>-->
</template>
Empty value defaults to ''
Rendering raw HTML may lead to XSS vulnerabilities.

Text render directives

This set of directives allows you to render and format content using external libraries.

*code="content"

Set element's textContent and perform syntax highlighting.

<code *code[javascript]="'...'">
<!--...-->
</code>
Empty value defaults to ''
This relies on an external dependency (highlight.js).

*markdown="content"

Set element's textContent and perform Markdown rendering.

<div *markdown="'...'">
<!--...-->
</div>
This relies on an external dependency (remark).

Conditional directives

This set of directives allows you to conditionally render content.

*if="expression"

Conditionally render a block.

<div *if="true">
<!--...-->
</div>
Empty value defaults to false

*else="expression"

Conditionally render a block after another *if or *else directive.

<div *if="false"></div>
<div *else="false"></div>
<div *else><!--...--></div>
Empty value defaults to true
Directive can only be defined on an element immediately preceded by another element that defines either a *if or *else directive.

Loop directives

This set of directives allows you to dynamically render content using iterable data.

*for="expression"

Duplicate and render a block for each iteration.

<!--<ul>-->
<li *for="const item of items"></li>
<!--</ul>-->
Any syntax that can be used by either a for, for...in or for...of loop is supported.

*id="expression"

Hint for *for directive to differentiate elements.

<!--<ol>-->
<li *for="const {id} of items" *id="id"></li>
<!--</ol>-->
Directive can only be defined on an element with a *for directive.
Resulting identifier must be unique within the loop. Any duplicate will be skipped.

Binding directives

This set of directives allows you to bind data to your content.

*set="context"

Set a context for the current element and its children.

<div *set="{foo:'bar'}">
<!--<span *text="foo"></span>-->
</div>

:attribute="value"

Bind an element's attribute value.

<a :href="url">
<!--...-->
</a>
Note that class, style and value (for applicable elements) attributes are handled differently.

:class="value"

Bind an element's class attribute.

<p :class="{foo: true, bar: false}">
<!--...-->
</p>

:style="value"

Bind an element's style attribute.

<p :style="{color: 'salmon'}]">
<!--...-->
</p>

:value="value"

Bind an <input>, <select> or <textarea> value in a bidirectional way.

<select :value="model">
<!--<option>...</option>-->
</select>

Event directives

This set of directives allows you create interactive elements that reacts to events.

@event="listener"

Listen for dispatched Event.

<button @click="this.value = 'Clicked!'">
<!--Not clicked yet-->
</button>
Empty value defaults to null
Multiple listeners can be attached to the same event by attaching a mizu [tag] (e.g. @click[1], @click[2], etc.).

HTTP directives

This set of directives inspired from htmx allows you to easily perform HTTP requests and handle responses.

%http="url"

Perform a fetch() call.

<div %http="'https://example.com'">
<!--...-->
</div>

%header[name]="value"

Set fetch() headers for a %http directive.

<div %header[x-foo]="'bar'">
<!--...-->
</div>
An header with either undefined or null value will be deleted.
An header with an Array value will have all of its value appended together.

%body="content"

Set fetch() body for a %http directive.

<div %body.json="{foo:'bar'}">
<!--...-->
</div>
Using a content modifier will automatically set Content-Type header.

%response="expression"

Reacts to a %http directive's response.

<div %http="'https://example.com'" %response.html>
<!--...-->
</div>
Empty value defaults to null
An empty %response.text directive will set element's textContent.
An empty %response.html directive will set element's innerHTML.

Custom element directives

This set of directives allows you to register and manipulate custom elements.

*custom-element="tag-name"

Register a new custom element.

<template *custom-element="'my-element'">
<ul><slot name="list"></slot></ul>
</template>
Directive can only be defined on a <template> element.
Evaluated tag-name must satisfy the definition of a valid name.
This does not use Shadow DOMs but rather duplicate the content of associated <template> inside the custom element.

#slot

Specify target <slot> in custom elements.

<my-element>
<li #list><!--...---></li>
</my-element>
Different elements can target the same slot.
Elements without a slot handle will be appended to the default slot.

*is="tag-name"

Dynamically change an element tagname.

<div *is="'section'">
<!--...-->
</div>

Processing directives

This set of directives allows you to control how mizu processes your content.

*skip

Skip any mizu directive.

<div *skip>
<!--<p *text="foo"></p>-->
</div>

*once

Render once and skip subsequent updates.

<div *once>
<!--...-->
</div>

*refresh="interval"

Force an update at a specified interval.

<div *refresh="5000">
<!--<time *text="new Date()"></time>-->
</div>