https://mizu.sh
mizu.js
*
*
*
*
*
*
mizu.js
Supercharge your HTML!
[deno][node][bun]
File
Edit
View
Run
Terminal
Help
ssr.ts
ssg.ts
ssr.mjs
ssg.mjs
ssr.ts
ssg.ts
#!/usr/bin/env -S deno serve --allow-read --allow-env
// Server-Side Rendering (SSR) with Mizu
import Mizu from "@mizu/render/server"
export default {
async fetch() {
const headers = new Headers({ "Content-Type": "text/html; charset=utf-8" })
const body = await Mizu.render(`
`, { context: { foo: " Yaa, mizu!" } })
return new Response(body, { headers })
},
}
#!/usr/bin/env -S deno run --allow-read --allow-env --allow-net --allow-write=/tmp/output
// Static Site Generation (SSG) with Mizu
import Mizu from "@mizu/render/server"
await Mizu.generate([
// Copy content from strings
[``, "index.html", { render: { context: { foo: " Yaa, mizu!" } } }],
// Copy content from callback return
[() => JSON.stringify(Date.now()), "timestamp.json"],
// Copy content from local files
["**/*", "static", { directory: "/fake/path" }],
// Copy content from URL
[new URL("https://matcha.mizu.sh/matcha.css"), "styles.css"],
], { clean: true, output: "/tmp/output" })
1
2
3
4
5
6
7
8
9
10
11
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Server-Side Rendering (SSR) with Mizu
import Mizu from "@mizu/render/server"
import { createServer } from "node:http"
createServer(async (_, response) => {
response.writeHead(200, { "Content-Type": "text/html; charset=utf-8" })
response.end(await Mizu.render(``, { context: { foo: " Yaa, mizu!" } }))
}).listen(8000, "0.0.0.0", () => console.log("Server is listening"))
// Static Site Generation (SSG) with Mizu
import Mizu from "@mizu/render/server"
await Mizu.generate([
// Copy content from strings
[``, "index.html", { render: { context: { foo: " Yaa, mizu!" } } }],
// Copy content from callback return
[() => JSON.stringify(Date.now()), "timestamp.json"],
// Copy content from local files
["**/*", "static", { directory: "/fake/path" }],
// Copy content from URL
[new URL("https://matcha.mizu.sh/matcha.css"), "styles.css"],
], { clean: true, output: "/tmp/output" })
1
2
3
4
5
6
7
8
1
2
3
4
5
6
7
8
9
10
11
12
13
// Server-Side Rendering (SSR) with Mizu
import Mizu from "@mizu/render/server"
Bun.serve({
port: 8000,
async fetch() {
const headers = new Headers({ "Content-Type": "text/html; charset=utf-8" })
const body = await Mizu.render(``, { context: { foo: " Yaa, mizu!" } })
return new Response(body, { headers })
},
})
console.log("Server is listening")
// Static Site Generation (SSG) with Mizu
import Mizu from "@mizu/render/server"
await Mizu.generate([
// Copy content from strings
[``, "index.html", { render: { context: { foo: " Yaa, mizu!" } } }],
// Copy content from callback return
[() => JSON.stringify(Date.now()), "timestamp.json"],
// Copy content from local files
["**/*", "static", { directory: "/fake/path" }],
// Copy content from URL
[new URL("https://matcha.mizu.sh/matcha.css"), "styles.css"],
], { clean: true, output: "/tmp/output" })
1
2
3
4
5
6
7
8
9
10
11
12
13
1
2
3
4
5
6
7
8
9
10
11
12
13
Terminal
Output
Ports
dev@mizu:~ $
deno add jsr:@mizu/render
npx jsr add @mizu/render
bunx jsr add @mizu/render
[browsers]
IIFE
ESM
[https://mizu.test/ii][https://mizu.test/es]
Yaa, mizu!
Elements
IIFE
{{ foo }}
ESM
{{ foo }}
browsers
deno
node
bun
Switch between browsers and runtimes using the icons above.
Change the current example by clicking on the tabs in the mockups.
Try out our online interactive playground and start experimenting
with mizu.js now!
Features
Plug-and-play
Simply include the library and start building amazing things
instantly with vanilla JavaScript expressions and HTML.
Cross-platform
Compatible across a wide range of JavaScript and TypeScript runtimes,
including all major browsers.
Any-side
Render your content wherever you need it and however you want it with
user-friendly APIs.
Hackable
Cherry-pick features and craft your own setup easily with
developer-friendly APIs and our custom builder.
Community-driven
Build, share and reuse custom elements and directives to supercharge
your development.
Want to effortlessly theme your page? Check out matcha.css!
Open-core
Licensed under the AGPLv3 License, source code fully available on
github.com.
Use MIT License terms for non-commercial projects or with an active
$1+ monthly sponsorship.
FAQ
Another web library? Really?
Yes, but hear us out!
Remember when building a web page was as simple as writing some HTML,
adding a bit of JavaScript, and styling with CSS? mizu.js brings back
that simplicity, offering a modern yet flexible approach to web
development.
By adhering closely to web standards and embracing the simplicity of
plain HTML and JavaScript, mizu.js offers an almost non-existent
learning curve. This makes it an excellent choice for both beginners
and seasoned developers.
Whether you're serving content from your favorite runtime, generating
static websites, or creating dynamic pages in the browser, mizu.js
adapts to your needs. -- All of it without the hassle of bundlers,
transpilers, or countless dependencies.
Why should I use mizu.js over other web frameworks?
We recognize the power and utility of comprehensive frameworks like
React, Vue.js, and Angular. These tools excel at building complex
applications and boast large communities and ecosystems. However,
they can be overwhelming for smaller projects, often requiring a
build step and a steep learning curve with their specific syntax and
concepts.
Lightweight alternatives such as Alpine.js and htmx are also
available. While they perform well in the browser, they were often
not designed for server-side use, limiting their applicability across
different scenarios.
mizu.js draws inspiration from all these frameworks but is designed
from the ground up to be:
* Flexible, suitable for single page applications, static websites,
interactive websites, and more.
* Versatile, works both client-side and server-side and in the
runtime of your choice.
* Simple, close to vanilla JavaScript and HTML and a minimal
learning curve.
* Customizable, easily opt-in/opt-out of features.
If all of this sounds appealing to you, then mizu.js might be the
right choice for your next project.
Does mizu.js use a Virtual DOM?
It depends.
On the server-side, mizu.js employs a Virtual DOM to simulate the
browser environment. The current implementation leverages JSDOM, but
you can use any other Virtual DOM library that adheres to web
standards. Non-compliant implementations may lead to unexpected
behaviors.
On the client-side, mizu.js interacts directly with the actual DOM.
It tracks processed elements and their states using weak references
to prevent memory leaks and enhance performance.
How reliable is mizu.js?
We want to ensure mizu.js delivers a reliable and consistent
experience across all supported environments, which is why each
feature is meticulously documented to detail its behavior and
functionality.
Our codebase is thoroughly tested and covered to guarantee that each
feature performs as expected. Integration tests are also performed on
various platforms and environment to ensure a consistent experience
as advertised.
If you encounter any issues or undocumented behavior, please open a
new issue so we can address it promptly.
What does the name mizu mean?
`Shui (mizu)' is the Japanese kanji for `water'.
Like water, mizu.js is fluid and adaptable, seamlessly fitting into
various use cases and execution environments.
Like water, mizu.js is simple and fundamental, staying close to
vanilla JavaScript and HTML with a minimal learning curve.
Like water, mizu.js is customizable, it can be mixed with other
libraries and additional features to suit your needs.
Need to add some flavor to your page? Add some matcha.css to your
mizu.js project! What is the licensing model of mizu.js?
mizu.js is licensed under the AGPLv3 License, allowing you to use it
freely for any project, provided you also distribute the source code
of your project that relies on it.
Alternatively, you can use mizu.js under the MIT License instead if
you meet one of the following conditions:
* Your project is non-commercial.
* You have an active $1+ monthly sponsorship.
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.
Looking for something? Jump to section:
* Directives
* Usage
* Concepts
* API
Directives
Rendering
*mizu
Phase1 -- ELIGIBILITY
Enable mizu.js rendering for the element and its children.
1 Restriction 1 Note $root
For performance reasons, this directive must not have any [tag] or
.modifiers. If it does, the directive will be ignored.
You can choose whether to require this directive for mizu.js
rendering with the implicit option when using the user API. By
default, rendering is explicit in Client-Side APIs and implicit in
Server-Side APIs.
Variables
$root: HTMLElement
The closest element that declares a *mizu directive.
Contextual
*set="context"
Phase11 -- CONTEXT
Set context values for an element and its children.
1 Restriction 1 Note
The context must resolve to a JavaScript Object.
The context is initialized once and persists across renderings, but
it can still be updated by other directives.
*ref="name"
Phase82 -- REFERENCE
Create a reference to an element for later use.
1 Note $refs .raw
Redefining a reference will shadow its previous value within the
current subtree, without affecting its value in the parent subtree.
Variables
$refs: Record
A collection of all referenced elements within the current subtree.
Modifiers
.raw[boolean=true]
Skip expression evaluation if set.
Conditional
*if="expression"
Phase23 -- TOGGLE
Conditionally render an element.
1 TBD
There is currently no special handling for elements, but
future versions may introduce specific behavior for these elements.
*else="expression"
Defaulttrue Phase23 -- TOGGLE
Conditionally render an element placed after another *if or *else
directive.
1 Restriction 1 TBD
Must be placed immediately after an element with an *if or *else
directive.
There is currently no special handling for elements, but
future versions may introduce specific behavior for these elements.
*show="expression"
Defaulttrue Phase71 -- DISPLAY
Conditionally display an element.
4 Notes
When hidden, the element's CSS display property is set to none !
important.
When shown and if initially hidden by a CSS stylesheet (display:
none), the element's display property is reset to initial !important.
Unlike *if and *else directives, the element remains in the DOM when
hidden.
You can take advantage of the default value being true to hide
elements before mizu.js loads (e.g.