Tiptap Editor 3.0 Beta is out. Start here

Migrate from CKEditor 4 to Tiptap

Editor

Migrating from CKEditor 4 to Tiptap is straightforward and offers significant benefits in terms of modern architecture and flexibility. This guide will walk you through the migration process step by step.

Content migration

HTML content compatibility

CKEditor 4 stores content as HTML, which makes migration to Tiptap seamless. Tiptap can directly use HTML content without any conversion:

// Your existing CKEditor 4 content
const existingContent =
  '<p>Hello <strong>world</strong>!</p><ul><li>Item 1</li><li>Item 2</li></ul>'

// Use directly in Tiptap
const editor = new Editor({
  content: existingContent,
  extensions: [StarterKit],
})

While HTML works perfectly, we recommend converting it to Tiptap's JSON format for better performance and readability. For batch conversion of existing content, use the HTML utility to convert HTML to JSON programmatically.

Editor setup

Installation

First, install Tiptap and its dependencies:

npm install @tiptap/core @tiptap/starter-kit

Tiptap supports all modern frontend UI frameworks like React and Vue. Follow the framework-specific installation instructions in our installation guides.

Basic editor setup

Replace your CKEditor 4 initialization with Tiptap:

// CKEditor 4 (before)
CKEDITOR.replace('editor', {
  toolbar: [
    { name: 'basicstyles', items: ['Bold', 'Italic', 'Underline'] },
    { name: 'paragraph', items: ['NumberedList', 'BulletedList'] },
    { name: 'links', items: ['Link', 'Unlink'] },
  ],
  height: 300,
})

// Tiptap (after)
import { Editor } from '@tiptap/core'
import StarterKit from '@tiptap/starter-kit'

const editor = new Editor({
  element: document.querySelector('#editor'),
  extensions: [StarterKit],
  content: '<p>Hello World!</p>',
})

Extensions

Understanding Tiptap's extension system

Tiptap uses a modular extension system that replaces CKEditor 4's plugin architecture. Each feature is an independent extension that can be configured and customized.

The StarterKit is a bundle of all the basic extensions, and you can add or remove other extensions as needed.

Explore all available extensions in our extensions guide, or create your own to support custom functionality and HTML elements.

Common CKEditor 4 plugin equivalents

CKEditor 4 PluginTiptap ExtensionNotes
basicstylesBold, Italic, UnderlineIncluded in StarterKit
listBulletList, OrderedList, ListItemIncluded in StarterKit
linkLinkIncluded in StarterKit
imageImageAvailable separately
tableTableAvailable separately
sourceareaCodeBlockIncluded in StarterKit
formatHeadingIncluded in StarterKit
blockquoteBlockquoteIncluded in StarterKit
justifyTextAlignAvailable separately
colorbuttonTextStyle, ColorAvailable separately
fontTextStyle, FontSizeAvailable separately
indentlistBuilt into list extensionsIncluded in StarterKit
horizontalruleHorizontalRuleIncluded in StarterKit

Extension configuration

import { Editor } from '@tiptap/core'
import StarterKit from '@tiptap/starter-kit'
import Image from '@tiptap/extension-image'
import Table from '@tiptap/extension-table'
import TableRow from '@tiptap/extension-table-row'
import TableHeader from '@tiptap/extension-table-header'
import TableCell from '@tiptap/extension-table-cell'
import TextAlign from '@tiptap/extension-text-align'
import Underline from '@tiptap/extension-underline'

const editor = new Editor({
  extensions: [
    StarterKit,
    Underline,
    Image.configure({
      inline: true,
      allowBase64: true,
    }),
    Table.configure({
      resizable: true,
    }),
    TableRow,
    TableHeader,
    TableCell,
    TextAlign.configure({
      types: ['heading', 'paragraph'],
    }),
  ],
})

Custom extensions

For CKEditor 4 custom plugins, create custom Tiptap extensions. See our custom extensions guide for detailed instructions.

UI implementation

Toolbar implementation

CKEditor 4's toolbar configuration translates to custom UI components in Tiptap:

// CKEditor 4 toolbar config
toolbar: [
  { name: 'basicstyles', items: ['Bold', 'Italic', 'Underline'] },
  { name: 'paragraph', items: ['NumberedList', 'BulletedList'] },
  { name: 'links', items: ['Link', 'Unlink'] },
]

// Tiptap equivalent (React example)
function Toolbar({ editor }) {
  if (!editor) return null

  return (
    <div className="toolbar">
      <button
        onClick={() => editor.chain().focus().toggleBold().run()}
        className={editor.isActive('bold') ? 'active' : ''}
      >
        Bold
      </button>

      <button
        onClick={() => editor.chain().focus().toggleItalic().run()}
        className={editor.isActive('italic') ? 'active' : ''}
      >
        Italic
      </button>

      <button
        onClick={() => editor.chain().focus().toggleUnderline().run()}
        className={editor.isActive('underline') ? 'active' : ''}
      >
        Underline
      </button>

      <button
        onClick={() => editor.chain().focus().toggleBulletList().run()}
        className={editor.isActive('bulletList') ? 'active' : ''}
      >
        Bullet List
      </button>

      <button
        onClick={() => editor.chain().focus().toggleOrderedList().run()}
        className={editor.isActive('orderedList') ? 'active' : ''}
      >
        Numbered List
      </button>

      <button
        onClick={() => {
          const url = window.prompt('URL')
          if (url) {
            editor.chain().focus().extendMarkRange('link').setLink({ href: url }).run()
          }
        }}
        className={editor.isActive('link') ? 'active' : ''}
      >
        Link
      </button>

      <button
        onClick={() => editor.chain().focus().unsetLink().run()}
        disabled={!editor.isActive('link')}
      >
        Unlink
      </button>
    </div>
  )
}

Pre-built UI components

For faster development, consider using Tiptap's pre-built UI components:

Migration checklist

  1. Install Tiptap packages
  2. Replace CKEditor 4 initialization with Tiptap setup
  3. Map CKEditor 4 plugins to Tiptap extensions
  4. Migrate toolbar configuration to custom UI components
  5. Test content compatibility
  6. Convert existing content to JSON format (recommended)
  7. Implement custom extensions for any missing functionality
  8. Update event handlers and API calls
  9. Test image upload and handling if used
  10. Verify table functionality if used
  11. Test user interactions

Next steps