BACKSTORY

The Backstory — How One Library Started It All

Change tracking is hard. Oxford felt that viscerally while working in a large codebase for a travel startup. The conventional publish/subscribe model (obj.subscribe()) had become prohibitively clunky to scale across the application. After several wipe-and-restart cycles, the practical answer became clear: a universal change-tracking primitive that worked with arbitrary objects, rather than a separate mechanism built into every object that needed to report changes.

Oxford wrote a simple API of that shape. The early work was called Reflex, and it became the standard across the team. The API would later evolve into the Observer API, with its central operation:

JavaScript
Observer.observe(obj, callback);

The difference was structural. With the conventional approach, every object that needed to report changes required its own mechanism. With a universal observer, the tracking mechanism could be applied to an object without making observability part of that object's design. One approach made change tracking a responsibility of individual objects; the other made it a capability available across the system.

The travel startup did not survive the COVID-19 period. But the problem it helped surface remained, and so did the insight that had emerged from trying to solve it.

From Reflex to the Observer API

The first public work around Reflex appeared in 2020. A Reflex-based implementation of the Web Monetization API, published that June, showed how changing browser state could be exposed through observable JavaScript objects.

The browser API communicated through events. An application tracking monetization state had to handle events such as monetizationpending, monetizationstart, and monetizationstop, then translate them into the representation its own code needed. The Reflex approach allowed that changing information to be exposed as object state that could be observed through a common mechanism.

Instead of every API consumer needing to know which events to register for and how to translate them, the application could work with the state itself. The integration still had to process the browser's events, but the application-facing interface no longer required consumers to reconstruct that machinery.

In 2021, WebQit, Inc. was founded as an open-source developer-tools startup. The wider ambition was to make the web platform a stronger foundation for application development, reducing the amount of framework-specific machinery developers had to build around native browser capabilities.

As the work developed, Reflex's central idea was separated into a more general API: Observer. A 2023 article introducing the Observer API and Reflex Functions explored object observability as a standalone problem, drawing on the idea behind the retired Object.observe() API while pursuing a broader interface for mutable JavaScript objects.

Observer let a library expose a mutable object without requiring consumers to use a bespoke subscription mechanism. The same observer could be applied across objects representing database results, application state, collections, URL components, or the interface.

The original solution had become a reusable primitive. But observing a mutation did not, by itself, maintain the computations that depended on the mutated state. Application code still had to arrange how those computations would respond.

From Observing Objects to Reactive Computation

Observing a change and keeping a computation up to date are two different jobs.

Reflex Functions addressed the second. The aim was to let developers express reactive computations in ordinary JavaScript without requiring them to assemble the usual collection of subscriptions, callbacks, and update logic around every piece of code.

In January 2024, Reflex Functions was renamed Quantum JS and underwent a major API and compiler overhaul. The implementation moved toward a more runtime-driven approach to reactivity. The concern had moved below the library level: JavaScript's execution model itself was now part of the work.

The March 2025 introduction to Quantum JS described the goal as imperative reactive programming. The intent was to preserve familiar JavaScript syntax while allowing a program's computations to reflect changes in the state they depend on.

Quantum JS expressed the opt-in through a quantum declaration. Its browser integration could use a script like this:

HTML
<script quantum>
    let count = 5;
    let doubleCount = count * 2;

    console.log(doubleCount);

    setInterval(() => {
        count = 10;
    }, 1000);
</script>

In the reactive execution model, changing count can cause the dependent computation to run again, updating doubleCount and producing the corresponding output. The developer writes ordinary imperative logic; the compiler and runtime provide the machinery needed to track dependencies and respond to changes in program state.

The later iteration of this work became UseLive, which developed the compiler, runtime, and programming model further. UseLive uses the "use live" directive to mark live JavaScript computations or whole programs:

HTML
<script>
    "use live";

    let count = 5;
    let doubleCount = count * 2;

    console.log(doubleCount);

    setInterval(() => {
        count++;
    }, 1000);
</script>

The directive opts the program into an execution model in which the runtime tracks dependencies and responds to changes in program state. UseLive also supports marking individual functions as live:

