Skip to content

build(deps): tiptap v3 + unify markdown on marked (drop markdown-it) - #1644

Open
mattwoberts wants to merge 3 commits into
mainfrom
deps/tiptap-markdown-swap
Open

build(deps): tiptap v3 + unify markdown on marked (drop markdown-it)#1644
mattwoberts wants to merge 3 commits into
mainfrom
deps/tiptap-markdown-swap

Conversation

@mattwoberts

Copy link
Copy Markdown
Contributor

The full unify-on-marked migration. Ends with the app running a single markdown engine (marked 17) for both the editor and the display renderer. Three commits:

  1. marked 4→17 — display renderer (markdown.ts) rewritten to marked's token API; byte-identical (markdown.spec.ts 32/32); .babelrcbabel.config.json + jest ESM transform.
  2. tiptap v2→v3 — whole @tiptap/* stack to 3.29.2, StarterKit Link/Underline disabled, Placeholder → @tiptap/extensions, setContent emitUpdate handling.
  3. editor engine swap → @tiptap/markdown — drops tiptap-markdown, markdown-it, and prosemirror-markdown.

What changed in the swap

  • markdown-it is gone. markdown-it, tiptap-markdown, prosemirror-markdown removed; only @tiptap/markdown + marked remain (both on marked 17, deduped).
  • CustomImage: parseMarkdown/renderMarkdown for the ![](fider-image:<bkey>) syntax; the node is now inline (marked tokenizes images inline — a block node was silently dropped during parse; also matches the fider-inline-image intent).
  • CustomMention: a custom marked markdownTokenizer for the non-standard @[name] syntax + parse/render hooks.
  • CommentEditor: contentType: "markdown" on content/setContent, getMarkdown().trim().

Gotchas found & handled

  • this inside parseMarkdown is not the extension (no this.name/this.options) → node types are literals; image src uses the static path (same fallback as before; live base64 uploads still go through the setImage command).
  • v3 setContent appends a trailing empty paragraph → .trim().
  • Hard breaks normalize to the standard two-space form — render-equivalent (the marked renderer emits identical <br> HTML for bare \n and \n under breaks:true), so existing stored content is unaffected.

Validation

  • 21-case byte-identical round-trip suite (CommentEditor.markdown.spec.ts): mentions/images standalone and in text, mixed inline, multi-paragraph, hard breaks, links+mentions.
  • markdown.spec.ts 32/32 (renderer contract unchanged), setImage command → ![](fider-image:…) verified.
  • make lint-ui / build-ui / test-ui green. CI (incl. e2e) is the next gate.

Please review carefully

Images are now inline rather than block — a deliberate change (required for marked parse; matches the inline-image class), but it changes editor layout, so worth a visual check. This is the experimental "how far can we go" branch; the safe fallback is the earlier tiptap-v3-only state.

🤖 Generated with Claude Code

mattwoberts and others added 3 commits July 29, 2026 15:37
First step of unifying the app's two markdown engines onto marked. This
upgrades the display renderer (public/services/markdown.ts) off the ancient
marked 4 (held by a dependabot ignore) to marked 17 — the version @tiptap/markdown
peers, so the later editor migration will dedupe to a single marked copy.

marked 5+ is ESM-only and replaced the positional Renderer API with token
objects registered via .use(). Changes:
- markdown.ts: two Marked instances (full + plain-text) with RendererObject
  overrides; custom escape keeps apostrophes literal (marked now emits &#39;);
  fider-image + @[mention] syntaxes preserved byte-identically.
- package.json: marked ^4.0.15 -> ^17.0.6; remove @types/marked (marked ships
  its own types); jest transform now includes .js + transformIgnorePatterns
  allows transforming marked's ESM.
- .babelrc -> babel.config.json: a root babel config is required for jest to
  transform ESM node_modules (a file-scoped .babelrc does not apply to them).
  Webpack's babel-loader only processes public/ + locale/, so the build is
  unaffected.
- dependabot.yml: marked now held on 17.x (was 4.x) pending @tiptap/markdown
  supporting marked 18.

Validated byte-identical: markdown.spec.ts (32/32), plus make lint-ui,
build-ui, test-ui all green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…0.9)

Bumps the whole @tiptap/* stack to 3.29.2 (exact-pinned — tiptap enforces
identical versions across its packages), tiptap-markdown -> 0.9.0, moves
Placeholder to @tiptap/extensions, disables StarterKit's now-bundled Link +
Underline, and sets setContent emitUpdate:false. Adds a byte-identical markdown
round-trip test suite (13 cases incl. fider-image + @mention) as the gate for
the later @tiptap/markdown engine swap. jest transformIgnorePatterns extended
for @tiptap/tiptap-markdown/prosemirror ESM.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… on marked)

Completes the unify-on-marked migration: the editor now uses first-party
@tiptap/markdown (marked engine) instead of tiptap-markdown (markdown-it).
markdown-it, tiptap-markdown and prosemirror-markdown are removed entirely —
the app now runs a SINGLE markdown engine (marked 17), shared by the editor
and the display renderer.

Custom-node rewrite (markdown-it rules -> @tiptap/markdown hooks):
- CustomImage: markdownTokenName "image" + parseMarkdown/renderMarkdown; detects
  ![](fider-image:<bkey>). Made the node INLINE — marked tokenizes images as
  inline tokens, so a block node was dropped during parse (matches the
  fider-inline-image intent).
- CustomMention: a custom marked markdownTokenizer for the non-standard @[name]
  syntax + parseMarkdown/renderMarkdown.
- Note: `this` inside parseMarkdown is NOT the extension (no this.name/this.options),
  so node types are literals and image src uses the static path (the same fallback
  used before; live base64 uploads still flow through the setImage command).
- CommentEditor: Markdown.configure({ markedOptions: { breaks, gfm } }),
  content/setContent use contentType:"markdown", getMarkdown().trim() (v3 appends a
  trailing empty paragraph).

Validation: new 21-case byte-identical round-trip suite (mentions/images in text,
mixed inline, multi-paragraph, hard breaks, links+mentions) + markdown.spec 32/32
(renderer contract unchanged) + make lint-ui/build-ui/test-ui all green. Hard
breaks normalize to the standard two-space form, which the renderer emits as
identical <br> HTML, so existing stored content is unaffected.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant