How to upgrade Tiptap v2 to v3
Tiptap v3 is a major update with breaking changes. This guide will help you upgrade your Tiptap v2 project to version 3.
Breaking Changes
Package Changes
- UMD builds have been removed (now using tsup)
Some packages may have been removed or renamed, so you may need to update your imports and dependencies. Here are some common changes:
Table packages - import Table from '@tiptap/extension-table' - import TableRow from '@tiptap/extension-table-row' - import TableCell from '@tiptap/extension-table-cell' - import TableHeader from '@tiptap/extension-table-header' + import { Table, TableRow, TableCell, TableHeader } from '@tiptap/extension-table'  List packages - import BulletList from '@tiptap/extension-bullet-list' - import OrderedList from '@tiptap/extension-ordered-list' - import ListItem from '@tiptap/extension-list-item' - import ListKeymap from '@tiptap/extension-list-keymap' - import TaskList from '@tiptap/extension-task-list' - import TaskItem from '@tiptap/extension-task-item' + import { BulletList, OrderedList, ListItem, ListKeymap, TaskList, TaskItem } from '@tiptap/extension-list'  Extensions - import Focus from '@tiptap/extension-focus' - import Placeholder from '@tiptap/extension-placeholder' - import History from '@tiptap/extension-history' - import Dropcursor from '@tiptap/extension-dropcursor' - import Gapcursor from '@tiptap/extension-gapcursor' - import CharacterCount from '@tiptap/extension-character-count' + import { Focus, Placeholder, UndoRedo, Dropcursor, Gapcursor, CharacterCount } from '@tiptap/extensions'  CollaborationCursor - import CollaborationCursor from '@tiptap/extension-collaboration-cursor' + import CollaborationCaret from '@tiptap/extension-collaboration-caret'  Collaboration History - import CollaborationHistory from '@tiptap-pro/extension-collaboration-history' + import Snapshot from '@tiptap-pro/extension-snapshot'  React Menus - import { BubbleMenu, FloatingMenu } from '@tiptap/react' + import { BubbleMenu, FloatingMenu } from '@tiptap/react/menus'  Vue 3 Menus - import { BubbleMenu, FloatingMenu } from '@tiptap/vue-3' + import { BubbleMenu, FloatingMenu } from '@tiptap/vue-3/menus'  Vue 2 Menus - import { BubbleMenu, FloatingMenu } from '@tiptap/vue-2' + import { BubbleMenu, FloatingMenu } from '@tiptap/vue-2/menus'Menu Systems
Tippy.js has been replaced with Floating UI for all floating elements. This affects:
- @tiptap/extension-bubble-menu
- @tiptap/extension-drag-handle
- @tiptap/extension-drag-handle-react
- @tiptap/extension-drag-handle-vue-2
- @tiptap/extension-drag-handle-vue-3
- @tiptap/extension-floating-menu
- @tiptap/extension-mention
- @tiptap/suggestion
Example migration:
// Before import { BubbleMenu } from '@tiptap/react'  const menu = <BubbleMenu tippyOptions={{ duration: 100 }}>{/* menu content */}</BubbleMenu>  // After import { BubbleMenu } from '@tiptap/react/menus' import { offset } from '@floating-ui/dom' const menu = (  <BubbleMenu  options={{  offset: 6,  placement: 'top',  }}  >  {/* menu content */}  </BubbleMenu> )- New required dependency: @floating-ui/dom. Install it with:
npm install @floating-ui/dom@^1.6.0Make sure to uninstall tippy.js if you were using it, as it is no longer needed.
npm uninstall tippy.jsAPI Changes Text Style Updates
- mergeNestedSpanStylesnow defaults to- true
- New text style extensions added: - font-size
- background-color
- line-height
 
- TextStyleKitAPI available for configuring multiple extensions
You can now use the new TextStyleKit for easier configuration:
import { TextStyleKit } from '@tiptap/extension-text-style'  new Editor({  extensions: [  TextStyleKit.configure({  backgroundColor: {  types: ['textStyle'],  },  color: {  types: ['textStyle'],  },  fontFamily: {  types: ['textStyle'],  },  fontSize: {  types: ['textStyle'],  },  lineHeight: {  types: ['textStyle'],  },  }),  ], })Introducing shouldRerenderOnTransaction 
 The @tiptap/react Editor configuration now includes shouldRerenderOnTransaction, controlling component rerendering.
