Document Structure

Organizing your Y.Doc for maintainable and efficient collaborative applications.

Overview

A Y.Doc is the root container for all collaborative data. Structure affects performance, maintainability, and how concurrent edits merge.

Structure by Purpose

Organize data into distinct categories:

Document
├── Content Data       (cells, objects, text)
├── Ordering Data      (arrays of IDs)
├── Metadata           (title, createdAt, version)
└── Configuration      (user preferences, settings)

Example: Spreadsheet

Document
├── cells: Map<rowId, Map<colId, CellData>>
├── rowOrder: Array<rowId>
├── colOrder: Array<colId>
├── rowProps: Map<rowId, {height}>
├── colProps: Map<colId, {width}>
├── namedRanges: Map<name, Range>
└── styles: Map<styleId, Style>

Example: Canvas App

Document
├── objects: Map<objectId, DrawingObject>
├── layers: Map<layerId, LayerData>
├── layerOrder: Map<layerId, Array<objectId>>
├── paths: Map<pathId, PathData>
├── textBoxes: Map<textId, Y.Text>
└── metadata: Map<key, value>

Example: Presentation

Document
├── slides: Map<slideId, SlideData>
├── slideOrder: Array<slideId>
├── containers: Map<containerId, Container>
├── masters: Map<masterId, MasterTemplate>
├── styles: Map<styleId, Style>
└── notes: Map<slideId, string>

Design Guidelines

Separate Content from Order

  • Store content in Y.Map by ID
  • Store ordering in Y.Array (IDs only)
  • Never put complex objects in reorderable arrays

Flatten When Possible

  • Deep nesting has overhead
  • Prefer 2-3 levels max
  • Use flat maps with composite keys when appropriate

Use TypeScript Interfaces

  • Define types for your document structure
  • Create helper functions for typed access

Initialize Required Structure

  • Access top-level types on document creation
  • Set defaults in a transaction

Performance Notes

  • Many top-level types is fine—enables granular sync
  • Deeply nested types (4+ levels) add overhead
  • Large arrays (10,000+ items): consider pagination or chunking

See Also