Isomorphic, not export
mdToDoc / docToMd via mdast. Clean blocks keep source spans so untouched prose doesn’t reformat away.
Rich text · Markdown isomorphism · AI-native
A schema-constrained tree, reversible Steps, and MD as a first-class projection —
not “export later.” Optional AI streams into real blocks; collab is one options field.
No ProseMirror.
Markdown source, stable-id tree, and the controlled editor are the same document. AI appends a draft block — accept commits, discard undoes. No second history.
# Shipping notes **markloom** keeps MD honest. - Tree is source of truth - Steps are reversible - AI writes real blocks ```ts apply ∘ invert = id ```
Paste text/plain as MD · HTML as blocks
Agents address id · paths move with structure
markloom keeps MD honest.
apply ∘ invert = id
Next: ship collab presence to production…
contentEditable owned · beforeinput → Steps
Four primitives. Product surfaces without a second document model.
mdToDoc / docToMd via mdast. Clean blocks keep source spans so untouched prose doesn’t reformat away.
Insert, delete, replace, splice. apply ∘ invert = identity — undo, history, and AI rollback are the same mechanism.
Preact + contentEditable owned via beforeinput. Model is truth; IME is a 3-way merge, not hope.
Slash /ai, format-bar continue/rewrite, stream into real draft blocks. Accept = commit; discard = undo.
collab: { url, room } on the editor. Centralized OT, presence avatars, per-person undo. Worker included.
Slash menu, bubble bar, drag handle, tables, callouts, TOC, comments — extensions without forking the kernel.
Kernel has no DOM. View, AI, collab, and React are optional entrypoints on the same package.
npm i markloom
import { Editor } from 'markloom/view'
import 'markloom/view/theme.css'
const ed = new Editor(root, doc, {
onChange: d => save(docToMd(d)),
// ai: { provider | endpoint | stream }
// collab: { url, room, name }
})
| Import | What it is |
|---|---|
markloom | Tree, Steps, history, MD, appendText / diffById |
markloom/view | Editor + theme.css |
markloom/ai | AI controller + stream helper + theme |
markloom/collab | Realtime OT client (pair with worker/) |
markloom/react | Optional React wrapper |
Stop gluing paste, IME, undo, and AI cards. Start from reversible Steps.