---
title: "Migrate from Draft.js to Tiptap"
description: "Learn how to migrate your existing Draft.js editor to Tiptap. Complete guide covering content migration, setup, and feature mapping."
canonical_url: "https://tiptap.dev/docs/guides/migrate-from-draftjs"
---

# Migrate from Draft.js to Tiptap

Learn how to migrate your existing Draft.js editor to Tiptap. Complete guide covering content migration, setup, and feature mapping.

Tiptap is a popular alternative to Draft.js and migrating from Draft.js to Tiptap is straightforward. This guide will help you transition from Draft.js's immutable state model to Tiptap's extension system.

## Content migration

### HTML content compatibility

Draft.js uses ContentState which needs to be converted to HTML for Tiptap:

```ts
// Convert Draft.js ContentState to HTML
import { convertFromRaw } from 'draft-js'
import { stateToHTML } from 'draft-js-export-html'

// If you have ContentState
const htmlContent = stateToHTML(contentState)

// If you have raw state (JSON)
const contentState = convertFromRaw(rawContentState)
const htmlContent = stateToHTML(contentState)

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

If you already have HTML output from Draft.js, you can use it directly:

```ts
// Your existing Draft.js HTML content
const existingContent = '<p>Hello <strong>world</strong>!</p>'

// 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](https://tiptap.dev/docs/editor/api/utilities/html.md) to convert HTML to JSON programmatically.

## Editor setup

### Installation

First, install Tiptap and its dependencies:

```bash
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](https://tiptap.dev/docs/editor/getting-started/install.md).

### Basic editor setup

Replace your Draft.js editor with Tiptap:

```tsx
// Draft.js (before)
import React, { useState } from 'react'
import { Editor, EditorState, RichUtils } from 'draft-js'

function MyDraftEditor() {
  const [editorState, setEditorState] = useState(EditorState.createEmpty())

  const handleKeyCommand = (command) => {
    const newState = RichUtils.handleKeyCommand(editorState, command)
    if (newState) {
      setEditorState(newState)
      return 'handled'
    }
    return 'not-handled'
  }

  return (
    <Editor
      editorState={editorState}
      onChange={setEditorState}
      handleKeyCommand={handleKeyCommand}
    />
  )
}

// Tiptap (after)
import { useEditor, EditorContent } from '@tiptap/react'
import StarterKit from '@tiptap/starter-kit'

function MyTiptapEditor() {
  const editor = useEditor({
    extensions: [StarterKit],
    content: '<p>Hello World!</p>',
  })

  return <EditorContent editor={editor} />
}
```

## Extensions

### Understanding Tiptap's extension system

Tiptap uses a modular extension system that resembles Draft.js's entity and decorator system. Each feature is an independent extension with clear APIs.

The [StarterKit](https://tiptap.dev/docs/editor/extensions/functionality/starterkit.md) 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](https://tiptap.dev/docs/editor/extensions/overview.md), or [create your own](https://tiptap.dev/docs/editor/extensions/custom-extensions.md) to support custom functionality and HTML elements.

### Common Draft.js feature equivalents

| Draft.js Feature       | Tiptap Extension          | Notes                  |
| ---------------------- | ------------------------- | ---------------------- |
| Bold inline style      | `Bold`                    | Included in StarterKit |
| Italic inline style    | `Italic`                  | Included in StarterKit |
| Underline inline style | `Underline`               | Included in StarterKit |
| Code inline style      | `Code`                    | Included in StarterKit |
| Link entity            | `Link`                    | Included in StarterKit |
| Image entity           | `Image`                   | Available separately   |
| Header block           | `Heading`                 | Included in StarterKit |
| Blockquote block       | `Blockquote`              | Included in StarterKit |
| Code block             | `CodeBlock`               | Included in StarterKit |
| Unordered list         | `BulletList`, `ListItem`  | Included in StarterKit |
| Ordered list           | `OrderedList`, `ListItem` | Included in StarterKit |

### Extension configuration

```ts
import { useEditor } from '@tiptap/react'
import StarterKit from '@tiptap/starter-kit'
import Image from '@tiptap/extension-image'
import { Color } from '@tiptap/extension-color'
import TextStyle from '@tiptap/extension-text-style'
import Highlight from '@tiptap/extension-highlight'

