Denier is a tiny library for building web frontend stuff.
Yes — it's yet another kind-of reactive web-UI library. I guess we should throw in "opiniated" too.
Denier has templates, events, context-provided objects, state, efficient DOM updates, typed styles et.c.
All in about 850 lines of code, with no external run-time dependencies. The minimized and gzipped version (why do we still list this?) is about 3k.
- Simple life-cycle, no magic.
- No extra DOMs or diffing.
- Mixes well with other libraries and frameworks.
- No special syntax, just plain HTML and Javascript/Typescript.
- Nice debug helpers
The name "Denier" refers to the unit for tiny thread sizes, and the fact that we deny the existence of all other similar frameworks. Or not. It's just a name. 🧦
A Denier template is created using html
- tagged strings:
const message = "Hello, world!";
const template = html`
<span>${message}</span>
`;
Templates are rendered into host tags:
<body>
<div id="my-app"></div>
</body>
const host = document.getElementById("my-app");
template.render(host!);
This would result in the following:
<body>
<span>Hello, world!</span>
</body>
Note that the template replaces the host tag!
By using a template within another template, we have a simple method for creating components:
function title(t) {
return html`<h2>${t}</h2>`;
}
const template = html`
<div>${title("Hello!")}</div>
`;
Templates are plain Javascript raw strings with interpolated values. Once created, they are static.
Templates can have dynamic parts by using functions or directives as interpolated values:
const now = () => new Date().toLocaleString("sv");
const dynamic = html`
<span>${now}</span>
`;
However, templates are not updated just because time passes. That's what the template update()
method is for.
By calling update()
, the template and interpolated values are re-evaluated and updated in place.
Updating a template is shallow - sub-templates are not updated when the parent template is.
Denier has a simple attribute directive for adding event handlers:
function doStuff(e) {
// Stuff being done here
}
const button = html`
<button ${on("click", (e) => doStuff(e))}>PRESS ME</button>
`;
List items can be keyed to allow for efficient update handling:
const list = html`
<ul>${items.map((item) => html`<li>${item.name}</li>`.key(item.id))}</ul>
`
- state in, UI out
- events in, state out
TBW
- Cleanup handler
TBW
- on
- ref
- flag
- provide
- using
- build
- style
TBW
- No "safe" or "raw" HTML input
TBW
- More docs
- More tests and testing
- More examples
- HMR