docs/slate-browser/four-way-api-deep-dive.md
Specialist testing/proof doc. For current queue and roadmap truth, see master-roadmap.md.
This is the focused follow-up on exactly four candidates:
LexicalProseMirrorTiptapedixThe question is not “which editor is best?”
It is:
slate-browserIf the goal is the absolute best Slate-flavoured testing framework:
Lexical is still the strongest helper-API sourceProseMirror is the strongest seam/invariant sourceedix still has a few high-value semantic getter ideasTiptap is mostly a DX and productization validator, not a helper-API mineThat means:
Lexical and ProseMirroredix targetedTiptap to hand us the core next API trancheFiles:
Still-high-value imports:
initialize(...)ignoreClasses, ignoreInlineStyles, ignoreDirwithExclusiveClipboardAccess(...)createHumanReadableSelection(...)ready contractWhy later:
Candidate shape:
const expected = selection({
anchor: {
path: [
[1, "table row"],
[0, "first cell"],
],
offset: [0, "start of cell"],
},
focus: {
path: [
[2, "last paragraph"],
[0, "first span"],
[0, "text node"],
],
offset: [9, "full text length"],
},
});
This should be a docs/test-authoring helper first, not the first new public runtime API.
initialize(...) breadthLexical is still where the next tranche gets its spine.
Files:
Still-high-value imports:
getBookmark()coordsAtPos, posAtCoordsThat is not a knock. It means ProseMirror is feeding invariants and later APIs, not next-week sugar.
This is the most interesting new idea from the deeper pass.
Candidate shape:
const bookmark = await editor.selection.bookmark();
// later in the same test
await editor.assert.selection(bookmark);
Or:
const bookmark = await editor.selection.capture();
What it should mean:
Why later:
Candidate shape:
const caret = await editor.selection.coords();
await editor.assert.selectionCoords({ top: [100, 104] });
Why later:
selection.rect() already covers the first cheap versionProseMirror is not giving the nicest API.
It is giving the best invariants and one serious later API:
selection bookmarks.
Files:
Still-high-value imports:
Small candidate:
await editor.assert.placeholder({
visible: true,
text: "Type something",
});
Why later:
ready, selection.select, blockTexts, and
snapshot()If withExtension(...) ever grows into a real hook surface, Tiptap’s
dispatchTransaction tests are the warning:
This is future design pressure, not a next API.
NodeRangeSelection is interesting, but not a slate-browser API yet.
It only becomes interesting if Slate itself grows a real block/node-range selection seam worth proving through the browser harness.
Tiptap is good for:
It is not where the next core slate-browser API tranche comes from.
Files:
Still-high-value imports:
getTextgetSelectiongetSelectedRectgetSeletedTextblockTextsselectedTextCandidate shape:
await editor.assert.caretAroundVoid({
path: [0],
beforeOffset: 3,
afterOffset: 4,
});
Why later:
Good for pure/browser lanes. Not good as a first-class Playwright public API.
We already got the main value:
Returns are diminishing now.
ready contract
editor.selection.select(...)
editor.get.blockTexts() / assert.blockTexts(...)
editor.snapshot()
editor.get.selectedText()
rect()
openFixture(...)editor.driver()After the deeper four-way pass:
Lexical still wins the next-helper questionProseMirror contributes one serious later API:
selection bookmarksTiptap is mostly a packaging and focused-test validatoredix still matters, but mainly for semantic gettersSo yes, digging deeper was worth it.
But it did not overthrow the ranking.
It made it sharper.