Loading the parity record
Fetching the measured run — the pinned upstream oracle, every symbol and every case.
Fetching the measured run — the pinned upstream oracle, every symbol and every case.
Parity / react
Every number on this page was produced by running both implementations over the same cases: the real react package pinned at 19.2.7 answers first, and its answer is the expectation the Go port is held to. Nothing is a hand-written expectation, so a new upstream release re-scores the port on its own.
Not a generic diagram: every node below names an artefact of this harness — the pinned package it installed, the runner files it started, the case files it streamed, and the counts it wrote out.
| Case group | Cases | Match | Mismatch | Group parity |
|---|---|---|---|---|
| svg | 184 | 184 | 0 | 100.0% |
| attr-names | 51 | 51 | 0 | 100.0% |
| style | 51 | 51 | 0 | 100.0% |
| attr-values | 48 | 47 | 0 | 97.9% |
| elements | 40 | 40 | 0 | 100.0% |
| escaping | 27 | 27 | 0 | 100.0% |
| void | 23 | 22 | 0 | 95.7% |
| text-flow | 18 | 18 | 0 | 100.0% |
| data-aria | 17 | 17 | 0 | 100.0% |
| document | 12 | 12 | 0 | 100.0% |
| raw-html | 12 | 12 | 0 | 100.0% |
Every exported symbol of the upstream package, and what the port offers for it. The upstream list is derived mechanically, never from a README: node -e "const R=require('react'),S=require('react-dom/server'),D=require('react-dom');
console.log(Object.keys(R).sort().join(' '));
console.log(Object.keys(S).sort().join(' '));
console.log(Object.keys(D).sort().join(' '))". A symbol with no case is untested, never a match.
| Upstream symbol | Go symbol | Status | Cases | Note |
|---|---|---|---|---|
| renderToStaticMarkup | react.RenderToStaticMarkup | differs | 281 cases (every group) | the port's output diverges in three formatting classes below |
| renderToString | react.RenderToString | differs | rts-* (7) | the port makes it an exact alias of RenderToStaticMarkup; React inserts <!-- --> between adjacent text nodes for hydration |
| renderToPipeableStream | — | missing | — | no streaming renderer; react.RenderToWriter writes eagerly to an io.Writer but has no shell/suspense boundaries |
| renderToReadableStream | — | missing | — | web-streams variant of the above |
| resume | — | missing | — | prerender/resume (partial pre-rendering) is not ported |
| resumeToPipeableStream | — | missing | — | ditto |
| version | react.Version | untested | — | the port reports 19.2.8, a port version, not the React version it tracks; nothing compares them |
| — | react.RenderToWriter | extra | — | streaming-to-io.Writer primitive the other two are built on |
| — | react.MustRenderToString | extra | — | panicking convenience wrapper |
| — | react.RenderPortalsToString | extra | — | returns portal subtrees separately; React has no server equivalent |
| — | react.AttributeName | extra | an-* (51) | exported prop→attribute mapping |
| — | react.FormatStyle | extra | st-* (51) | exported style-object serializer |
| createElement | react.CreateElement / react.H | match | el-* (40) | children model, keys, arrays, falsy children |
| Fragment | react.Fragment | match | el-fragment-* (4) | |
| isValidElement | react.IsValidElement | untested | — | no serialized answer to compare |
| cloneElement | react.CloneElement | untested | — | not reachable through the tree encoding |
| Children | react.ChildrenCount, ChildrenForEach, … | untested | — | React's Children.map/toArray/only are split into functions; not serialization |
| Suspense | react.Suspense | untested | — | server behaviour needs streaming to be meaningful |
| StrictMode | react.StrictMode | untested | — | no server-visible output |
| Profiler | react.Profiler | untested | — | no server-visible output |
| Activity | — | missing | — | React 19.2 Activity/offscreen |
| Component, PureComponent | — | missing | — | class components are deliberately not ported (API-DEVIATIONS.md) |
| createContext | react.CreateContext | untested | — | transparent to the serializer |
| forwardRef | react.ForwardRef | untested | — | refs mean nothing server-side |
| createRef | react.CreateRef | untested | — | |
| memo | react.Memo / react.MemoWith | untested | — | transparent to the serializer |
| lazy | react.Lazy | untested | — | |
| use | react.Use | untested | — | |
| cache, cacheSignal | react.Cache, react.NewCache | untested | — | no cacheSignal equivalent |
| act | react.Act | untested | — | client-side test helper |
| startTransition | react.StartTransition | untested | — | |
| useState | react.UseState | untested | — | hooks run during SSR but are covered by the port's own unit tests, not by this corpus |
| useReducer | react.UseReducer, UseReducerInit | untested | — | |
| useEffect | react.UseEffect, UseEffectFn | untested | — | |
| useLayoutEffect | react.UseLayoutEffect, UseLayoutEffectFn | untested | — | |
| useInsertionEffect | react.UseInsertionEffect | untested | — | |
| useMemo | react.UseMemo | untested | — | |
| useCallback | react.UseCallback | untested | — | |
| useRef | react.UseRef | untested | — | |
| useContext | react.UseContext | untested | — | |
| useImperativeHandle | react.UseImperativeHandle | untested | — | |
| useDebugValue | react.UseDebugValue, UseDebugValueFn | untested | — | |
| useId | react.UseId | untested | — | React's ids are hydration-stable («R…»); the port's scheme is its own |
| useDeferredValue | react.UseDeferredValue, UseDeferredValueInitial | untested | — | |
| useTransition | react.UseTransition | untested | — | |
| useOptimistic | react.UseOptimistic | untested | — | |
| useActionState | react.UseActionState | untested | — | |
| useSyncExternalStore | react.UseSyncExternalStore | untested | — | |
| useEffectEvent | — | missing | — | React 19.2 |
| unstable_useCacheRefresh | — | missing | — | unstable |
| captureOwnerStack | — | missing | — | dev-only owner stacks |
| __CLIENT_INTERNALS_…, __COMPILER_RUNTIME | — | missing | — | private |
| createPortal | react.CreatePortal | untested | — | the port emits portal subtrees separately (RenderPortalsToString); React's server renderer drops them |
| flushSync | react.FlushSync, FlushSyncValue | untested | — | not serialization |
| unstable_batchedUpdates | react.Batch | untested | — | |
| useFormStatus | — | missing | — | |
| useFormState | react.UseFormState | untested | — | |
| requestFormReset | — | missing | — | |
| preload, preloadModule, preinit, preinitModule, preconnect, prefetchDNS | — | missing | void-img-src, void-meta | React 19 Float: these hoist <link>/<meta>/<title> into the head and emit preloads for img[src]. The port has no resource hoisting at all, which is observable in the output — recorded as deviations |
| __DOM_INTERNALS_… | — | missing | — | private |
Every case the harness streamed to both runners, with the exact upstream symbol and Go symbol it exercised. A deliberate, documented difference is a deviation and is counted apart from a mismatch.
| Case | Group | Upstream symbol | Go symbol | Status | Note |
|---|---|---|---|---|---|
| an-classname | attr-names | ReactDOM property table | react.AttributeName | match | |
| an-htmlfor | attr-names | ReactDOM property table | react.AttributeName | match | |
| an-defaultvalue | attr-names | ReactDOM property table | react.AttributeName | match | |
| an-tabindex | attr-names | ReactDOM property table | react.AttributeName | match | |
| an-tabindex-zero | attr-names | ReactDOM property table | react.AttributeName | match | |
| an-acceptcharset | attr-names | ReactDOM property table | react.AttributeName | match | |
| an-httpequiv | attr-names | ReactDOM property table | react.AttributeName | match | |
| an-charset | attr-names | ReactDOM property table | react.AttributeName | match | |
| an-colspan | attr-names | ReactDOM property table | react.AttributeName | match | |
| an-rowspan | attr-names | ReactDOM property table | react.AttributeName | match | |
| an-maxlength | attr-names | ReactDOM property table | react.AttributeName | match | |
| an-crossorigin | attr-names | ReactDOM property table | react.AttributeName | match | |
| an-datetime | attr-names | ReactDOM property table | react.AttributeName | match | |
| an-enctype | attr-names | ReactDOM property table | react.AttributeName | match | |
| an-formaction | attr-names | ReactDOM property table | react.AttributeName | match | |
| an-hreflang | attr-names | ReactDOM property table | react.AttributeName | match | |
| an-inputmode | attr-names | ReactDOM property table | react.AttributeName | match | |
| an-autocomplete | attr-names | ReactDOM property table | react.AttributeName | match | |
| an-autocapitalize | attr-names | ReactDOM property table | react.AttributeName | match | |
| an-referrerpolicy | attr-names | ReactDOM property table | react.AttributeName | match | |
| an-srcset | attr-names | ReactDOM property table | react.AttributeName | match | |
| an-srcdoc | attr-names | ReactDOM property table | react.AttributeName | match | |
| an-srclang | attr-names | ReactDOM property table | react.AttributeName | match | |
| an-cellpadding | attr-names | ReactDOM property table | react.AttributeName | match | |
| an-usemap | attr-names | ReactDOM property table | react.AttributeName | match | |
| an-itemprop | attr-names | ReactDOM property table | react.AttributeName | match | |
| an-mediagroup | attr-names | ReactDOM property table | react.AttributeName | match | |
| an-radiogroup | attr-names | ReactDOM property table | react.AttributeName | match | |
| an-keytype | attr-names | ReactDOM property table | react.AttributeName | match | |
| an-classid | attr-names | ReactDOM property table | react.AttributeName | match | |
| an-frameborder | attr-names | ReactDOM property table | react.AttributeName | match | |
| an-nomodule | attr-names | ReactDOM property table | react.AttributeName | match | |
| an-contextmenu | attr-names | ReactDOM property table | react.AttributeName | match | |
| an-controlslist | attr-names | ReactDOM property table | react.AttributeName | match | |
| an-imagesizes | attr-names | ReactDOM property table | react.AttributeName | match | |
| an-autocorrect | attr-names | ReactDOM property table | react.AttributeName | match | |
| an-lowercase-passthrough | attr-names | ReactDOM property table | react.AttributeName | match | |
| an-uppercase-passthrough | attr-names | ReactDOM property table | react.AttributeName | match | |
| an-hyphen-custom | attr-names | ReactDOM property table | react.AttributeName | match | |
| an-svg-hyphenated | attr-names | ReactDOM property table | react.AttributeName | match | |
| an-svg-camel-kept | attr-names | ReactDOM property table | react.AttributeName | match | |
| an-svg-text-anchor | attr-names | ReactDOM property table | react.AttributeName | match | |
| an-svg-clip-path | attr-names | ReactDOM property table | react.AttributeName | match | |
| an-svg-marker | attr-names | ReactDOM property table | react.AttributeName | match | |
| an-xlink-href | attr-names | ReactDOM property table | react.AttributeName | match | |
| an-xml-lang | attr-names | ReactDOM property table | react.AttributeName | match | |
| an-font-family | attr-names | ReactDOM property table | react.AttributeName | match | |
| an-event-handler-dropped | attr-names | ReactDOM property table | react.AttributeName | match | |
| an-onx-prefixed-custom | attr-names | ReactDOM property table | react.AttributeName | match | |
| an-key-not-emitted | attr-names | ReactDOM property table | react.AttributeName | match | |
| an-ref-not-emitted | attr-names | ReactDOM property table | react.AttributeName | match | |
| av-disabled-true | attr-values | ReactDOMServer.renderToStaticMarkup | react.RenderToStaticMarkup | match | |
| av-disabled-false | attr-values | ReactDOMServer.renderToStaticMarkup | react.RenderToStaticMarkup | match | |
| av-disabled-null | attr-values | ReactDOMServer.renderToStaticMarkup | react.RenderToStaticMarkup | match | |
| av-disabled-undefined | attr-values | ReactDOMServer.renderToStaticMarkup | react.RenderToStaticMarkup | match | |
| av-disabled-string | attr-values | ReactDOMServer.renderToStaticMarkup | react.RenderToStaticMarkup | match | |
| av-checked-true | attr-values | ReactDOMServer.renderToStaticMarkup | react.RenderToStaticMarkup | match | |
| av-checked-false | attr-values | ReactDOMServer.renderToStaticMarkup | react.RenderToStaticMarkup | match | |
| av-defaultchecked | attr-values | ReactDOMServer.renderToStaticMarkup | react.RenderToStaticMarkup | match | |
| av-readonly-true | attr-values | ReactDOMServer.renderToStaticMarkup | react.RenderToStaticMarkup | match | |
| av-required | attr-values | ReactDOMServer.renderToStaticMarkup | react.RenderToStaticMarkup | match | |
| av-multiple | attr-values | ReactDOMServer.renderToStaticMarkup | react.RenderToStaticMarkup | match | |
| av-hidden-true | attr-values | ReactDOMServer.renderToStaticMarkup | react.RenderToStaticMarkup | match | |
| av-hidden-string | attr-values | ReactDOMServer.renderToStaticMarkup | react.RenderToStaticMarkup | match | |
| av-open | attr-values | ReactDOMServer.renderToStaticMarkup | react.RenderToStaticMarkup | match | |
| av-async-defer | attr-values | ReactDOMServer.renderToStaticMarkup | react.RenderToStaticMarkup | match | |
| av-autofocus | attr-values | ReactDOMServer.renderToStaticMarkup | react.RenderToStaticMarkup | match | |
| av-autoplay-loop-muted | attr-values | ReactDOMServer.renderToStaticMarkup | react.RenderToStaticMarkup | match | |
| av-controls | attr-values | ReactDOMServer.renderToStaticMarkup | react.RenderToStaticMarkup | match | |
| av-novalidate | attr-values | ReactDOMServer.renderToStaticMarkup | react.RenderToStaticMarkup | match | |
| av-formnovalidate | attr-values | ReactDOMServer.renderToStaticMarkup | react.RenderToStaticMarkup | match | |
| av-allowfullscreen | attr-values | ReactDOMServer.renderToStaticMarkup | react.RenderToStaticMarkup | match | |
| av-playsinline | attr-values | ReactDOMServer.renderToStaticMarkup | react.RenderToStaticMarkup | match | |
| av-itemscope | attr-values | ReactDOMServer.renderToStaticMarkup | react.RenderToStaticMarkup | match | |
| av-reversed | attr-values | ReactDOMServer.renderToStaticMarkup | react.RenderToStaticMarkup | match | |
| av-selected | attr-values | ReactDOMServer.renderToStaticMarkup | react.RenderToStaticMarkup | match | |
| av-contenteditable-true | attr-values | ReactDOMServer.renderToStaticMarkup | react.RenderToStaticMarkup | match | |
| av-contenteditable-bool | attr-values | ReactDOMServer.renderToStaticMarkup | react.RenderToStaticMarkup | match | |
| av-contenteditable-false-bool | attr-values | ReactDOMServer.renderToStaticMarkup | react.RenderToStaticMarkup | match | |
| av-draggable-true | attr-values | ReactDOMServer.renderToStaticMarkup | react.RenderToStaticMarkup | match | |
| av-draggable-false | attr-values | ReactDOMServer.renderToStaticMarkup | react.RenderToStaticMarkup | match | |
| av-spellcheck-false | attr-values | ReactDOMServer.renderToStaticMarkup | react.RenderToStaticMarkup | match | |
| av-custom-attr-true | attr-values | ReactDOMServer.renderToStaticMarkup | react.RenderToStaticMarkup | match | React drops a boolean on a non-boolean, non-data/aria attribute (dev build also warns). |
| av-custom-attr-false | attr-values | ReactDOMServer.renderToStaticMarkup | react.RenderToStaticMarkup | match | |
| av-null-drops | attr-values | ReactDOMServer.renderToStaticMarkup | react.RenderToStaticMarkup | match | |
| av-undefined-drops | attr-values | ReactDOMServer.renderToStaticMarkup | react.RenderToStaticMarkup | match | |
| av-empty-string-kept | attr-values | ReactDOMServer.renderToStaticMarkup | react.RenderToStaticMarkup | match | |
| av-number-int | attr-values | ReactDOMServer.renderToStaticMarkup | react.RenderToStaticMarkup | match | |
| av-number-float | attr-values | ReactDOMServer.renderToStaticMarkup | react.RenderToStaticMarkup | match | |
| av-number-zero | attr-values | ReactDOMServer.renderToStaticMarkup | react.RenderToStaticMarkup | match | |
| av-number-negative | attr-values | ReactDOMServer.renderToStaticMarkup | react.RenderToStaticMarkup | match | |
| av-number-exponent | attr-values | ReactDOMServer.renderToStaticMarkup | react.RenderToStaticMarkup | match | Same JS-vs-Go number formatting boundary as el-child-exponent. |
| av-value-input | attr-values | ReactDOMServer.renderToStaticMarkup | react.RenderToStaticMarkup | match | |
| av-value-number | attr-values | ReactDOMServer.renderToStaticMarkup | react.RenderToStaticMarkup | match | |
| av-alt-empty | attr-values | ReactDOMServer.renderToStaticMarkup | react.RenderToStaticMarkup | match | |
| av-input-type-order | attr-values | ReactDOMServer.renderToStaticMarkup | react.RenderToStaticMarkup | match | |
| av-option-value-order | attr-values | ReactDOMServer.renderToStaticMarkup | react.RenderToStaticMarkup | match | |
| av-multi-attrs | attr-values | ReactDOMServer.renderToStaticMarkup | react.RenderToStaticMarkup | match | |
| order-insertion | attr-values | ReactDOMServer.renderToStaticMarkup | react.RenderToStaticMarkup | deviation | React emits attributes in JS object insertion order; the port sorts prop names, because Go maps have no order (react/ssr.go). Every other case is authored with prop keys pre-sorted so the two agree. |
| da-data-simple | data-aria | ReactDOMServer.renderToStaticMarkup | react.RenderToStaticMarkup | match |