docs/solutions/performance-issues/2026-05-01-slate-v2-legacy-compare-benchmark-must-align-bun-workspace-source-and-built-react-surfaces.md
The huge-document legacy comparison benchmark was stale after the Slate v2 hard cut. It still assumed legacy-style public Editor APIs and only emitted one v2 row, so it could not compare v2 with islands against v2 without islands.
Editor.replace was undefined when the current runner imported root slate.Editor.replace only to fail on stale current-side
assumptions like editor.insertText, editor.select, and editor.insertFragment.slate-react through Bun hit JSX runtime failures such as React is not defined.slate with built slate-react caused transform-registry singleton mismatches because Bun still resolved slate-react's bare workspace imports to source.legacyChunkOff, legacyChunkOn, and v2LargeDocument, but no v2NoIsland.withReact cut, the current benchmark runner failed with
Export named 'withReact' not found in module .../packages/slate-react/dist/index.js.shellEnabled after the shell/island rename,
so current-only runs could fail before emitting trace artifacts.slate-react source directly. It exposed source JSX-runtime assumptions that are irrelevant to the built benchmark target.dist. Bun workspace resolution still made built slate-react consume source slate internals.slate/internal from the built current package for core compare.
That exposed only the built package's runtime export shape, not the full source
static Editor API needed by local benchmark fixtures.largeDocument option as already benchmarked both ways. The script only hardcoded enabled: true.Keep the current benchmark runner on one runtime identity:
slate plus slate/internal for v2 editor setup and transaction helpersslate-react/dist/index.js for the React surface after the script's forced buildtx.selection.set, tx.text.insert, tx.fragment.insertlargeDocument: null../../packages/slate/src/index.ts and ../../packages/slate/src/internal/index.ts
first, then fall back to package imports for legacy checkoutswithReact cut, current React benchmark rows should import
createReactEditor from ../../packages/slate-react/dist/index.js and
replace every current-side withReact(createEditor()) fixture with
createReactEditor()shellEnabled still
names the old concept, derive it locally from the current strategy flag before
the trace is emittedKept file:
The benchmark needs v2's hard-cut write API and v2 React's built JSX output, but it must not split editor runtime singletons. Source slate and source slate/internal keep the editor registry aligned with the workspace resolution used by built slate-react.
The no-island row is not a separate feature flag. It is the same <Editable> surface with largeDocument: null, which makes EditableTextBlocks render all top-level runtime ids instead of an island plan.
Core compare runners are stricter: they do not need built React, but they still
need the current source static Editor API. A local runner under .tmp/benchmarks
can import current source files with ../../packages/slate/src/...; legacy
checkouts cannot, so the same embedded runner must fall back to import('slate')
and legacy Transforms.
import.meta.resolve(...) before mixing source and dist.Editor internals, and keep a package-import fallback for
legacy.Editor.getSnapshot/Editor.getChildren/editor.children for reads, and
tx.text.insert/tx.selection.set/tx.fragment.insert versus legacy
Transforms for writes.0 benchmark JSON as "command ran", not "claim passed".
Inspect threshold fields and stress-row numbers before updating issue claims.