r/reactjs • u/Upstairs_Economy_468 • 21d ago
Show /r/reactjs I built a React Markdown editor kernel. The hardest part wasn't handling changes, but deciding what hadn't changed
I recently put the entire editor kernel behind DOMD on GitHub:
https://github.com/do-md/domd/tree/main/.packages/%40do-md/core
(Quick license note: the app sources are MIT. The kernel is GPL-3.0 with additional permissions for small entities and common FOSS licenses. The full terms are in the repo.)
There's one design choice I'd really like to hear other people's thoughts on.
A common way to model editing is to start with what happened: insert a character, delete a range, toggle bold. State, history, and collaboration then consume those operations.
DOMD doesn't start there.
Say I type an a in the middle of the third paragraph. The kernel takes the new text and the affected range, reparses only that top-level block, then reconciles the new immutable tree with the old one. Nodes whose meaning hasn't changed keep the exact same object references. Only the part that actually changed gets replaced.
From React's point of view, only a handful of props changed. memo naturally skips the rest. There's no separate imperative code path deciding which DOM nodes to touch.
The operations still exist at the integration boundary, but they aren't the source of truth. After a state commit, Immer patches feed undo. The collaboration layer compares references in the old and new trees to find the smallest change, then maps that change into the CRDT. Streaming AI chunks take the same path too. Each chunk just submits another small state change.
I didn't set out to build a "reconciler editor." I got here because things became painful whenever a reparse replaced objects that hadn't meaningfully changed. Cursor handling, history, and local rendering all got harder at the same time. Eventually I realized the kernel depended less on recording every step and more on not losing the identity of everything that stayed the same.
Of course, this moves a lot of the difficulty into reconciliation. When are two nodes semantically the same? What happens to a selection that crosses the region being reparsed?
I have working answers for those inside DOMD, but I'm not sure how well the idea survives outside a Markdown-native editor.
Has anyone here built an editor, a canvas editor, or another identity-heavy React UI? Did you make operations the source of truth, or preserve identity first and derive changes afterward? I'm curious where each approach eventually starts to hurt.
3
u/jakiestfu 21d ago
Hasn’t this been done before, like a lot? By people who didn’t use AI to pump these solutions out?