JavaScript
let count = 5;

function logDoubleCount() {
    "use live";

    console.log(count * 2);
}

logDoubleCount();

Both forms allow familiar imperative JavaScript to participate in a live execution model. The runtime handles the relationships between the state being read and the computations that depend on it, rather than requiring application code to reconstruct those relationships through separate reactive primitives.

The work had moved from making changes observable to making computations respond to them. It also explored a deeper shift in responsibility: the language and runtime already govern program state, dependencies, and control flow, making them a natural place to handle the work of following changes through a program.

Bringing HTML into the Same Model

The work was also developing in the HTML and DOM layers. OOHTML explored reusable HTML structures, scoping, and reactive behavior, addressing recurring problems around element lookup, data binding, and keeping the document aligned with application state.

OOHTML was already being developed before its article appeared. The January 2024 article introducing OOHTML described the project's approach to the HTML problem space; it did not mark the beginning of the project.

Even when JavaScript state was observable and computations could respond to changes, the connection between that state and the DOM still had to be expressed and maintained. OOHTML brought the work into the markup layer, exploring how HTML could participate more directly in application logic.

This was a different responsibility from the runtime work. UseLive addressed the relationship between program state and dependent computations; OOHTML addressed the structure of the document and its connection to those computations.

The work had reached three closely related parts of application development: observing mutations, executing computations that respond to changing state, and connecting those computations to the document.

When the Database Joined the Story

A separate line of work began with Objective SQL, an earlier database effort that grew into LinkedQL.

A conventional SQL query returns a result for the database state against which it runs. If the underlying data changes afterward, the existing result does not automatically reflect those changes. An application that needs current results must arrange how to detect relevant database changes, determine their effects on its queries, and propagate the updated results to the code consuming them.

Applications commonly approach this through polling, subscriptions, cache invalidation, or repeated queries. The query itself and the machinery for maintaining its result over time are treated as separate concerns.

LinkedQL developed a live-query model in which an application can request a result that continues to reflect relevant database changes:

JavaScript
const result = await db.query(sql, { live: true });

Observer.observe(result.rows, () => {
    render(result.rows);
});

The live: true option asks the database layer to maintain the query result as the underlying data changes. Observer then provides a way to respond to changes in the result object. The application can work with a result that remains current rather than constructing a separate update pipeline around a one-time query.

Making this possible required a substantial engine. The system must understand the query, determine how changes to the underlying data affect its result, and maintain that result as those changes arrive. It must also account for database transactions and the different mechanisms through which databases expose changes.

The LinkedQL Realtime Engine processes changes from sources such as write-ahead logs, binary logs, and in-memory emitters, translating storage-level mutations into logical updates to live query results. Its query-inheritance model allows related queries to share computation rather than independently maintaining overlapping results.

The LinkedQL Realtime Engine engineering paper, published in November 2025, documents this architecture. A May 2026 design review of live SQL queries on PostgreSQL describes the application-facing interface, including db.query(sql, { live: true }).

The database engine had to do more than detect that something had changed. It needed to calculate the consequences of that change for a query and maintain the correct result. Observer could expose the resulting mutations through a common interface, while the specialized database machinery handled the semantics of relational data.

LinkedQL eventually grew beyond its original place within WebQit and was considered as the basis for a separate startup. It had become a distinct compiler and database project.

FlashQL extends the database work into a local, embedded setting. It is being developed around the LinkedQL contract, with transaction-first MVCC, query planning, federation, online/offline synchronization, and pluggable persistence. The aim is to bring querying and live results into a consistent model across local and remote data.

Webflo and the Projects That Grew Out of It

Webflo brought the work into a full-stack application framework.

Developed as a Web-Native framework, Webflo aimed to build applications on the web platform's own capabilities, bringing together capabilities from the browser and the wider application stack. Its direction reflected WebQit's wider ambition: less framework-specific machinery around capabilities the web platform already provides.

As Webflo evolved to become Observer-native, the framework could use the same observability mechanism across more of the application rather than relying on separate change-tracking conventions in each layer.

