Skip to content
C.W.K.
Stream
Lesson 05 of 05 · published

Why CM6 Wins

~11 min · why-cm6, reuse, architecture, synthesis

Level 0Cold Draft
0 XP0/44 lessons0/13 achievements
0/100 XP to next level100 XP to go0% complete
"The decoration engine doing triple duty isn't a nice bonus. It's the whole reason CodeMirror was chosen."

Three Features, One Primitive

Step back and look at the three jobs together. Live Preview: compute ranges, attach marks (and replace decorations that hide tokens). Voice underline: compute ranges, attach a mark and a hover note. CMD+K: attach a widget holding a proposal, mutate on accept. Three features that look completely unrelated — a renderer, a linter, an AI editor — collapse to the same shape: compute ranges over the source, attach decorations, mutate only when the user commits. One primitive, learned once, powering the entire soul layer.

Live Preview   ranges -> marks + replacements        (render the look)
Voice underline ranges -> marks + a hover note         (flag voice issues)
CMD+K          a widget proposal -> one accept edit    (stage an AI rewrite)

# Different inputs. Same decoration primitive. That's the win.

Where a Rich-Text Model Pulls Apart

Now imagine building the same three features on a rich-text tree (Tiptap over ProseMirror, or Lexical). Be fair to it first: ProseMirror has decorations too — inline ones that style a range and widget ones that insert UI, none of them mutating the document — so a voice underline and a pending CMD+K proposal could share that primitive there as well. The split comes from the model underneath. Live Preview isn't even a concept on a tree: the tree is the rendered form, and there is no Markdown source left to reveal on the active line, so "show source with a rendered look" fights the model. And every position the other two features compute is a tree position, which has to be translated back to the Markdown file you actually store. Two of the three jobs fit; the job that made Rekindle feel like Rekindle doesn't, and everything pays a translation tax.

The Reuse Is the Architecture

This is why 'one mechanism, three jobs' is a load-bearing decision, not a happy accident. CodeMirror was chosen because its decoration-over-source primitive makes all three soul features the same shape. The soul features — live voice, inline AI, every decoration-borne UI — ride one mechanism you build and debug once (margin-Pippa herself rides the bind; that's track 6). That's the family's first pillar, Reuse, expressed as an editor-core choice: don't pick the substrate with the most features; pick the one whose single primitive your features already share. When the reuse is that deep, it stops being an optimization and becomes the architecture.

Code

Three jobs, one decoration primitive·text
Feature         Shape                                   Kind
--------------  --------------------------------------  -----------------
Live Preview    ranges -> marks + replacements          render the look
Voice underline ranges -> marks + a hover note          flag voice issues
CMD+K           a widget proposal -> one accept edit    stage an AI rewrite

# Different inputs, same primitive, over the same source text the file
# stores. A rich-text tree has decorations too, but no source to reveal
# for Live Preview, and tree positions to translate back for the rest.

External links

Exercise

Take any editor feature you'd want to add to Rekindle next (say, showing translation suggestions, or highlighting repeated words). Ask: does it reduce to 'compute ranges over source, attach marks or a widget, mutate on accept'? If yes, it needs no new subsystem — it rides the existing engine. Notice how the substrate choice keeps paying off with every new feature.
Hint
Most 'show something over the writer's text' features do reduce to the decoration shape. The ones that don't (a true rich-text table editor, say) are exactly the features that would justify a different substrate — which is how you'd know Rekindle had outgrown its core, if it ever did.

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.