@desenlabs/react-renderer
v1.0.0-beta.2
Published
DESEN Protocol React Renderer — DesenProvider, DesenRenderer, ErrorBoundary
Downloads
372
Maintainers
Readme
@desenlabs/react-renderer
The DESEN Protocol React Runtime. Renders DESEN surfaces in React / Next.js, resolves bindings, emits telemetry, enforces fail-closed behavior.
Install
pnpm add @desenlabs/react-renderer react react-domPeer dependencies: React 18+ and React-DOM 18+.
Minimal example
import { DesenProvider, DesenRenderer } from "@desenlabs/react-renderer";
import type { SurfaceSpec } from "@desenlabs/core";
const surface: SurfaceSpec = await fetch("/api/surface/hello").then(r => r.json());
export function Page() {
return (
<DesenProvider
mode="strict"
sessionId="sess_abc123"
onTelemetry={(envelope) => {
// §4.5 envelope — every event passes through here
console.log(envelope);
}}
>
<DesenRenderer surface={surface} />
</DesenProvider>
);
}What this package does (and doesn't)
Does
- Parses and enforces every §2 schema before rendering.
- Resolves bindings via a pluggable
DataSourceRegistry(§2.7, §3.4). - Enforces all four runtime guardrails (§3.4): max depth, document size, binding timeout, repeater items.
- Applies
modifiers.visiblefail-closed (§2.11). - Emits every standard envelope (§4.5) with sanitized payloads (§4.3).
- Tracks conversions (§4.9) and navigations (§4.10) with causal
trigger_sequence_numberlinking. - Enforces the canonical
element_idmapping for telemetry.
Doesn't
- Ship any design system or CSS — styles come from your DESEN tokens (§2.6).
- Make network calls.
DataSourceRegistrylets you wire any fetch layer. - Do governance — for that, run the daemon (
@desenlabs/cli).
SSR
Works with Next.js App Router, React Server Components (as a client boundary), and renderToString / renderToStaticMarkup. Hydration-safe as long as your session id is stable server-to-client.
Extending
Custom data source
import { DataSourceRegistry } from "@desenlabs/react-renderer";
const registry = new DataSourceRegistry();
registry.register("backend", async (path) => {
return fetch(`/api/data/${path}`).then(r => r.json());
});
<DesenProvider dataSourceRegistry={registry} ...>Custom telemetry sink
<DesenProvider onTelemetry={(envelope) => emitToMyCollector(envelope)}>Testing
55 tests cover: fail-closed subtree rendering, binding resolution timeouts, a11y constraint enforcement, navigation flows, conversion attribution, and Repeater scoping.
Links
- Protocol: SPEC.md
- Cookbook recipes: IMPLEMENTATION-COOKBOOK.md
- Schemas:
@desenlabs/core - Umbrella:
desen
