⚠️ Alpha · testnets only. ChainRender is in active alpha and deployed on testnets only — Ethereum Sepolia, the Robinhood Chain Testnet, and the Circle Arc Testnet — not on any mainnet. Contracts, addresses, and APIs may change. Do not use with real funds or production assets.
Concepts

What's Fully On-Chain (Capabilities & Robustness)

ChainRender's central claim is that apps are fully on-chain. This page substantiates that claim: it catalogs exactly what lives on-chain, what capabilities that unlocks, and what engineering makes it robust. If you're evaluating whether "fully on-chain" is real or marketing, this is the page to read.

What is actually on-chain

Everything required to store, render, and verify an app — and to read the live data it displays:

On-chain What it is
App bytes Your compiled component tree, stored via SSTORE2 in the ComponentRegistry.
The renderer RenderRouter + the interpreter — a view function that turns bytes into HTML/SVG.
The vocabulary Every UI primitive (box, text, button, chart, table, controls, layout, scene) is rendered by on-chain code.
Live data Resolvers (view contracts) read chain state at render time — prices, balances, ENS, credentials.
Media Generative art, SDF/point-cloud scenes, NFT images, geo maps, identicons, gradients — all generated on-chain as SVG.
Rendering libraries p5.js, three.js (r160 UMD), and the ~500-icon set are stored on-chain in the DependencyRegistry (gzip-compressed, fetched by name, decompressed natively in the browser). Rich-media apps and icons load their libraries from chain — never from a CDN.
The trust logic The enforcer + trust grade compute on-chain.
Theming Design tokens → CSS generated on-chain (ThemeCssView); themes stored on-chain.
Naming & versions Subname registrar, version registry, theme sets, advisories — all on-chain.

There is no server in the render path, no index.html on a host, no build pipeline, and no CDN — not even for the rendering libraries (p5/three/icons load from chain, as plain scripts, decompressed natively; an embedded copy is only a fail-open fallback). To display an app you make one eth_call. To verify it you recompile and re-render — nothing is hidden off-chain.

What this unlocks (capabilities)

Because it's all on-chain, ChainRender apps get properties a hosted frontend cannot:

  • Permanent. The app exists as long as the chain does. It cannot be taken down, and it doesn't depend on anyone continuing to host it.
  • Un-spoofable. Content addressing binds the exact UI to its hash. No one can serve you a different button under the same identity.
  • Reproducible. Anyone renders the same app against any RPC and gets byte-identical output. Trust becomes verification, not faith.
  • Chain-portable. Deterministic rendering means the same app has the same hash and output on any EVM chain.
  • Free to render. Rendering is a view call — no gas. You pay once to register bytes; render forever for free.
  • Rich. Charts, tables, multi-view navigation, 2D/3D scenes, generative art, animation, live data, themes — the on-chain surface is broad, not a lowest-common-denominator "static token image."

What makes it robust (the built-in engineering)

"Fully on-chain" would be fragile if a single failure could break a render or produce a lie. ChainRender is engineered so that cannot happen. These are the robustness mechanisms, and they're not aspirational — they're built and tested:

  • Fail-closed everywhere. A reverting resolver, a gas-bomb, a missing source, a failed proof, an unavailable GPU — none breaks the render. Each degrades to an honest fallback: "unavailable," an axes-only chart, a poster image. An app can never be made to render a lie by a failing dependency.
  • The floor. Every app has a complete, on-chain rendering that needs nothing but the chain; enhancements (GPU, fetch, motion) layer on top and fail closed to it. See The Floor.
  • Escaped by construction. Every value a resolver returns is re-escaped before entering the output — a resolver can never inject markup. Safety is structural, not a check you might forget.
  • Drift-locked. The SDK's off-chain logic (grade, format constants, theme generation) is asserted byte-identical to the on-chain logic by tests. What you compute locally is exactly what the chain computes — no divergence.
  • Paginated reads. Large outputs (a world atlas, a long table) support chunked reads that concatenate byte-identically to the whole, so even big apps stay within call limits without truncation.
  • Gas-bounded resolution. Data slots resolve under a gas stipend; a resolver that tries to run away is cut off and the slot fails closed — one expensive read can't break the page.
  • Legibility & accessibility invariants. A font-size floor (never below 12px) and a WCAG contrast invariant are enforced as build-failing checks — an illegible or inaccessible theme cannot ship.
  • Content-addressed storage. SSTORE2 stores bytes immutably and cheaply; the same bytes always yield the same hash, so storage itself is verifiable.
  • Ownerless & immutable contracts. No admin, no upgrade key anywhere in the render path — nothing can change what your app displays after you verify it.

The honest boundary

Two things are worth stating plainly, because ChainRender's discipline is to never overclaim:

  1. The read path is your choice. The rendered output is fully on-chain and reproducible, but which RPC you read through is a client decision — an RPC sees which app and address you queried (a metadata concern, not an integrity one). You can use a private or light-client RPC to address this.
  2. Declared off-chain enhancements exist and are disclosed. An app may declare a CLIENT_FETCH (off-chain data) — but doing so drops its grade and is itemized in the breakdown. The floor beneath it stays on-chain; the enhancement is never hidden.

Neither of these weakens the core claim — they sharpen it. "Fully on-chain" means the app's identity, rendering, and integrity are on-chain and verifiable; where something optional reaches off-chain, the grade says so.

Related