Skip to main content

Prerequisites

The editor requires React 18+ and a bundler that supports package exports (Vite, Next.js, webpack 5, etc.).

Install

Install the editor and its peer dependencies:
npm install @react-email/editor@experimental @tiptap/react @radix-ui/react-popover

Import CSS

The editor ships CSS for its UI components and a default theme. Import the styles you need:
// Required for bubble menu styling (covers text, link, button, and image menus)
import '@react-email/editor/styles/bubble-menu.css';

// Required for slash command menu
import '@react-email/editor/styles/slash-command.css';

// Default color theme
import '@react-email/editor/themes/default.css';
Shortcut: @react-email/editor/themes/default.css bundles all of the above CSS files into a single import. If you don’t need to cherry-pick styles, just import this one file:
import '@react-email/editor/themes/default.css';
If you prefer to keep your bundle lean, you can import only the CSS for the components you use instead of the bundled theme file.

Minimal editor

The simplest setup uses StarterKit with EditorProvider — no UI overlays, just a content-editable area with all core extensions (paragraphs, headings, lists, tables, code blocks, and more):
import { StarterKit } from '@react-email/editor/extensions';
import { EditorProvider } from '@tiptap/react';

const extensions = [StarterKit];

const content = {
  type: 'doc',
  content: [
    {
      type: 'paragraph',
      content: [
        {
          type: 'text',
          text: 'Start typing or edit this text.',
        },
      ],
    },
  ],
};

export function MyEditor() {
  return <EditorProvider extensions={extensions} content={content} />;
}

Adding a bubble menu

To add a floating formatting toolbar that appears when you select text, add BubbleMenu.Default as a child of EditorProvider:
import { StarterKit } from '@react-email/editor/extensions';
import { BubbleMenu } from '@react-email/editor/ui';
import { EditorProvider } from '@tiptap/react';
import '@react-email/editor/themes/default.css';

const extensions = [StarterKit];

const content = {
  type: 'doc',
  content: [
    {
      type: 'paragraph',
      content: [
        { type: 'text', text: 'Select this text to see the bubble menu. Try ' },
        { type: 'text', marks: [{ type: 'bold' }], text: 'bold' },
        { type: 'text', text: ', ' },
        { type: 'text', marks: [{ type: 'italic' }], text: 'italic' },
        { type: 'text', text: ', and other formatting options.' },
      ],
    },
  ],
};

export function MyEditor() {
  return (
    <EditorProvider extensions={extensions} content={content}>
      <BubbleMenu.Default />
    </EditorProvider>
  );
}
Select text in the editor to see the formatting toolbar with bold, italic, underline, alignment, and more.

Content format

The editor accepts content in two formats: TipTap JSON — A structured document tree:
{
  "type": "doc",
  "content": [
    {
      "type": "paragraph",
      "content": [
        { "type": "text", "text": "Hello world" }
      ]
    }
  ]
}
HTML string — Parsed automatically into the editor’s document model:
const content = `
  <h1>Welcome</h1>
  <p>This is a <a href="https://react.email">link</a>.</p>
`;

<EditorProvider extensions={extensions} content={content} />

Next steps

Bubble Menu

Add floating formatting toolbars on text selection.

Slash Commands

Insert content blocks with a command menu.

Email Theming

Apply visual themes to your email output.

Email Export

Convert editor content to email-ready HTML.