No description
Find a file
DarkWiiPlayer 05654a064f Expose State identifying symbol as class attribute
This is only for user convenience and to decouple the interface from the
actual name of the symbol.
2026-03-09 17:07:16 +01:00
documentation Expose State identifying symbol as class attribute 2026-03-09 17:07:16 +01:00
.editorconfig Add basic editorconfig 2024-06-24 12:27:05 +02:00
controller-registry.js Add ControllerRegistry 2026-02-19 21:08:00 +01:00
controllers.js Add ControllerRegistry 2026-02-19 21:08:00 +01:00
domProxy.js Fix error in DOM-Array 2026-02-24 10:25:53 +01:00
importmaps.html Add domProxy to exported modules 2025-11-19 16:58:31 +01:00
jsconfig.json Add jsdoc class annotations to skooma module 2024-02-12 13:38:57 +01:00
license.md Update metadata 2023-10-04 10:35:56 +02:00
mini.js Add explanation to mini-renderer 2025-11-15 20:16:57 +01:00
observable.js Expose State identifying symbol as class attribute 2026-03-09 17:07:16 +01:00
package.json Fix error in DOM-Array 2026-02-24 10:25:53 +01:00
readme.md Add jsdelivr badge to readme 2026-02-24 15:09:23 +01:00
ref.js Extract Ref class into separate module 2024-02-29 15:33:26 +01:00
render.js Expose State identifying symbol as class attribute 2026-03-09 17:07:16 +01:00

Nyooom

A lean and hackable front-end micro-framework

import {html} from "nyooom/render"
import {Observable} from "nyooom/observable"

const text = new Observable({value: "Nyooom is cool"})
setTimeout(() => {text.value = "Nyooom is awesome!"}, 1e5)

document.body.append(html.div(
    html.h1("Hello, World!"),
    html.p(text.signal("value"), {class: "amazing"}),
    html.button("Show Proof", {click: event => { alert("It's true!") }})
))

Goals

Arrakis teaches the attitude of the knife - chopping off what's incomplete and saying: "Now, it's complete because it's ended here."

— Frank Herbert, Dune

Nyooom aims to offer as much convenienve as possible within the following constraints:

  1. Small, independent modules that can also work on their own
  2. Easy to figure out by someone who doesn't normally use nyooom
  3. Easy to gradually introduce and remove rather than forcing big re-writes
  4. Flexible and hackable

Importmaps

The included file importmaps.html can be used as a starting point for importing nyooom via importmaps in a minimal environment. Search-and-replace ./ to wherever the library should be loaded from if necessary.

A few more examples:

Create a Button that deletes itself:

document.body.append(
	html.button("Delete Me", {click: event => event.target.remove()})
)

Turn a two-dimensional array into an HTML table:

const table = rows =>
	html.table(html.tbody(rows.map(
		row => html.tr(row.map(
			cell => html.rd(cell, {dataset: {
				content: cell.toLowerCase(),
			}})
		))
	)))

A list that you can add items to

let list, input = ""
document.body.append(html.div([
	list=html.ul(),
	html.input({type: 'text', input: e => input = e.target.value}),
	html.button({click: event => list.append(html.li(input))}, "Add"),
]))

A list that you can also delete items from

const listItem = content => html.li(
	html.span(content), " ", html.a("[remove]", {
		click: event => event.target.closest("li").remove(),
		style: { cursor: 'pointer', color: 'red' },
	})
)
let list, input = ""
document.body.append(html.div([
	list=html.ul(),
	html.input({type: 'text', input: e => input = e.target.value}),
	html.button({click: event => list.append(listItem(input))}, "Add"),
]))