That created concrete engineering requirements. The framework needed live behavior at the network interface, in messages passed between execution contexts, in DOM queries, and in other parts of an application that work with changing state. URL state and storage also needed reusable interfaces that could fit the wider model.

Each requirement first arose within the framework. As the solutions developed, however, the capabilities proved useful beyond Webflo. They were separated into independent projects so applications could use them without adopting the framework itself.

FetchPlus: Live HTTP Responses

An ordinary HTTP request returns a response to a request. When an application needs to keep working with server-side state as it changes, the conventional approach is to pair the initial request/response exchange with a separate update channel, often using WebSockets. Application code must coordinate the initial response with subsequent updates.

Webflo needed to abstract those responsibilities so individual routes and application features would not have to assemble their own mechanisms for maintaining that relationship. This work led to a breakout project: FetchPlus.

FetchPlus extends the Fetch API with additional request and response capabilities, including live responses. Its fetch() interface lets an application request a live response:

JavaScript
const response = await fetch(url, { live: true });

FetchPlus's LiveResponse model allows the response to remain connected to changing application data rather than ending with a one-time delivery. It also supports response replacement and messaging through a port.

The underlying network and protocol machinery still has to handle communication and updates. What changes is the application-facing interface: the framework can work with a live response instead of requiring each feature to reconstruct the relationship between the initial response and subsequent changes.

FetchPlus began as part of the work required to make Webflo's architecture fit together. Once developed as an independent project, the capability could serve applications beyond the framework.

PortPlus: Live State Across Message Ports

Webflo also needed to carry changing state between execution contexts. Ordinary message passing transfers a message, but does not by itself maintain a continuing relationship through which later mutations to the source object appear at the receiving side.

Applications that need that relationship otherwise have to arrange how changes are detected, transmitted, and applied. Webflo needed a way to abstract that work rather than requiring each feature to implement its own propagation mechanism. That work led to another breakout project: PortPlus.

PortPlus developed live-object projection as an extension to web messaging primitives. The same postMessage() interface can send a payload in live mode:

JavaScript
port.postMessage({ state }, { live: true });

The receiver obtains a live counterpart whose state continues to reflect mutations to the sender's object. The two execution contexts do not literally share one JavaScript object identity. PortPlus maintains reference-like continuity through a protocol that observes source mutations, sends differential updates through a private channel, and applies them to the receiving copy.

The continuing relationship becomes part of the messaging interface instead of a synchronization protocol that every application must construct independently.

RealDOM: Live DOM Queries

The DOM presented another form of the same engineering need. A call to the native document.querySelectorAll(css) returns a static collection of matching elements. If the document changes afterward, that collection does not become a continually maintained query result.

Webflo needed to work with DOM queries whose results could change as the document changed. That work became the RealDOM project.

RealDOM developed low-level DOM mutation-observation and realtime-query capabilities for this purpose. document.querySelectorAll(css, { live: true }) was built on this.

For example:

JavaScript
realdom.realtime(document.body).query(
    "li",
    handleItems,
    { subtree: true }
);

The realtime query reports changes to matching elements within the selected scope. The framework can respond to those changes through the query interface rather than having each part of the application repeatedly run a selector and reconcile the results.

URLPlus and Keyval: URL State and Storage

The same framework work extended to URL state and key-value storage.

URLPlus addressed URL state through a reusable interface. Keyval provided a reusable key-value storage interface.

These projects grew out of the effort to make Webflo's underlying capabilities reusable and coherent. They were developed as independent libraries so their APIs could serve applications beyond Webflo as well.

The resulting projects addressed different boundaries of the web platform: HTTP, messaging, DOM structure, URLs, and storage. Each required implementation suited to its own domain, but each could provide a reusable capability that fit into the wider application model.

One Model, Across the Application

The projects could now be composed. The observable output of one computation could become state for another, even when the two used different underlying implementation mechanisms.

A live database query and a live location can be established independently. The query maintains its rows as relevant database state changes. The location maintains its coordinates as the device moves beyond a specified distance threshold:

JavaScript
const result = await db.query(sql, { live: true });

const loc = getLiveLocation(50);

A live program can consume both outputs, producing a list in the DOM and rendering the location:

