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

# Migrate from Lexical to Tiptap

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

Replace your Lexical editor with a better alternative like Tiptap. Migrating from Lexical to Tiptap is straightforward. This guide will help you transition from Lexical's node-based architecture to Tiptap's extension system.

## Content migration

### HTML content compatibility

Lexical uses its own JSON structure that needs to be converted for Tiptap. You can serialize Lexical content to HTML:

```ts
// Convert Lexical JSON to HTML
import { $generateHtmlFromNodes } from '@lexical/html'
import { $getRoot } from 'lexical'

// Assuming you have a Lexical editor instance
const htmlContent = editor.update(() => {
  const root = $getRoot()
  return $generateHtmlFromNodes(editor, root)
})

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

If you already have HTML output from Lexical, you can use it directly:

```ts
// Your existing Lexical 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 Lexical editor with Tiptap:

```tsx
// Lexical (before)
import { createEditor } from 'lexical'
import { LexicalComposer } from '@lexical/react/LexicalComposer'
import { RichTextPlugin } from '@lexical/react/LexicalRichTextPlugin'
import { ContentEditable } from '@lexical/react/LexicalContentEditable'

const initialConfig = {
  namespace: 'MyEditor',
  theme: {},
  onError: console.error,
}

function MyLexicalEditor() {
  return (
    <LexicalComposer initialConfig={initialConfig}>
      <RichTextPlugin
        contentEditable={<ContentEditable />}
        placeholder={<div>Enter some text...</div>}
      />
    </LexicalComposer>
  )
}

// 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 resembles Lexical's node and plugin architecture. 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 Lexical plugin equivalents

| Lexical Plugin/Node  | Tiptap Extension                        | Notes                  |
| -------------------- | --------------------------------------- | ---------------------- |
| `@lexical/rich-text` | `Bold`, `Italic`                        | Included in StarterKit |
| `@lexical/link`      | `Link`                                  | Included in StarterKit |
| `@lexical/list`      | `BulletList`, `OrderedList`, `ListItem` | Included in StarterKit |
| `@lexical/code`      | `Code`, `CodeBlock`                     | Included in StarterKit |
| `@lexical/table`     | `Table`                                 | Available separately   |
| `HeadingNode`        | `Heading`                               | Included in StarterKit |
| `QuoteNode`          | `Blockquote`                            | Included in StarterKit |
| `ImageNode`          | `Image`                                 | Available separately   |
| `@lexical/history`   | `History`                               | Included in StarterKit |
| `@lexical/text`      | `TextStyle`, `Color`                    | Available separately   |

### Extension configuration

```ts
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 { Color } from '@tiptap/extension-color'
import TextStyle from '@tiptap/extension-text-style'

const editor = new Editor({
  extensions: [
    StarterKit,
    Image.configure({
      inline: true,
      allowBase64: true,
    }),
    Table.configure({
      resizable: true,
    }),
    TableRow,
    TableHeader,
    TableCell,
    TextStyle,
    Color.configure({
      types: [TextStyle.name],
    }),
  ],
})
```

### Custom extensions

For Lexical custom nodes or plugins, 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

Lexical's toolbar plugins translate to custom UI components in Tiptap:

```tsx
// Lexical toolbar (before)
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'
import { FORMAT_TEXT_COMMAND } from 'lexical'

function ToolbarPlugin() {
  const [editor] = useLexicalComposerContext()

  return (
    <div>
      <button
        onClick={() => {
          editor.dispatchCommand(FORMAT_TEXT_COMMAND, 'bold')
        }}
      >
        Bold
      </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().toggleUnderline().run()}
        className={editor.isActive('underline') ? 'active' : ''}
      >
        Underline
      </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)

### Floating toolbar

Replicate Lexical's floating toolbar using Tiptap's BubbleMenu:

```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={() => {
            const url = window.prompt('URL')
            if (url) {
              editor.chain().focus().extendMarkRange('link').setLink({ href: url }).run()
            }
          }}
          className={editor.isActive('link') ? 'active' : ''}
        >
          Link
        </button>
      </BubbleMenu>
    </>
  )
}
```

### Node views (custom nodes)

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

```tsx
// Lexical custom node (before)
class ImageNode extends DecoratorNode {
  static getType() {
    return 'image'
  }

  createDOM() {
    const img = document.createElement('img')
    img.src = this.__src
    return img
  }
}

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

const ImageComponent = ({ node }) => {
  return <img src={node.attrs.src} />
}

const CustomImage = Node.create({
  name: 'customImage',

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

## Migration checklist

Install Tiptap packages
Convert Lexical JSON content to HTML
Replace Lexical editor initialization with Tiptap setup
Map Lexical plugins to Tiptap extensions
Migrate custom nodes to [Node Views](https://tiptap.dev/docs/editor/extensions/custom-extensions/node-views.md)
Migrate toolbar plugins to Tiptap UI components
Test content compatibility
Convert existing content to JSON format (recommended)
Implement custom extensions for any missing functionality
Update event handlers and command dispatching
Test floating toolbar functionality
Verify table functionality if used
Test history (undo/redo) 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
