@wulperstd/renderer-react
v1.0.0
Published
DOM-free React element renderer for the block editor's document JSON, sharing renderer-core's node/mark rules with renderer-html.
Readme
@wulperstd/renderer-react
DOM-free React element renderer for the block editor's document JSON. Shares
@wulperstd/renderer-core's node/mark rules with @wulperstd/renderer-html,
so both renderers agree on tags, attributes, and safety gating from one table
instead of two independently maintained copies.
See openspec/changes/renderer-react/design.md and
openspec/changes/renderer-react/specs/renderer-react-output/spec.md for the
full design rationale.
Public API
import {
renderToReact,
renderToReactWithDiagnostics,
DocumentRenderer,
} from '@wulperstd/renderer-react';
const element = renderToReact(doc, {
nodeMapping: { codeBlock: ({ renderDefault, node }) => renderDefault() },
markMapping: {},
unhandledNode: ({ kind, type }) => null,
onDiagnostic: (record) => console.warn(record),
});Guarantees
- Produces a React element tree, never an HTML string, and never uses
dangerouslySetInnerHTML. - The default (no-override) tree calls no React hook, so it renders
identically under
renderToStaticMarkup, client-side rendering, and React Server Components. - Every safety-relevant attribute (
hrefschemes, color, block-id) is revalidated at render time via@wulperstd/renderer-core's shared predicates, regardless of prior validation. react-domis a devDependency only, used by this package's own tests and by any consumer's own render call — never imported fromsrc.
Bundle size
The renderer is tree-shakeable: @wulperstd/schema, @wulperstd/renderer-core
and this package declare "sideEffects": false, and the renderer only imports
schema predicates and constants. A client bundle that uses renderToReact
therefore does not include prosemirror-model (about 33 kB minified, 9 kB
gzip for the whole renderer chain, excluding React).
validate, validateReport and blockSchema from @wulperstd/schema do need
prosemirror-model. Validate on the server (a route loader, an API handler
or a Server Component) and pass the validated JSON to the client renderer.
test/bundle-size.test.ts fails if prosemirror-model reaches the renderer's
client bundle.
