Initial deliverable of the architecture phase: 16 ADRs (stack, CRDT collaboration, plugin sandbox, import/export, backups, CI/CD), data model, permission model, real-time collaboration and plugin concepts, deployment/operations/security documentation, and the milestone roadmap that the implementation issues are derived from. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2.7 KiB
2.7 KiB
ADR 0004: TipTap (ProseMirror) as the WYSIWYG editor
- Status: accepted
- Date: 2026-07-04
Context
Dorfteich needs a WYSIWYG editor with: collaborative cursors, CRDT binding (ADR 0003), Markdown-friendly copy/paste, image paste from the clipboard, link editing UX (edit URL / open in new tab), and a schema that plugins can extend with custom block types (ADR 0008).
Decision
- TipTap (MIT-licensed core, built on ProseMirror) is the editor
framework, used with:
@tiptap/extension-collaboration— binds the document to Yjs,@tiptap/extension-collaboration-cursor— remote cursors/selections,- standard extensions for headings, lists, tables, code blocks, images, links, task lists.
- Document schema is the source of truth and is defined centrally in
packages/shared(node/mark specs), so that editor, server-side rendering/export, and plugin validation agree on what a valid document is. - Markdown interop: paste and import/export convert between Markdown and
the ProseMirror document model (
prosemirror-markdown, extended for our custom nodes such as wikilinks). Markdown remains the primary exchange format; the internal format is the ProseMirror/Yjs document, as the vision allows ("internal format follows technical requirements"). - Links: a bubble menu on links offers "edit URL" and "open in new tab" (the two actions required by the vision).
- Images: clipboard paste and menu insert both upload through the API (quota-checked, ADR 0011) and insert an image node referencing the stored file — no base64 blobs inside documents.
- Wikilinks: a custom inline node
wikilinkwith[[autocomplete, resolved against pages of the current pond; backlinks are indexed server-side (seedata-model.md).
Consequences
- ProseMirror's schema-based model gives us structural guarantees (valid documents by construction) that plain contenteditable or Markdown-string editors cannot.
- Plugin-defined block types register as ProseMirror nodes rendered inside a
sandbox (details in
plugin-architecture.md). - Mobile editing is explicitly out of scope (kickoff decision); we target desktop browsers and accept degraded editing UX on touch devices, while reading stays fully responsive.
Alternatives considered
- Slate, Lexical: capable editors, but Yjs integration and the extension ecosystem are notably less mature than ProseMirror/TipTap's.
- CodeMirror + Markdown source editing: excellent for developer wikis but contradicts the WYSIWYG requirement.
- BlockNote (block editor on TipTap): attractive UX shortcut, but its opinionated block model would constrain our plugin block types and styling requirements; we build on TipTap directly.