Documentation source
TipTap v3 Migration
Evaluate and plan migration from TipTap v2.27 to v3.22
## Problem
We are on TipTap v2.27.2 with `tiptap-markdown@0.8.10`. TipTap v3.22 is stable and offers first-class markdown APIs (`parseMarkdown`, `renderMarkdown`, `createInlineMarkdownSpec`) that would replace our `addStorage()` workaround for wikilink serialization. v2 will eventually lose maintenance.
## Current State
| Package | Current | Latest |
|---------|---------|--------|
| `@tiptap/core` | 2.27.2 | 3.22.2 |
| `@tiptap/react` | 2.27.2 | 3.22.2 |
| `@tiptap/starter-kit` | 2.27.2 | 3.22.2 |
| `@tiptap/extension-link` | 2.27.2 | 3.22.2 |
| `@tiptap/extension-placeholder` | 2.27.2 | 3.22.2 |
| `@tiptap/pm` | 2.27.2 | 3.22.2 |
| `tiptap-markdown` | 0.8.10 | 0.9.0 (v3 peer dep) |
| `@tiptap/suggestion` | 2.27.2 | 3.22.2 |
**Editor instances:** 4 files use TipTap (markdown-editor, markdown-viewer, notes-editor, field-card-block).
**Custom extensions:** 2 (wikilink-extension, slash-command-extension) — both use `addStorage()` for markdown integration.
## Recommendation
**Upgrade, but not urgently.** Schedule as P2 after the obsidian-interop feature is stable and merged.
### Pros
| Benefit | Impact |
|---------|--------|
| **First-class markdown APIs** | `parseMarkdown`/`renderMarkdown` on extension config replace the `addStorage.markdown` workaround. Cleaner, less fragile. |
| **Maintained dependency** | v2 will eventually be EOL. v3 gets security patches and new features. |
| **Bundle improvements** | v3 has better tree-shaking and smaller ProseMirror builds. |
| **tiptap-markdown 0.9.0 exists** | Already published (Sep 2025) with `@tiptap/core: ^3.0.1` peer dep. Direct upgrade path. |
| **Future extensions** | Any new TipTap extensions or community plugins will target v3. |
### Cons
| Risk | Severity | Mitigation |
|------|----------|-----------|
| **tiptap-markdown 0.9.0 is new** | Medium | Published Sep 2025. Only 7 months of production use. Test thoroughly. |
| **No `@tiptap/extension-markdown` exists** | Low | We stay on `tiptap-markdown` (community lib), just bump to 0.9.0. |
| **`createInlineMarkdownSpec` uses shortcode syntax** | Low | It uses `{name attr="val"}` format, not `[[wikilink]]`. We still need our custom markdown-it plugin for parsing. Only `renderMarkdown` replaces our serialize function. |
| **Coordinated 7-package upgrade** | Medium | All `@tiptap/*` packages must be bumped together. Use exact versions. |
| **No immediate user-facing benefit** | N/A | Pure tech-debt reduction. No new features unlocked. |
## Design
### What changes
**Package upgrades (mechanical):**
```
@tiptap/core 2.27.2 → 3.22.x
@tiptap/react 2.27.2 → 3.22.x
@tiptap/starter-kit 2.27.2 → 3.22.x
@tiptap/extension-link 2.27.2 → 3.22.x
@tiptap/extension-placeholder 2.27.2 → 3.22.x
@tiptap/pm 2.27.2 → 3.22.x
@tiptap/suggestion 2.27.2 → 3.22.x
tiptap-markdown 0.8.10 → 0.9.0
```
**Wikilink extension update:**
v2 (current — `addStorage` workaround):
```typescript
addStorage() {
return {
markdown: {
serialize(state, node) {
state.write(`[[${node.attrs.label}]]`);
},
parse: {
setup(md) {
md.inline.ruler.after("emphasis", "wikilink", tokenizer);
md.renderer.rules.wikilink = renderer;
},
},
},
};
}
```
v3 (first-class API — investigate if supported by tiptap-markdown 0.9.0):
```typescript
// If tiptap-markdown 0.9.0 supports the new API:
renderMarkdown(node) {
return `[[${node.attrs.label}]]`;
}
parseMarkdown(token, h) {
return h.createNode("wikilink", { label: token.content });
}
// If not, addStorage still works — 0.9.0 maintains backward compat
```
### What does NOT change
- `useEditor()` API — identical in v3
- `editor.chain().focus().toggle*().run()` — identical
- `editor.commands.setContent()` — identical
- `editor.storage.*` — identical
- `editor.can()` — identical
- `EditorContent` component — identical
- Toolbar implementation — all formatting commands unchanged
- Source mode toggle — raw textarea, no TipTap involvement
### API compatibility audit
| API | v2 | v3 | Change needed |
|-----|----|----|---------------|
| `useEditor({ extensions, content, ... })` | Works | Works | None |
| `editor.storage.markdown.getMarkdown()` | Works | Works (tiptap-markdown 0.9.0) | None |
| `editor.commands.setContent(md)` | Works | Works | None |
| `Node.create({ addStorage })` | Works | Works | None (backward compat) |
| `@tiptap/suggestion` char: `[[` | Works | Works | None |
| `Markdown.configure({ html: false })` | Works | Works (0.9.0) | None |
| `immediatelyRender: false` | Works | Works | None |
## Trade-offs
**Do it now:** Clean up tech debt while the TipTap surface area is small (4 files, 2 custom extensions). The longer we wait, the more TipTap code accrues.
**Wait:** Zero user-facing benefit. Risk of subtle regressions in a well-working editor. tiptap-markdown 0.9.0 gets more production miles.
**Recommendation:** Wait until after obsidian-interop is merged and stable. Then do it as a focused 1-day task in a worktree.
## Acceptance Criteria
- [ ] All 7 `@tiptap/*` packages at v3.22.x, `tiptap-markdown` at 0.9.0
- [ ] Wikilink serialization round-trip works (existing test passes)
- [ ] Rich text toolbar: all 11 formatting commands work
- [ ] Source mode toggle preserves content
- [ ] Markdown viewer renders read-only content correctly
- [ ] Notes editor inline edit/save works
- [ ] Field card long-text edit works
- [ ] No console warnings about deprecated APIs
- [ ] Bundle size delta documented (should decrease or stay flat)
- [ ] `pnpm test && pnpm typecheck && pnpm build` pass
## Files
| File | Change |
|------|--------|
| `package.json` | Bump 8 packages |
| `features/entities/components/editor/wikilink-extension.ts` | Possibly simplify markdown spec if 0.9.0 supports new API |
| `features/entities/components/editor/wikilink-extension.test.ts` | Update if extension API changes |
| `components/ui/markdown-editor.tsx` | Verify storage access types |
| `components/ui/markdown-viewer.tsx` | Verify read-only rendering |
| `features/entities/components/notes-editor.tsx` | Verify inline editor |
| `features/blocks/components/field-card-block.tsx` | Verify field editor |
## Estimated Effort
- Package upgrades: 30 min
- Code updates (if any): 1 hour
- Testing all 4 editor instances: 2 hours
- Wikilink round-trip verification: 30 min
- Build + bundle size check: 30 min
- **Total: ~4-5 hours**