React integration
React components, streaming, SSR and custom nodes sharing the Vue parser core.
@quirekit/incremark-react provides React 19 QuireMarkdown directly over
@quirekit/incremark-core. Parsing, late references, footnotes, HTML sanitization and
cache rules are shared with Vue. The React package renders its own semantic DOM and
does not require Vue, QuireKit UI or UnoCSS.
Workspace integration
The packages are not on npm yet. In a React application inside the QuireKit workspace:
pnpm add '@quirekit/incremark-react@workspace:*' react@^19.3.0 react-dom@^19.3.0
import { QuireMarkdown } from '@quirekit/incremark-react'
import '@quirekit/incremark-react/styles.css'
export function Answer({ received, messageId, receiving }: {
received: string
messageId: string
receiving: boolean
}) {
return <QuireMarkdown
content={received}
identity={messageId}
status={receiving ? 'receiving' : 'complete'}
html={{ styles: 'safe' }}
onError={failure => console.error(failure)}
/>
}
content is always the complete received source prefix. The host owns network chunks,
cancellation and stopping; the component owns incremental parsing and presentation.
Stopping retains the current string. status does not repair markers or freeze earlier
paragraphs. Change identity for another message and replace options to reconfigure
the parser. Advanced hosts may supply a mutually exclusive state snapshot.
Runnable React example
This example mounts a real React root. The application is react/app.ts; the Vue file
only bridges it into this documentation site. Stream again to observe incomplete HTML,
custom markers, late links and footnotes. Disable block reuse for a rendering comparison.
Components and extensions
components replaces semantic tags with React components or native tags. Custom
components receive node, validated properties and children. Consume node before
forwarding props to a native element; native tags receive no source metadata. Code block
components additionally receive code and language instead of reconstructing source
from children.
Native Lezer options.syntax and MSFE options.extensions are shared with Vue. Import
withMarkdownReading from the React package to attach ReactNode presentation to the
existing source codec. renderInline / renderBlocks keep source-bound validation.
cacheKey(document) covers external custom dependencies; an omitted key conservatively
reprojects. Do not freeze late definitions to improve cache hit rates.
load(context, signal) starts only after client commit. Input replacement, identity
changes and unmount abort it; late resources are also released. A failing render
callback preserves source, and node boundaries isolate client descendant failures.
React server rendering does not catch arbitrary descendant exceptions; the host must
handle root SSR failures according to React's error boundary contract.
SSR, hook and cache
Default ssr="semantic" completes the same semantic parse on the server and first
hydration. ssr="source" initially escapes source and parses after mount. Both sides
must supply identical content, identity, configuration and locale. Math and diagram
previews use client resources and do not run loaders in SSR.
useMarkdownSource(input, onError?) exposes state, pending, generation and error
for custom React reading shells. Headless hosts use the parser core.
QuireMarkdown already includes the hook, so it needs no second session.
React prepares a cache frame during render and accepts it after commit. Abandoned
frames neither alter the committed directory nor notify error observers. Advanced
hosts use MarkdownRenderer.prepare(...) / frame.commit(); synchronous hosts can
use render(...). StrictMode cleanup and reconnection are repeatable. External keys
and HTML callbacks are rechecked on each component render; trigger a React update
after changing their external data.
Core, Vue and React are available; other frameworks are deferred. Reuse covers complete top-level blocks. See performance limits and React API.