Architecture

RTCode.io and RTEdge.net are two parts of one system. RTCode.io is the playground: an editor and a live output that run in your browser. RTEdge.net is Elefunc's deployment network: it serves what you deploy from the playground and runs your edge workers on Cloudflare's network. The same source, and the same worker code, runs in both places. This article explains the parts, how an edit and a request travel through them, and where each part runs.

Overview

A playground has two sides. While you edit, your page and your worker run in your own browser. When you deploy, the platform compiles the same playground state for each route, and RTEdge.net serves the result.

Editorrtcode.io/x/editschangesOutputout.rtcode.iorequestsOutput service workerfiles and workersplayground stateDeployCtrl/⌘+Seach routeRoutername.rt.ht or your domaindispatchEdge workerone script per route
PartWhere it runsWhat it does
Editorhttps://rtcode.io/x/, in your browserHolds the input, the commands and the playground URL. It is a static app, not an RTEdge.net deployment.
Outputout.rtcode.io or out.rtcode.net, in an iframe, a tab or a popupRenders the live page from your input.
Output service workerThe output's origin, in your browserServes the output document, your exported files and your worker, and runs <script type=worker> code.
Consoleco.rtcode.io, in an iframeShows the Console and Network panels.
Deploy pipelineThe RTEdge.net platformCompiles the playground for each route, stores it, records a version and takes a screenshot.
RouterCloudflare's networkOne shared worker that serves every route.
Edge workerCloudflare Workers for PlatformsOne isolated script for each route that has <script type=worker edge>.

The editor and the output

The editor is a static web app at https://rtcode.io/x/. It holds the input, the HTML you write, and keeps most of the playground's state in the playground URL, so a link reopens the same session. See Playground in the glossary.

The live output is a separate document. The editor renders it in an iframe on its own origin, out.rtcode.io or out.rtcode.net, so your page's code and the editor never share an origin. Edits flow from the input to the output without reloading it, and changes made in the output flow back into the input. The IOSync model explains how.

Which output origin the playground uses depends on how you view it:

How the output is shownOrigin
The playground is the top-level page, in a browser that keys agent clusters by originhttps://out.rtcode.io
The playground is embedded in another page, or the browser does not key agent clusters by originhttps://out.rtcode.net
The output is opened in a tab or a popup windowhttps://out.rtcode.net

The two output origins are different origins, so their service workers and stored data are separate. The Console and Network panels run in a third origin, co.rtcode.io, in an iframe of their own.

The output service worker

Each output origin has one service worker, registered by the output page. It serves every open playground on that origin and keeps their files and worker code apart by session. It is the playground's worker runtime: the <script type=worker> code you write runs inside it. The editor sends the exported files, the worker code and the worker:fs assets to the service worker on every full output load.

A request that the output makes is answered in this order:

  1. The ::su suffix, which returns the signed-in account's email or null.
  2. Your exported files, matched by path when the last path segment contains a ..
  3. The exported files of sibling routes.
  4. Your worker, when you have one. GET / itself never reaches it.
  5. The network.

GET / always returns the input document, even when a worker exists, so a worker never sees it. Ask for : to reach the worker at /.

Worker code learns where it runs from request.rt. In the playground, the service worker finds the device's public address and location by asking ip.rt.ht. It asks once, keeps the first answer for its lifetime, and uses it for request.rt.ip and for an emulated request.cf.

Playground KV storage lives in the output origin's IndexedDB. It persists across reloads, it never syncs with RTEdge.net KV, and it is separate for out.rtcode.io and out.rtcode.net.

From deploy to a stored route

Edge: Deploy (Ctrl+S / ⌘+S) sends the whole playground state, the playground URL with its hash, to RTEdge.net. The platform compiles that one state for each route in Code.D, after a sizing pass for the quota check. A compile produces the root document, the exported files, the edge worker, the access rules and the worker assets. For every route the platform then stores the build, uploads the route's edge worker, records a version and queues a screenshot.

Part of a deploymentServed or kept as
Root documentServed at route/.
Exported filesServed at route/<name>.
Edge workerAnswers route/:… and the requests that no file or page answers.
Route metadataThe owner, the editors, the deploy time and digest, and the last saver.
VersionA commit in the route's history. route/?? opens the version viewer.
ScreenshotA 1200×630 image, the default og:image.

The edge worker is uploaded as its own Cloudflare Workers for Platforms script. Deploying a playground that has no edge worker deletes the route's existing one. Versions are commits in GitFar, Elefunc's GitHub-compatible service over git repositories. Anatomy of a deployment follows one deployment through each step.

