← RESOLVE
Client-Server mandatory
Statelessness mandatory
Cacheability mandatory
Uniform Interface mandatory
Layered System mandatory
Code-on-Demand optional
.htx — source representationbilateral
<htx:layout src="layouts/main.htx" /> <htx:include src="partials/header.htx" /> <htx:data type="post" order="published_at desc" limit="3" as="posts" /> <main class="posts"> <htx:each items="posts" as="post"> <article> <h2><htx:v>post.title</htx:v></h2> <p><htx:v>post.author | uppercase</htx:v></p> <a hx-get="/post/{htx:post.slug}" hx-target="main">Read</a> </article> </htx:each> </main> <htx:auth> <htx:action name="create" type="post" /> <form hx-post="/posts?t={htx:$actions.create}"> <input name="title" /> <button>Post</button> </form> </htx:auth> <htx:script> el.addEventListener('click', e => e.target.closest('article')?.classList.toggle('open')); </htx:script>
.html — resolved representationunilateral
<!-- layout wrapper + resolved header omitted for clarity --> <main class="posts"> <article> <h2>My First Post</h2> <p>JARED</p> <a hx-get="/post/my-first-post" hx-target="main">Read</a> </article> <!-- two more article blocks expanded from htx:each --> </main> <form hx-post="/posts?t=eyJhY3Rpb24i...sig"> <input name="title" /> <button>Post</button> </form> <script> el.addEventListener('click', e => e.target.closest('article')?.classList.toggle('open')); </script>
0Static hypermedia — plain HTMLno JS
1Declarative attributes (hx-*)tiny runtime
2Scoped behavioral units (on-click, on-change)per-scope scripts
3Server-pushed codeWebSocket
4Authenticated data channelschannel tokens
5Binary delivery (images, audio, blobs)binary frames
6WebAssembly — native-speed client computewasm manifest
<!-- plain hypermedia; htmx not loaded -->
<a href="/post/my-first-post">Read</a>

<form method="post" action="/posts">
  <input name="title">
  <button>Post</button>
</form>
<!-- request + target + swap, declaratively -->
<button hx-get="/posts/new"
        hx-target="#content"
        hx-swap="innerHTML">
  New Post
</button>
<!-- hx-on::* scopes a handler to its element -->
<form hx-post="/posts"
      hx-on::after-request="this.reset()"
      hx-target="#list">
  <input name="title">
  <button>Post</button>
</form>
<!-- ws extension + out-of-band swaps -->
<div hx-ext="ws" ws-connect="/events">
  <!-- server pushes fragments like: -->
  <!-- <div id="alert" hx-swap-oob="true">…</div> -->
</div>
<!-- channel token materialized into the representation -->
<div hx-ext="ws"
     ws-connect="/channel/trading?t={htx:$grants.channel}">
  <!-- token expires; channel closes; no ambient authority -->
</div>
<!-- binary gated by signed URL; grant materialized server-side -->
<img src="/asset/{htx:$grants.asset}/chart.png"
     alt="role-scoped, expires-in-session">
<!-- htmx triggers load; the wasm runtime takes over -->
<div id="chart"></div>
<script hx-trigger="load" type="module">
  const { instance } = await WebAssembly.instantiateStreaming(
    fetch('/wasm/chart.wasm?t={htx:$grants.wasm}')
  );
  instance.exports.render(document.getElementById('chart'));
</script>

Independent implementations of the specification

TypeScript Go Elixir Python Rust C
One specification · htxlang

jaredfoy.com / presto

PRESTO

Progressive Representational State Transfer with On-Demand Code

In 2000, Roy Fielding named five mandatory constraints and one optional constraint for the architectural style of the Web. The mandatory five produced the Web we have. The optional sixth — code-on-demand — was adopted without being mapped. PRESTO is the architectural style that maps it, as a progressive spectrum rather than a binary.

01 · The unexplored constraint

The sixth

REST's five mandatory constraints produced the Web: scalability, independent deployment, simplicity, modifiability. Code-on-demand was the optional sixth. The amber tile pulses because it's the one whose design space the field left unexplored.

Adoption was binary in practice: either the client runs no code (the old static web) or it runs all the code (the modern SPA, which violates the other five constraints to do so). Between them, a progressive spectrum was never mapped.

The claim of this work: PRESTO is that map.

Doc 193 → The PRESTO White Paper
02 · The bilateral boundary

One string, two interpreters

The central visual is an .htx template — a source representation. Look at the colors. Purple directives (htx:include, htx:data, htx:each, <htx:v>, htx:auth, htx:action, htx:script) are consumed by the server. Amber attributes (hx-get, hx-post, hx-target) are addressed to the browser.

The server ignores the amber. The browser never sees the purple. Same document, two interpreters, mutual indifference — a structural property that's been operative in every server-rendered HTTP response since 1993.

