Skip to content

Getting started ​

justdom is a family of small packages. Pick the ones for what you render:

To renderInstall
Reactive state onlyjustdom-signal
The DOM, on a page or on a serverjustdom-core and justdom-signal
A Three.js scenejustdom-three, justdom-signal and three
DOM panels in a scene, such as a keyboardjustdom-three-ui and the above
A WebXR sessionjustdom-xr with justdom-three

For example, a page that renders the DOM:

npm install justdom-core justdom-signal
js
import { Signal, just } from "justdom-signal";
import { $, children, set, on, text } from "justdom-core";

const count = Signal.of(0);

const Counter = $("button", [
  set({ className: "counter" }),
  on("click", () => count.set(count.get() + 1)),
  children(text`Clicked ${() => count.get()} times`),
]);

just(document.querySelector("#app"), [children(Counter)]).subscribe();

Three things in those lines are the whole model, and the next pages take them one at a time:

  • count is a signal: a value somebody writes. Reading it inside a getter, as the text template does, makes whatever runs the getter depend on it. Reactivity is about that.
  • $("button", [...]) builds a real element and the list of effects that keep it current. There is no virtual tree and no diff: set writes a property, on adds a listener, children places nodes, and each is wired to the one DOM write it stands for. Rendering the DOM is about that.
  • .subscribe() mounts the app. The render tree is a subscription tree: unsubscribing takes it down, in dependency order, running every cleanup. There is no separate mount and unmount API.

The todo demo is such a page. Add justdom-three and justdom-xr, and a headset shows the same DOM: the scene mirrors the element the app is mounted in into a panel in the room, so the app's interface is not built twice. DOM panels is about that.

The todo app on a pageThe same app in an emulated headset

The packages are JavaScript with JSDoc types, checked by tsc and shipped as source, so an editor sees every signature, and the .d.ts files a consumer gets are generated from the same comments. The API reference lists every export with its options and defaults.

To see what the packages can do, open the demos. Each one links to its source.