Skip to content
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/44 lessons0/13 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: a bold button whose effect Ctrl+Z undoes as exactly one step, interleaved correctly with the typing around it, in every browser. 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 a black box: it groups typing by its own heuristics, those heuristics differ between browsers, and changes your own code makes to the DOM don't land in it the way the user's typing does. Undo that follows YOUR rules means owning the history yourself — its own subsystem, and 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 in — Please sign in to comment.

No comments yet — be the first.