Drivers

The reactive core stays independent of the DOM. It runs a program and produces emissions, a plain description of what the program wants to show. A driver takes those emissions and renders them to a target. The DOM driver is one; it turns emissions into tags, attributes and text and keeps a page in step. The same core drives a console, a canvas, or a test harness just as well.

The core emits, the driver renders

As a program runs, its components emit descriptors into the current scope rather than touching the page. When the run finishes, the driver receives that emitted tree and projects it onto its target. Keeping the two apart is what lets the core stay small and target-agnostic: it decides what should be shown, the driver decides how.

1

State

The program's inputs: plain reactive state.

2

Run

The program re-runs and components emit descriptors.

3

Emissions

A tree of plain descriptors, still ahead of the DOM.

4

Driver

Renders the emissions to its target and patches changes.

The DOM driver

Reactive.Dom is the driver for the browser. Its component calls, Reactive.Dom.button, Reactive.Dom.input, and the rest, emit plain elements: a tag, some attributes, and text or child elements. They are the raw materials of an HTML page rather than widgets or a component library.

Rendering happens in two modes. The first time, the driver builds the elements and inserts them. On every run after that, it patches in place: it matches each new descriptor to the element it produced last time by stable identity, updates only the attributes and text that changed, and leaves everything else untouched. Re-running the whole program stays cheap because the driver rebuilds only what moved.

Mount ties a program to an element

Reactive.Mount is where a program meets its driver. Give it a program and a target element; it runs the program once, hands the emissions to the DOM driver to render, and then stays connected. From then on every Set schedules a re-run, and the driver reconciles the result against what is already on the page.

const app = Reactive.Program(() => {
  const count = Reactive.State(0);
  Reactive.Dom.button({ onclick: () => Reactive.Set(count, count.value + 1) },
    `Clicked ${count.value} times`);
});

Reactive.Mount(app, "#app");   // run + drive the DOM from here on
Mounting a program onto a DOM element

One program, different targets

Because emissions are data, the driver is swappable. A program written against the reactive core can be driven onto the DOM in the browser, printed by a console driver, or captured by a driver built for testing, all with the program unchanged. Separating the model from its rendering is what keeps Reactive a core you plug in rather than a framework you build around.