# What Technology Powers the @plane/editor Package in Plane?

> Discover the core technologies behind the @plane/editor package in Plane. Built with TipTap, Yjs, and Floating UI, it delivers a powerful real-time rich-text editing experience.

- Repository: [Plane/plane](https://github.com/makeplane/plane)
- Tags: internals
- Published: 2026-08-22

---

**The @plane/editor package is built on TipTap (a headless ProseMirror wrapper), Yjs for real-time collaboration, and Floating UI for positioning, creating a rich-text editing engine used throughout the Plane project management platform.**

The `@plane/editor` package serves as the rich-text editing backbone for Plane, an open-source project management platform. Understanding what technology powers the @plane/editor package reveals a modern architecture that combines proven editing frameworks with Conflict-free Replicated Data Types (CRDTs) for seamless multi-user collaboration.

## Core Editing Engine: TipTap and ProseMirror

The foundation of `@plane/editor` relies on **TipTap**, a headless editor framework that wraps the robust **ProseMirror** library. This combination provides the document model, schema validation, and command infrastructure necessary for complex rich-text operations.

### TipTap Core and ProseMirror Foundation

At the heart of the editor is **`@tiptap/core`** (declared in [`packages/editor/package.json`](https://github.com/makeplane/plane/blob/main/packages/editor/package.json) at line 46), which supplies the low-level ProseMirror document model and schema system. The editor leverages TipTap's extension ecosystem—including `@tiptap/extension-heading`, `@tiptap/extension-bold`, `@tiptap/extension-list`, and table extensions—to assemble a comprehensive feature set. These extensions map directly to ProseMirror's `RawCommands` interface, allowing the editor to execute document transformations programmatically.

### React Integration Layer

The package connects TipTap's imperative API to React's component model through **`@tiptap/react`** (line 65). This dependency exposes the `useEditor` hook and `EditorContent` component, enabling React components to instantiate and render the ProseMirror view. The editor maintains a Ref API that bridges React's declarative patterns with TipTap's command-based architecture.

## Real-Time Collaboration Infrastructure

Beyond single-user editing, the package implements collaborative capabilities using a **Yjs** and **Hocuspocus** stack.

**`yjs`** (line 84) provides the CRDT-based state management that allows multiple users to edit the same document simultaneously without conflicts. The **`@hocuspocus/provider`** (line 39) layer handles WebSocket server/client communication, synchronizing Yjs document updates across connected clients in real time. This architecture enables features like live cursors and concurrent text editing in Plane's collaborative documents.

## UI Positioning and Utility Libraries

The editor's interface components rely on **Floating UI** (`@floating-ui/react` and `@floating-ui/dom` at line 36) to calculate positioning for toolbars, pop-overs, and context menus relative to the cursor or selection. Additional utility libraries declared in [`packages/editor/package.json`](https://github.com/makeplane/plane/blob/main/packages/editor/package.json) (lines 69-78) include:

- **`lodash-es`** for helper functions
- **`linkifyjs`** for automatic link detection
- **[`highlight.js`](https://github.com/makeplane/plane/blob/main/highlight.js)** and **`lowlight`** for syntax highlighting in code blocks
- **[`tippy.js`](https://github.com/makeplane/plane/blob/main/tippy.js)** for tooltip management

## Editor Components and API Architecture

The package exposes two primary editor variants and a comprehensive Ref-based API for programmatic control.

### RichTextEditorWithRef and LiteTextEditorWithRef

The main entry points are implemented in distinct component files:

- **`RichTextEditorWithRef`** ([`packages/editor/src/core/components/editors/rich-text/editor.tsx`](https://github.com/makeplane/plane/blob/main/packages/editor/src/core/components/editors/rich-text/editor.tsx)): Creates a full-featured TipTap instance with all extensions enabled, including tables, embeds, and collaborative features.
- **`LiteTextEditorWithRef** ([`packages/editor/src/core/components/editors/lite-text/editor.tsx`](https://github.com/makeplane/plane/blob/main/packages/editor/src/core/components/editors/lite-text/editor.tsx)): A lighter variant that disables heavy extensions while maintaining the same TipTap core foundation.

Both components wire the Yjs provider when collaborative configuration is present and render the ProseMirror view through the React integration layer.

### CoreEditorRefApi Interface

The public API is defined in [`packages/editor/src/core/types/editor.ts`](https://github.com/makeplane/plane/blob/main/packages/editor/src/core/types/editor.ts) through the **`CoreEditorRefApi`** type, which exposes methods for controlling the editor instance:

```ts
// Defined in packages/editor/src/core/types/editor.ts
export type CoreEditorRefApi = {
  blur: () => void;
  focus: (args: Parameters<RawCommands["focus"]>[0]) => void;
  executeMenuItemCommand: <T extends TEditorCommands>(props: TCommandWithPropsWithItemKey<T>) => void;
  emitRealTimeUpdate: (action: TDocumentEventsServer) => void;
  // …other methods
};

```

This interface allows parent components to execute commands, trigger real-time updates, and manipulate focus without accessing the underlying TipTap instance directly. Plane-specific extensions to these types are maintained in [`packages/editor/src/ce/types/editor-extended.ts`](https://github.com/makeplane/plane/blob/main/packages/editor/src/ce/types/editor-extended.ts).

## Implementation Examples

### Creating a Rich-Text Editor

```tsx
import { RichTextEditorWithRef } from '@plane/editor';
import type { IRichTextEditorProps, EditorRefApi } from '@plane/editor';

function MyPage() {
  const editorRef = React.useRef<EditorRefApi>(null);

  const props: IRichTextEditorProps = {
    id: 'my-page',
    initialValue: '',
    editable: true,
    fileHandler: async (file) => {/* upload logic */},
    mentionHandler: {/* mention logic */},
    getEditorMetaData: (html) => {/* meta parsing */},
    // …other required props
  };

  return <RichTextEditorWithRef {...props} forwardedRef={editorRef} />;
}

```

### Using the Ref API

```ts
// Assuming the ref from the previous example
if (editorRef.current) {
  // Insert a table at the current cursor position
  editorRef.current.executeMenuItemCommand({ itemKey: 'table' });

  // Get the current Markdown representation
  const markdown = editorRef.current.getMarkDown();

  // Trigger a real-time update (e.g., after a custom embed)
  editorRef.current.emitRealTimeUpdate({
    type: 'embed',
    payload: { url: 'https://example.com' },
  });
}

```

### Enabling Collaboration

```tsx
import { CollaborativeDocumentEditorWithRef } from '@plane/editor';
import type { ICollaborativeDocumentEditorProps } from '@plane/editor';

function CollaborativePage() {
  const collaborativeProps: ICollaborativeDocumentEditorProps = {
    id: 'doc-123',
    realtimeConfig: { provider: 'hocuspocus', doc: 'doc-123' },
    user: { id: 'user-1', name: 'Alice' },
    // …other required props
  };

  return <CollaborativeDocumentEditorWithRef {...collaborativeProps} />;
}

```

## Summary

- **TipTap and ProseMirror** provide the foundational document model and editing engine in `@plane/editor`, with core dependencies declared in [`packages/editor/package.json`](https://github.com/makeplane/plane/blob/main/packages/editor/package.json).
- **Yjs and Hocuspocus** enable real-time collaborative editing through CRDT-based state synchronization and WebSocket transport.
- **Floating UI** powers the positioning of contextual toolbars and menus relative to text selections.
- **RichTextEditorWithRef** and **LiteTextEditorWithRef** offer full-featured and lightweight editing experiences respectively, both exposing the `CoreEditorRefApi` for programmatic control.
- The editor architecture supports Plane-specific extensions through TypeScript definitions in the `ce` (community edition) directory structure.

## Frequently Asked Questions

### What is the core technology behind @plane/editor?

The package is built on **TipTap**, a headless framework that wraps **ProseMirror**. According to the source code in [`packages/editor/package.json`](https://github.com/makeplane/plane/blob/main/packages/editor/package.json), the editor imports `@tiptap/core` to handle the document schema and `@tiptap/react` for React integration, providing a modern abstraction over ProseMirror's imperative API.

### How does @plane/editor handle real-time collaboration?

Real-time collaboration is implemented using **Yjs** for Conflict-free Replicated Data Types (CRDTs) and **Hocuspocus** as the WebSocket provider. As configured in [`packages/editor/package.json`](https://github.com/makeplane/plane/blob/main/packages/editor/package.json), Yjs manages the shared document state while Hocuspocus synchronizes updates between clients, enabling simultaneous multi-user editing without locks or conflicts.

### What is the difference between RichTextEditorWithRef and LiteTextEditorWithRef?

**RichTextEditorWithRef** ([`packages/editor/src/core/components/editors/rich-text/editor.tsx`](https://github.com/makeplane/plane/blob/main/packages/editor/src/core/components/editors/rich-text/editor.tsx)) instantiates a TipTap editor with all heavy extensions enabled, including tables, embeds, and full collaborative features. **LiteTextEditorWithRef** ([`packages/editor/src/core/components/editors/lite-text/editor.tsx`](https://github.com/makeplane/plane/blob/main/packages/editor/src/core/components/editors/lite-text/editor.tsx)) uses the same TipTap core but disables resource-intensive extensions, offering a streamlined editing experience for simpler text inputs.

### How can I programmatically execute commands in the editor?

Access the editor's imperative API through the React ref using **`CoreEditorRefApi`**. The `executeMenuItemCommand` method accepts a command key (such as `'table'` or `'bold'`) and executes the corresponding TipTap command. You can also trigger real-time updates via `emitRealTimeUpdate` or retrieve Markdown content through `getMarkDown()` as defined in [`packages/editor/src/core/types/editor.ts`](https://github.com/makeplane/plane/blob/main/packages/editor/src/core/types/editor.ts).