Mininext is a web framework that brings the immediate mode GUI paradigm to the web. It automatically throttles rendering when the tab isn't visible, via the browser requestAnimationFrame throttling.
read the architecture document for more details
import { html } from "../mininext/mininext";
// ── static skeleton html ────────────────────────────────────────────────
const skeleton = await html`<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Counter</title>
<style>
body {
font-family: sans-serif;
text-align: center;
padding: 50px;
}
h1 {
font-size: 4rem;
}
button {
font-size: 1.5rem;
padding: 15px 30px;
}
</style>
</head>
<body>
<h1>Counter demo</h1>
<div id="count">${null}</div>
<form method="POST" action="/">
<button type="submit">+1</button>
</form>
<p>(form submit full page reload, zero JS on frontend)</p>
</body>
</html>`.build();
let globalCounter = 0;
// ── request handler ─────────────────────────────────────────────────────
function fetch(req: Request) {
// increment only on POST (form submit)
if (req.method === "POST") {
globalCounter++;
return Response.redirect("/", 303);
}
return new Response(
skeleton.fill(html`<div id="count">${globalCounter}</div>`),
);
}
// ── server ──────────────────────────────────────────────────────────────
const server = Bun.serve({
routes: skeleton.static_routes,
fetch,
});
// hmr support
globalThis.minireload = () => {
server.reload({
routes: skeleton.static_routes,
fetch,
});
};
console.log("Counter server running at http://localhost:3000");for a frontend counter example consult the counter demo repo
To install
bun add @spirobel/mininextsyntax highlighting:
github:
quickstart:
bun create spirobel/counter yournewprojectif you don't have bun installed, run first:
curl -fsSL https://bun.sh/install | bash # for macOS, Linux, and WSLTo install dependencies:
bun installdev:
bun run --hot counter.tsproduction:
NODE_ENV=production bun run counter.tsIf you understand these 3 basic concepts you can build your own webapp with mininext:
- html + css
- templating
- you can use data inside of your html templates