The router and the edge workers

On RTEdge.net one shared router serves every route: every name.rt.ht address and every custom domain. The router is a single ordinary Cloudflare Worker. For each request it works out the route, reads that route's deployment, and either answers with the root document or an exported file, or dispatches the request to the route's edge worker. Every route's worker is its own isolated script, so a deploy adds or replaces one script and never needs the router to be redeployed.

Platform handlers run before your deployment is read: redirects that normalize URLs, protection, and the suffix handlers such as ::si and ::qr. The router takes the route from the host and from the part of the path before the first :, and it reads exactly that route. Parent routes are never searched. Request routing gives the full order.

Custom domains reach the same router: the domain points to RTEdge.net with a CNAME record. See Domains and subdomains.

The network

RTEdge.net runs on Cloudflare's network. Elefunc's figures for it are 337 cities, 125+ countries and 500 Tbps of capacity, with under 50 ms of latency for 95% of Internet users.

The router, the storage that holds each build and every route's edge worker are Cloudflare products on that network, so a request to a deployment is answered in the data center that serves the visitor. Sessions are signed with ECDSA P-384 and checked at the edge, with no database round trip, and account data is consulted only when you deploy, delete or claim a domain.

You can measure the latency from your own browser with lt.rt.ht, and see the network on the map at rtedge.net. Connections use hybrid post-quantum key agreement, described in Post-quantum cryptography.

One worker, two runtimes

A <script type=worker edge> element runs in two places. In the playground it is the fetch handler of the output's service worker, inside your own browser. Deployed to RTEdge.net, the same code runs on Cloudflare Workers for Platforms. The handler gets the same (request, env, ctx) arguments in both, and only request.rt says where it runs.

FieldPlaygroundRTEdge.net
Runs inThe output's service workerCloudflare Workers for Platforms
request.rt.codetrueNot present
request.rt.edgeNot presenttrue
request.rt.server'RTCode.io''RTEdge.net'
request.rt.vendor'Elefunc, Inc.''Elefunc, Inc.'

Request.rt lists every field. Playground and edge differences lists where the two runtimes behave differently.

A worker that reports where it runs

The iframe asks the worker for :, and the worker answers with what it can tell about itself. In the playground, server is RTCode.io, and colo and country come from the emulated request.cf. Deployed, server is RTEdge.net, colo and country come from request.rt, and shell is the date of the shell compiled into your worker.

html
<iframe src=:></iframe>
<script type=worker edge>
  export default {
    fetch: r => Response.json({
      runtime: r.rt.edge ? 'RTEdge.net' : 'RTCode.io playground',
      server:  r.rt.server,
      colo:    r.rt.colo ?? r.cf?.colo ?? null,
      country: r.rt.country ?? r.cf?.country ?? null,
      shell:   r.rt.worker?.version?.shell
    })
  }
</script>

Isolation and origins

Origins keep the parts apart. The editor and your code never share one.

PartOrigin
The editorrtcode.io
Your output and playground workerout.rtcode.io or out.rtcode.net
The Console and Network panelsco.rtcode.io
A deploymentname.rt.ht, or your own domain

rt.ht is in the private section of the Public Suffix List, so browsers treat every name.rt.ht as its own site. A deployment cannot set cookies for .rt.ht, so other deployments never see its cookies, and two rt.ht subdomains are cross-site for SameSite cookies, storage partitioning and site isolation. Sign-in sessions are per host.

Path routes on one host are separate deployments, each with its own files, worker and versions, but they share the host's origin: its cookies, its storage, its service worker scopes and its sign-in session. Security and access model and Domains and subdomains cover what this means for your sites.

Sites built on RTEdge.net

Elefunc's own sites are RTCode.io playgrounds served by RTEdge.net, for example elefunc.com, rtedge.net, webpdf.pro, zoo.do and gitfar.com. So are several of the helper hosts, such as logo.rt.ht, qi.rt.ht and lt.rt.ht. Their pages carry a deploy response header that names the deploy time. The editor app itself, rtcode.io/x/, is a static app and not an RTEdge.net deployment.

Guarantees and limits

Request routing

The order in which the playground output and RTEdge.net answer a request.

Anatomy of a deployment

What one deploy produces, and how each part is served.

The IOSync model

How edits flow between the input and the output.

Security and access model

Sites, sessions, owners, editors and permits.

Playground and edge differences

Everything that behaves differently in the playground and on RTEdge.net.

See also