Chapter 14. The Convergence

This chapter is the evidence. The JavaScript ecosystem was not reading a derivation; it had its own problems: pages that crawlers could not read and first paints that took too long. Driven by those problems, it has spent a decade converging back toward the proper factorization, one rediscovery at a time:

The framing is convergent evolution: independent lineages, under the same pressure, arrive at the same design, and the match is explained by the pressure, not by chance. The lineages had contact with nothing but the costs, and the costs are the derivation’s predictions.

Years mark mainstream adoption, not invention. The figure shows when each piece returned, not how much: S1 and S2 have recovered to partial scores, while R3 and S4 have not been recovered at all.

GraphQL

GraphQL
R1 ✓ — a graph model; encodes any domain
R2 ✗ — schemas compose only by coordination
R3 ✗ — no global identifiers; names stop at the schema boundary
S1 ~ — select genuinely separated, but behind one endpoint
S2 ~ — a specified but prose-defined semantics
S3 ~ — substitution within one schema’s contract
S4 ✗ — one endpoint; results are not addressable

SPA/JS, revised

SPA/JS (Ch 11) SPA/JS (2026)
S1 ✗ ~ — select re-extracted
S2 ✗ ~ — declarative islands in an imperative shell
R3 ✗ ✗
S4 ✗ ✗ — the wire format has no URI

R1, R2, S3: unchanged from Chapter 11’s column.

The convergence recovers S1 and S2, to a tilde, not a check, but neither R3 nor S4, the two properties that make an architecture the web rather than an app platform that happens to use browsers. The reason is that the remaining work benefits everyone except the vendor doing it: vendors recover the properties that benefit them privately and stop there.

A dashed path leaving the front door of a house, wandering past hills, mountains, and a lake, and stopping just short of the door beside it