Open-Source Wikis

/

tldraw

/

Packages

/

@tldraw/tlschema

tldraw/tldraw

@tldraw/tlschema

Active contributors: Steve Ruiz, Mime Čuvalo, David Sheldrick, Mitja Bezenšek

Purpose

@tldraw/tlschema defines the record types that make up a tldraw document, plus their validators and migrations. Where @tldraw/store is the engine, @tldraw/tlschema is the data model. Every shape, binding, asset, page, and presence record originates here.

Directory layout

packages/tlschema/
├── package.json
└── src/
    ├── index.ts
    ├── createTLSchema.ts            # the schema factory (15 KB)
    ├── createPresenceStateDerivation.ts
    ├── store-migrations.ts          # store-level migrations
    ├── recordsWithProps.ts          # union helper
    ├── util-types.ts
    ├── records/                     # one file per top-level record kind
    │   ├── TLShape.ts               # 16 KB
    │   ├── TLBinding.ts             # 12 KB
    │   ├── TLAsset.ts
    │   ├── TLDocument.ts
    │   ├── TLPage.ts
    │   ├── TLPageState.ts
    │   ├── TLInstance.ts            # 17 KB
    │   ├── TLPresence.ts
    │   ├── TLPointer.ts
    │   ├── TLCamera.ts
    │   ├── TLUser.ts
    │   ├── TLRecord.ts              # union
    │   └── TLCustomRecord.ts
    ├── shapes/                      # per-shape shape records (TLArrowShape, TLDrawShape, …)
    ├── bindings/                    # per-binding records
    ├── styles/                      # StyleProp definitions (color, dash, fill, font, size)
    ├── translations/
    ├── assets/                      # asset record types
    ├── misc/                        # handles, geometry types
    └── migrations.test.ts           # 66 KB of migration tests

Key record types

Record File Description
TLDocument records/TLDocument.ts Document singleton (document:document).
TLPage records/TLPage.ts Page within a document.
TLShape records/TLShape.ts Union of all concrete shape records.
TLBinding records/TLBinding.ts Relationship between two shapes (e.g., arrow bound to shape).
TLAsset records/TLAsset.ts Image/video/bookmark asset.
TLInstance records/TLInstance.ts Per-instance editor state (current page, current tool, theme).
TLInstancePageState records/TLPageState.ts Per-instance per-page selection/hover state.
TLInstancePresence records/TLPresence.ts Multiplayer presence (cursor, selection).
TLPointer records/TLPointer.ts Local pointer state.
TLCamera records/TLCamera.ts Per-instance per-page camera.
TLUser records/TLUser.ts User-level state (theme preference).

Concrete shape records

Under packages/tlschema/src/shapes/:

File Shape kind
TLBaseShape.ts Base type.
TLArrowShape.ts Arrows.
TLDrawShape.ts Freehand draw.
TLGeoShape.ts Geometric primitives (rect, ellipse, …).
TLLineShape.ts Multi-point line.
TLNoteShape.ts Sticky note.
TLTextShape.ts Text label.
TLImageShape.ts Image.
TLVideoShape.ts Video.
TLBookmarkShape.ts Bookmark card.
TLEmbedShape.ts Iframe embed.
TLFrameShape.ts Frame container.
TLHighlightShape.ts Highlighter.
TLGroupShape.ts Group.
ShapeWithCrop.ts Crop helper type used by image/video.

How it works

graph LR
    Schema["createTLSchema()"] -->|registers| RecordTypes
    Schema -->|registers| Migrations
    Schema -->|registers| Validators
    RecordTypes --> Store["new Store({ schema })"]
    Validators --> Store
    Migrations --> Store

createTLSchema() returns a StoreSchema that the editor passes to new Store(...). The schema knows how to validate every record, migrate older versions on load, and serialize for snapshots.

Style props

packages/tlschema/src/styles/ defines StyleProp instances — color, dash, fill, font, size. These are shared across shapes (a draw stroke and a geo shape both use the same color style prop), and the UI's style panel reads them generically. The list of style props in use determines what shows up in the panel.

Migrations

Every schema change ships a migration:

  • Record-level migration — declared inside the record's file via defineMigrations({ ... }).
  • Store-level migration — declared in store-migrations.ts for changes that span records (introducing a new record type, restructuring relationships).
  • Migration tests in migrations.test.ts snapshot the up/down behavior.

Integration points

  • Imports. @tldraw/store (RecordType, StoreSchema), @tldraw/utils, @tldraw/validate.
  • Importers. @tldraw/editor re-exports the entire schema. The dotcom client uses it for parsing .tldr snapshots; @tldraw/sync-core uses it to validate inbound records over the wire.

Entry points for modification

  • New shape kind? Add TLNewShape.ts under shapes/, register in createTLSchema.ts (or via the shape util in tldraw), add a migration test.
  • New prop on an existing shape? Add it to the shape's record file and write a migration that backfills a default value.
  • New binding kind? Mirror the pattern under bindings/.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

@tldraw/tlschema – tldraw wiki | Factory