Previously (pre-3.0.0), the Editor rerendered on every transaction-induced state update, facilitating continuous editor object tracking but potentially impacting rendering performance.
shouldRerenderOnTransaction is disabled by default. Enable it by setting shouldRerenderOnTransaction: true in the editor configuration.
Post-upgrade, UI elements relying on the Editor's state might become unresponsive. Solutions include disabling the option (potential performance implications) or implementing manual state tracking, as demonstrated:
function MyEditor() {  const [selection, setSelection] = useState({ from: 0, to: 0 });   const editor = useEditor({  // Editor configuration  onTransaction({ transaction }) {  setSelection({  from: transaction.selection.from,  to: transaction.selection.to,  });  },  }); }You can also use useEditorState to extract either the whole state or select specific values to extract.
const { currentSelection } = useEditorState({  editor,  selector: (snapshot) => {  return { currentSelection: snapshot.editor.state.selection }  }, })This allows explicit state extraction and management for dependent UI logic.
Command Changes
- clearContentand- setContentnow emit updates by default
- setContentsignature changed to (content, options)
- insertContentbehavior modified to prevent splitting text nodes at the beginning
NodeView Changes
The getPos function in NodeViewRendererProps can now return undefined. Update your code to handle this case:
// Before const pos = nodeViewProps.getPos()  // After const pos = nodeViewProps.getPos() if (pos !== undefined) {  // use pos }Removed Features
- editor.getCharacterCount()method has been removed
- considerAnyAsEmptyoption removed from placeholder extension
New Features
Extensions Package
The new @tiptap/extensions package combines multiple utility extensions:
This will automatically update the imports in your project.
Example migration:
- import CharacterCount from '@tiptap/extension-character-count' + import { CharacterCount } from '@tiptap/extensions'Server-Side Rendering
Improved SSR support with the ability to run the editor on the server-side without rendering:
const editor = new Editor({  element: null, // opt-in to SSR  content: {  type: 'doc',  content: [  /* ... */  ],  },  extensions: [  /* ... */  ], })Mark Views
Adds support for mark views, which allow you to render custom views for marks within the editor. This is useful for rendering custom UI for marks, like a color picker for a text color mark or a link editor for a link mark.
Including support for React and Vue 3 frameworks
// Plain JS import { Mark } from '@tiptap/core'  Mark.create({  // Other options...  addMarkView() {  return ({ mark, HTMLAttributes }) => {  const dom = document.createElement('b')  const contentDOM = document.createElement('span')   dom.appendChild(contentDOM)   return {  dom,  contentDOM,  }  }  }, })  // React import { Mark } from '@tiptap/core' import { ReactMarkViewRenderer } from '@tiptap/react'  Mark.create({  // ... other options  addMarkView() {  return ReactMarkViewRenderer(YourComponent)  }, })  // Vue 3 import { Mark } from '@tiptap/core' import { VueMarkViewRenderer } from '@tiptap/vue-3'  Mark.create({  addMarkView() {  return VueMarkViewRenderer(Component)  }, })Other Improvements
- New delete event tracking
- HTML parsing now uses happy-dom-without-node
- New node/mark attribute validation support
- Performance improvements for transaction handling
StarterKit Updates
StarterKit now includes these extensions by default:
If you've installed these separately, you can remove them:
- import Link from '@tiptap/extension-link' - import ListKeymap from '@tiptap/extension-list-keymap' - import Underline from '@tiptap/extension-underline'Also make sure to update disabled extension names in your StarterKit configuration if you were using them:
const editor = new Editor({  extensions: [  StarterKit.configure({ - history: false, // disable history + undoRedo: false // disable undo/redo (previously history)  })  ] })Migration Steps
-  Update Dependencies - Remove UMD-dependent code
- Install @floating-ui/dom(for bubble & floating menus)
- Update Tiptap packages to v3
 
-  Update Menu Implementations - Replace tippyOptionswith Floating UI options
- Update menu imports to use /menussuffix
 
- Replace 
-  Review NodeView Usage - Add checks for undefinedgetPos
 
- Add checks for 
-  Update Extensions - Migrate to @tiptap/extensionswhere applicable
- Remove redundant StarterKitextensions
- Update text style configurations
 
- Migrate to 
-  Review Command Usage - Update setContentcalls to use new signature
- Check clearContentbehavior with default updates
 
- Update