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
viewcall — 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:
- 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.
- 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
- The Floor — why enhancements never compromise the on-chain guarantee.
- The Render Pipeline — the fail-closed render path, step by step.
- The Trust Grade — how any deviation from fully-on-chain is measured and disclosed.
- Contracts → Architecture — the on-chain contracts, by layer.