This is the boundary REST didn't name. This is what PRESTO formalizes.

03 · The pipeline consumes

The server's half resolves

A resolution pipeline transforms the source. Includes fold in. Data queries materialize. Expressions evaluate — <htx:v>post.title</htx:v> becomes an actual title, tinted green. Each-loops iterate. Auth conditionals resolve. Action tokens get minted.

Every purple directive is consumed. None of them reach the browser. The pipeline isn't a framework feature the developer has to orchestrate; it's the ordered sequence of resolutions the style specifies.

The pipeline is the mechanism by which the bilateral form becomes a unilateral form.

04 · The unilateral representation

What the browser receives

Terminal state. Pure HTML. The server's affordances have been consumed. Only the client's remain — as discoverable structure in the document. This is HATEOAS in its strongest form: the complete representation carries every affordance the client needs, and nothing it doesn't.

No build step. No bundler. No hydration. No "API contract" separate from the response. The document is the contract. The script that runs on click can reach any element, because the document is the shared state.

REST-conformant, because the resolved representation is what travels. REST-extending, because what gets constructed inside the server is now formalized too.

05 · Layer 0

Static hypermedia

The foundation. Plain HTML. No JavaScript runtime, no build step, no bundler. Every browser since 1993 renders it, and every architecture above is additive — Layer 0 is never abandoned.

A complete HTML document is already a working application: readable, navigable, form-submittable. If the server returns a useful representation, the application works.

This is the claim that distinguishes PRESTO from frameworks that treat JavaScript as foundational. The foundation is the document.

06 · Layer 1

Declarative attributes

hx-get, hx-post, hx-target, hx-swap. A small runtime (about 5 KB) watches for these attributes, fires the request the attribute declares, and swaps the returned HTML fragment into the target.

The server stays authoritative: it produces HTML fragments, not JSON. The client doesn't know about endpoints — it follows hypermedia.

Carson Gross demonstrated this portion of the space in htmx and Hypermedia Systems. PRESTO names it as the first rung above plain HTML and specifies its constraint cost.

07 · Layer 2

Scoped behavioral units

When an interaction needs logic that doesn't fit declarative attributes — keyboard handling, validation, local rearrangement — a short script bound to its component's scope does the work.

This is not a framework mounted at the page root. Each script is scoped to the element that owns it. el refers to that element. When the element is removed, the script has nothing to attach to, and the browser reclaims it.

Component-level behavior without a client-side runtime.

08 · Layer 3

Server-pushed code

A WebSocket opens after the initial response. The server can push new behaviors mid-session: a trading-dashboard module arrives when the user signs in; a richer editor arrives when the user opens a specific document.

The code is authorized by the server, not selected at build time by the client. Different users receive different capabilities based on context the server knows.

The REST representation is still the root: it embedded the WebSocket token that authorized the channel the code arrived on.

09 · Layer 4

Authenticated data channels

Server-issued JWT channel tokens (120-second default TTL) let the client open specific, typed data channels. The channel is scoped to a module name. The token expires quickly so an exfiltrated one is quickly useless.

The client doesn't hardcode channel URLs. It reads them from the representation, presents the token, opens the channel. Every capability traces back to an authorization in the initial HTTP response.

No extension exists that the representation did not mediate.

10 · Layer 5

Binary delivery

Images, audio, PDFs, arbitrary blobs — delivered as binary frames through an authenticated channel. No separate CDN auth flow. No signed-URL round-trip. The channel authorizes the delivery in the same act that granted the capability.

Useful for streaming large assets that need to be revocable, resized per-client, or gated by runtime context (role, subscription tier, geolocation) that a static URL cannot express.

11 · Layer 6

WebAssembly

Native-speed client compute. The server delivers a .wasm binary through the channel with a JSON manifest declaring its exported APIs. The module runs in the browser at near-native speed.

The sandbox is real: no filesystem, no network, no DOM unless explicitly granted, capability-scoped at the language level. The server decides, at resolution time, what this client should be able to do locally.

The end of the progressive spectrum. Nothing in this stack required the others to be abandoned.

12 · Cross-language convergence

Six implementations, one specification

The seven layers above are the architectural claim. This is the empirical one. The specification (htxlang) is language-agnostic. Conformant engines have been independently implemented in TypeScript, Go, Elixir, Python, Rust, and C — each passing the same verification suite, each reasoning from the same constraints.

The convergence is the mechanism by which the specification discovers its own completeness. Each implementation, reasoning from the same constraints in a different paradigm, reveals consequences the previous missed. The specification is then refined, and the next implementation receives a tighter set of rules.

The smallest conformant engine fits in 3,122 lines of code, runs in 11 MB of memory, and requires zero build infrastructure. The full progressive spectrum operates within the resource budget of a single-board computer.

Doc 193 → The full dissertation