C.W.K.
Stream
Lesson 01 of 04 · published

Don't Hand-Roll the Core

~11 min · cm6-thin, contenteditable, borrow, uxp-thin

Level 0Cold Draft
0 XP0/33 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"Half the reason editors are hard is getting the text primitive layer right. So don't build it — borrow it."

The Layer That Looks Free and Isn't

A browser hands you contenteditable and it feels like a gift: slap it on a <div> and text is editable. That's the trap. The moment you need real behavior — a cursor that lands where you expect, selection across styled spans, undo/redo that groups edits sanely, copy/paste that doesn't inject garbage HTML, and above all IME composition — you discover you now own a bottomless pit. Every browser behaves slightly differently, and every one of them fights you.

This is the text primitive layer, and getting it right is half of what makes an editor hard. It is not glamorous work; it is months of edge cases. Rekindle refuses to spend those months. It stands on CodeMirror 6 and never writes raw contenteditable.

Borrow the Commoditized Hard Part

The whole editing core — cursor math, selection model, history, IME lifecycle — arrives in a few lines when you borrow it. What you'd bleed for over a year is an import:

import { EditorView, basicSetup } from "codemirror";
import { markdown } from "@codemirror/lang-markdown";

new EditorView({
  doc: "# Hello\n\nStart writing...",
  extensions: [basicSetup, markdown()],
  parent: document.querySelector("#editor")!,
});

That's cursor, selection, undo, and IME — solved, correct, cross-platform — for free. Your job is not to rebuild it; your job is to layer your value (Live Preview, voice underline, CMD+K) on top of a core someone else already made bulletproof.

The Same Rule Cinder Follows

This is not a Rekindle quirk — it's a family law. Cinder's version is UXP-thin: don't rebuild a mini-Photoshop inside the plugin; let Photoshop be the hand. Loomis's version is deterministic geometry first, ML only for landmark fitting. Every sibling names the commoditized hard part and refuses to rebuild it. Rekindle's commoditized hard part is text editing, and CodeMirror 6 is where it goes to be solved.

Code

The entire editing core, borrowed in a few lines·typescript
import { EditorView, basicSetup } from "codemirror";
import { markdown } from "@codemirror/lang-markdown";

// Cursor, selection, undo/redo, IME composition, cross-platform —
// all of it arrives here. You are borrowing it, not building it.
const view = new EditorView({
  doc: "# Hello\n\nStart writing...",
  extensions: [basicSetup, markdown()],
  parent: document.querySelector("#editor")!,
});

// Your job starts ABOVE this line: layer Live Preview, voice
// underline, and CMD+K on a core that's already bulletproof.

External links

Exercise

Open a plain HTML file, add a div with contenteditable, and try to implement one 'simple' feature: Ctrl+Z that undoes your last word as one step, not one character. Time how long you last before reaching for a library. That wall you hit is exactly the wall CodeMirror 6 already climbed for you.
Hint
You'll hit it fast: the browser's native undo for contenteditable is per-input-event and un-groupable. Grouping edits into sane undo steps is its own subsystem — one of the many CM6 hands you for free.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.