const editor = useEditor({
  extensions: [
    StarterKit,
    Image.configure({
      inline: true,
      allowBase64: true,
    }),
    TextStyle,
    Color.configure({
      types: [TextStyle.name],
    }),
    Highlight.configure({
      multicolor: true,
    }),
  ],
})
```

### Custom extensions

For Draft.js custom entities or decorators, create custom Tiptap extensions. See our [custom extensions guide](https://tiptap.dev/docs/editor/extensions/custom-extensions.md) for detailed instructions.

## UI implementation

### Toolbar implementation

Draft.js's RichUtils-based toolbar translates to Tiptap UI components:

```tsx
// Draft.js toolbar (before)
import { RichUtils } from 'draft-js'

function DraftToolbar({ editorState, onChange }) {
  const toggleInlineStyle = (style) => {
    onChange(RichUtils.toggleInlineStyle(editorState, style))
  }

  const toggleBlockType = (blockType) => {
    onChange(RichUtils.toggleBlockType(editorState, blockType))
  }

  return (
    <div>
      <button onClick={() => toggleInlineStyle('BOLD')}>Bold</button>
      <button onClick={() => toggleInlineStyle('ITALIC')}>Italic</button>
      <button onClick={() => toggleBlockType('header-one')}>H1</button>
    </div>
  )
}

// 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().toggleHeading({ level: 1 }).run()}
        className={editor.isActive('heading', { level: 1 }) ? 'active' : ''}
      >
        H1
      </button>
    </div>
  )
}
```

### Pre-built UI components

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

- Explore our [UI components](https://tiptap.dev/docs/ui-components/getting-started/overview.md) for ready-to-use components
- Check out practical examples in our [default text editor example](https://tiptap.dev/docs/examples/basics/default-text-editor.md)

### Inline toolbar

Create an inline toolbar similar to Draft.js's inline styling:

```tsx
import { BubbleMenu } from '@tiptap/react'

function MyEditor() {
  const editor = useEditor({
    extensions: [StarterKit],
  })

  return (
    <>
      <EditorContent editor={editor} />
      <BubbleMenu editor={editor}>
        <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>
      </BubbleMenu>
    </>
  )
}
```

### Entity replacement (node views)

Draft.js entities can be replaced with Tiptap's [Node Views](https://tiptap.dev/docs/editor/extensions/custom-extensions/node-views.md):

```tsx
// Draft.js entity (before)
const LinkEntity = (props) => {
  const { url } = props.contentState.getEntity(props.entityKey).getData()
  return <a href={url}>{props.children}</a>
}

// Tiptap Node View (after)
import { Node } from '@tiptap/core'
import { ReactNodeViewRenderer } from '@tiptap/react'

const LinkComponent = ({ node }) => {
  return <a href={node.attrs.href}>{node.textContent}</a>
}

const CustomLink = Node.create({
  name: 'customLink',

  addNodeView() {
    return ReactNodeViewRenderer(LinkComponent)
  },
})
```

## Migration checklist

Install Tiptap packages
Convert Draft.js ContentState to HTML
Replace Draft.js editor with Tiptap setup
Map Draft.js inline styles to Tiptap marks
Map Draft.js block types to Tiptap nodes
Migrate entities to [Node Views](https://tiptap.dev/docs/editor/extensions/custom-extensions/node-views.md) or extensions
Migrate toolbar components to Tiptap UI
Test content compatibility
Convert existing content to JSON format (recommended)
Implement custom extensions for any missing functionality
Update event handlers and key commands
Test inline toolbar functionality
Verify link and image handling
Test list functionality

## Next steps

- Explore the [extension overview](https://tiptap.dev/docs/editor/extensions/overview.md) to discover all available extensions
- Learn about [custom extensions](https://tiptap.dev/docs/editor/extensions/custom-extensions.md) for advanced customization
- Check out our [examples](https://tiptap.dev/docs/examples.md) for implementation inspiration
- Review the [performance guide](https://tiptap.dev/docs/guides/performance.md) for optimization tips
