facebook / facebook/lexical

Feature: Scaling Lexical for large documents using chunked multi-editor architecture

Open
#8,743 22 comments 0 reactions 0 assignees View on GitHub
enhancement
Dominant language
TypeScript
Stars
23.9k
Forks
2.2k
Avg merge
1d 16h
Merged PRs (30d)
61

Description

## Description
I’m building a large document editor (Word/Google Docs-like) using Lexical.

Problem

I need to support:

~300–1000 page documents
lossless import/export (HTML/structured docs)
smooth editing on low-end machines

A single Lexical editor becomes heavy at this scale due to large EditorState and DOM size.

Proposed architecture (summary)

I’m considering:

A canonical document model as source of truth
Chunk engine to split document into block-based units
Viewport-based virtualization
Multiple LexicalComposer instances mounted only for visible chunks
Separate layout engine for page view rendering

### Full design reference:

---

**Word-Class Document Editor Architecture**

This document describes the architecture of a scalable, Word-class document editor designed for large documents, lossless imports, and high-performance editing on low-end machines.

---

**1. Core Principle**

> **The Document Model is the only source of truth.**

Everything else in the system is a projection:

* Lexical ? editing layer
* Chunk Engine ? performance partitioning
* Layout Engine ? page/web rendering
* UI ? visual representation

No other layer owns canonical data.

**2. High-Level Architecture**

Document Model (Source of Truth)
?
Chunk Engine (Storage Partitioning)
?
Viewport Virtualization (Performance Control)
?
Mounted Lexical Editors (Editing Runtime)
?
Layout Engine (Page/Web Rendering)
?
UI Renderer

---
3. Document Model (Core Layer)

Purpose

The Document Model is the canonical representation of all content.

Structure

Syntax:

Document {
blocks: Block[]
}

Block {
id: string
type: "paragraph" | "heading" | "table"
text: string
styles: StyleSpan[]
}

**Responsibilities**

* Store all document content
* Maintain stable IDs
* Track structure and formatting
* Remain independent of UI and rendering

**Rules**

* No page information
* No chunk information
* No DOM / Lexical dependency

# 4. Chunk Engine (Storage Layer)

## Purpose

The Chunk Engine divides large documents into manageable units for performance optimization.

## Structure

syntax
Chunk {
id: string
blockIds: string[]
dirty: boolean
version: number
}

## Responsibilities

* Partition document into chunks (e.g., 50–200 blocks per chunk)
* Track dirty state for updates
* Enable lazy loading and unloading
* Improve performance for large documents

## Rules

* NOT related to pages
* NOT related to layout
* NOT tied to Lexical or UI

---

# 5. Viewport Virtualization Layer

## Purpose

Controls which chunks are actively mounted in the editor.

## Behavior

Only chunks in or near the viewport are active:

Visible:
Chunk 48
Chunk 49
Chunk 50

Mounted:
3–5 Lexical editors

Unloaded:
Remaining chunks

## Responsibilities

* Mount/unmount Lexical editors dynamically
* Manage scroll-based loading
* Maintain constant memory usage

---

# 6. Lexical Layer (Editing Runtime)

## Purpose

Lexical is the interactive editing surface.

## Key Concept

Lexical is NOT the document. It is a projection.

## Structure

Each mounted chunk becomes a Lexical instance:

## Responsibilities

* Handle typing and input
* Manage cursor and selection
* Process IME input
* Maintain local editing state

## Output

Lexical emits commands:

UpdateBlockText(blockId, newText)
InsertBlock(...)
DeleteBlock(...)

---

# 7. Layout Engine (Page/Web Rendering)

## Purpose

Computes visual representation of the document.

## Key Concept

> Pages are computed, not stored.

## Structure

PageMap {
blockId ? pageIndexes[]
}

## Responsibilities

* Line breaking
* Page breaking
* Pagination rules
* Reflow calculations
* Rendering layout updates

## Example

Before edit:

Page 5:
Paragraph B

Page 6:
Paragraph C

After edit:

Page 5:
Paragraph B (partial)

Page 6:
remainder of B
Paragraph C

---

# 8. System Flow (Write Operation)

When a user types:

## Step 1: Input in Lexical

User modifies text inside active chunk.

## Step 2: Lexical updates local state

Chunk-level editor updates.

## Step 3: Command emitted

UpdateBlockText(blockId, newText)

## Step 4: Document Model update

Canonical state is updated.

## Step 5: Chunk marked dirty

Affected chunk flagged for recomputation.

## Step 6: Layout recalculation

Only affected region is recomputed.

## Step 7: UI updates

Pages and visible content are re-rendered.

---

# 9. Page View System

## Key Principle

> Pages are a visual projection, not stored data.

## Flow

Document Model
?
Layout Engine
?
Page Mapping
?
UI Renderer

## Behavior

Typing can move content across pages without modifying:

* chunk structure
* document model
* Lexical structure

Only layout mapping changes.

---

# 10. Design Rules

## Rule 1

Chunks ? Pages

## Rule 2

Lexical ? Source of Truth

## Rule 3

Pages are computed, not stored

## Rule 4

Only Document Model is permanent state

## Rule 5

Chunking is a performance optimization, not a structural model

---

# 11. Architecture Diagram

```text
+--------------------+
¦ Document Model ¦
¦ (Source of Truth) ¦
+--------------------+
¦
+-------------------------------+
¦ ¦
+------?------+ +-------?-------+
¦ Chunk Engine ¦ ¦ Layout Engine ¦
¦ (Storage) ¦ ¦ (Pagination) ¦
+--------------+ +---------------+
¦ ¦
? ?
+--------------+ +----------------+
¦ Lexical Pool ¦ ¦ Page Renderer ¦
¦ (Mounted) ¦ ¦ (Virtual UI) ¦
+--------------+ +----------------+
```

---

# 12. System Goals

This architecture enables:

* High-performance editing of large documents
* Constant memory usage under load
* Lossless import/export pipelines
* Page + web view rendering
* Future support for collaboration and track changes

---

# 13. Summary

This system separates concerns into four independent layers:

* **Document Model** ? truth
* **Chunk Engine** ? scalability
* **Lexical Layer** ? editing
* **Layout Engine** ? rendering

This separation ensures long-term scalability and maintainability for enterprise-grade document editing systems.

---

Additional question

If anyone has tried similar approaches, what were the biggest issues (selection sync, undo consistency, performance, etc.)?

Contributor guide

Open the contributing guide

Research direction

The issue names no repository files, tests, or entry points. Start by evaluating the proposed canonical model, chunk engine, virtualization, and multiple LexicalComposer instances against the questions about synchronization, selection, undo consistency, and performance. A completed outcome is not defined beyond determining whether this architecture is viable.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
frontend, performance
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.