HTML
<script>
    "use live";

    ul.replaceChildren();

    for (const row of result.rows) {
        const li = document.createElement("li");
        li.textContent = row.content;
        ul.append(li);
    }

    render(loc);
</script>

The program's state includes the outputs of result and loc. Its output is the resulting list and rendered location. A change in either upstream value changes the state against which the program is defined, causing its output to reconverge.

The resulting DOM can itself be observed through a realtime query:

JavaScript
realdom.realtime(ul).query(
    "li",
    handleItems,
    { subtree: true }
);

The database engine maintains its query result; the location interface maintains its state; the runtime tracks the live program's dependencies; and RealDOM reports changes to the resulting document. Each component retains its own semantics and implementation.

The outputs nevertheless compose. A live query can feed a live program, whose output feeds a live DOM query: the result of one computation becomes observable state for the next. The systems need not share an implementation mechanism; their outputs need only be available as observable entities that the next computation can use as state.

The work had reached beyond a collection of libraries sharing an interface. Independently developed capabilities could participate in a larger computation while retaining the implementation appropriate to each domain—and the developer no longer had to reconstruct the full chain of change detection, dependency tracking, and synchronization at every boundary.

From a Developer-Tools Startup to Convergent Machines Lab

The experience accumulated through the WebQit stack changed the scope of the work.

Reflex began as a practical solution to change tracking in a large application. Observer made object observability reusable. Reflex Functions, Quantum JS, and UseLive brought the concern into program execution. OOHTML brought it into the markup layer. Objective SQL grew into LinkedQL, with live-query maintenance and a database engine of its own, while FlashQL extended the database work into local and embedded settings. Webflo brought the approach across an application stack, and FetchPlus, PortPlus, RealDOM, URLPlus, and Keyval made its capabilities available beyond the framework.

At each stage, the immediate engineering problem led to another implementation of the same underlying concern. The full pattern was not apparent in the original library; it became clearer as the work extended across the stack. What emerged was more than a collection of solutions to individual engineering problems. Taken together, the projects enabled a materially different programming model for application development, one made possible by moving more responsibility for state into the substrate beneath the application.

The significance of that result is in the lens that it provides into computing itself: computing as we know it today has taken its present shape partly as a consequence of how we have understood state and handled it through local solutions at different layers. If a central treatment of state materially changes the programming model available to the application layer, then carrying that treatment through the underlying computing substrate substantially changes the shape of computing itself.

The WebQit stack provided the engineering evidence for this broader thesis. Its implementations were shaped by JavaScript and the web platform, but the fundamental shift—state as a central problem, rather than a local problem—isn't local to the implementation environment. The shift generalizes across programming languages, runtimes, and systems. The thesis of a different shape of computing describes the same outcome at a larger scope: computing itself.

Exploring this thesis is the new mission, and it is structurally different from the startup that helped make it concrete: WebQit.

Convergent Machines Lab (September 2026) has been founded to take it up from here. The lab's program is to formalize the principles beneath this engineering work and develop models around state, observability, and convergence. Research investigates which parts of the approach can be generalized across computing, how they relate to existing computational foundations, and what they imply for the design of languages, runtimes, databases, protocols, and other computing systems.

The lab seeks to provide a new theoretical foundation that language and API authors, runtime engineers, database developers, and other systems builders can adopt in their own implementations. Those implementations will differ across languages and domains, but the models should help them address the underlying concerns in ways that compose more naturally.

Engineering informs the research; research informs the engineering.

A Better Future for Computing. Thanks to Reflex

The question for the new lab isn't whether this is worth doing, or how far we can go. It is how fast we can go.

The implications reach beyond conventional developer tooling. AI systems increasingly write, integrate, and operate software, but the systems they build still need to detect changes, keep derived results current, and maintain dependencies and relationships across components and environments. Today, much of that responsibility falls to the software and engineers assembling the pieces. A substrate that takes on more responsibility for change and convergence could reduce the coordination logic human engineers must build and maintain, while giving AI systems a simpler foundation on which to build reliable software.

Convergent Machines Lab is the next chapter of this work. But the discovery that made it possible began years earlier, with a local library built to solve a practical problem.