Usage

Reactive is a reactive programming framework for the browser. It gives you a small, predictable model of state, calculations, reverse calculations, control flow and effects, plus a plain DOM driver to project that model onto the page.

The idea

Most frameworks bundle a reactive core together with a large user-interface library: components, layout, widgets, styling. Reactive keeps only the core. It offers a simplified DOM driver that deals in tags, attributes and text. That makes it small, easy to reason about, and simple to drop into an existing page.

The result is a framework you plug in. Mount a reactive component into any element and leave the rest of the page exactly as it is.

Where it comes from

Reactive is a small, hand-written JavaScript library, built from scratch for the browser. Its model, reactive values with readable and writable halves, forward calculations, reverse calculations, and lock-aware readiness, is drawn from a larger reactive system, then refined and tuned to fit JavaScript. The result is a focused runtime you can read in an afternoon.

The runtime primitives live under one object, Reactive: State, Set, Mount, If, Reverse and the rest. Library modules are their own top-level globals: you declare one with Reactive.Module, then call it directly, such as Content.Title(...) or Maths.Add(...). The surface stays small and it runs straight in the browser with no build step and no imports.

What makes it different

Four choices set Reactive apart. Each links to its full page.

A read lock and a write lock. Every value is boxed. The read is the value and one read lock. The write refers to a state or a reverse, and its lock is a counter. A lock carries no error and no retry. Those belong to the application. A calculation uses a read-locked value, and its result is read-locked. The program does not look at the lock. A driver does.

Reversibility in place of event handlers. Interaction is a write. Setting a reverse runs its block, and Reactive.Set carries that write out to state. You understand a control by reading the output or the binding it was given.

Contexts. A context is a set of functions whose implementation is supplied where the program runs. Reactive.With installs one implementation for a region. A body in that layer calls the implementation underneath, not the sibling written beside it.

Drivers. Each driver implements one context and is injected before the program runs. A call of that context enters the driver during the refresh. Maths, strings, Logic.Maybe, and arrays are those calls. The driver also registers the native types.

Principles

Coding standards

Reactive programs are written in a deliberately small, strict subset of JavaScript. Keeping to it lets the framework read your program, reason about readiness, direction and identity for you, and keep the code tidy as it grows. The rules are few:

Reactive.Function(Collection.Array.Of(Ui.Component), "Render", () => {
  const children = Reactive.Hole("children");

  Reactive.With(() => {
    Content(() => {
      Text((text) => {
        const textValue = Ui.Value.text(text);
        const attributes = Collection.Map.Gather(() => {
          Collection.Map.Gather.Entry("text", textValue);
        });
        const component = Ui.Component("Ui.Text", attributes);
        Reactive.Emit("components", component);
      });
    });
    children();
  });

  const components = Reactive.Gather(Collection.Array.Of(Ui.Component), "components");
  return components;
});
A function, a hole, a With, an emit, a gather, and the return.