# tldraw SDK releases -------- # v4.3.0 [View on GitHub](https://github.com/tldraw/tldraw/releases/tag/v4.3.0) This release introduces several significant changes: a new pattern for defining custom shape/binding typings, pluggable storage for `TLSocketRoom` with a new SQLite option, reactive `editor.inputs`, and optimized draw shape encoding. It also adds various other API improvements, performance optimizations, and bug fixes, including better support for React 19. --- ### New pattern for defining custom shape/binding types (breaking change) ([#7091](https://github.com/tldraw/tldraw/pull/7091)) We've improved the developer experience of working with custom shape and binding types. There's now less boilerplate and fewer gotchas when using tldraw APIs in a type-safe manner. This is a minor breaking change at the type level—your code will still run, but you'll get TypeScript errors until you migrate.
Migration guide When _declaring_ types for custom shapes, you can now use TypeScript's module augmentation feature to provide more specific types for the custom shape. Before: ```ts import { TLBaseShape } from 'tldraw' // Shapes were defined by using the helper TLBaseShape type type MyShape = TLBaseShape`<'my-shape', { w: number; h: number; text: string }>` ``` After: ```ts import { TLShape } from 'tldraw' const MY_SHAPE = 'my-shape' // We now use TypeScript's module augmentation feature to allow // extending the builtin TLShape type. declare module 'tldraw' { export interface TLGlobalShapePropsMap { [MY_SHAPE]: { w: number; h: number; text: string } } } type MyShape = TLShape`` ``` The benefit of this new system is that Editor APIs such as `createShape` now know about your custom shapes automatically: ```ts // Just works - TypeScript validates props and provides autocomplete editor.createShape({ type: 'my-shape', props: { w: 100, h: 100, text: 'Hello' } }) // Will cause a TypeScript error for `text` editor.createShape({ type: 'my-shape', props: { w: 100, h: 100, text: 123 } }) ``` The same pattern applies to custom bindings. See the [Custom Shapes Guide](https://tldraw.dev/docs/shapes#Custom-shapes-1) and the [Pin Bindings example](https://github.com/tldraw/tldraw/tree/main/apps/examples/src/examples/pin-bindings) for details.
(contributed by [@Andarist](https://github.com/Andarist)) --- ### Pluggable storage for TLSocketRoom + SQLite support ([#7320](https://github.com/tldraw/tldraw/pull/7320), [#7123](https://github.com/tldraw/tldraw/pull/7123)) We've refactored the `TLSocketRoom` API to support a pluggable storage layer. We're providing two implementations: - **`SQLiteSyncStorage`** – Automatically persists room state to SQLite. Recommended for production. - **`InMemorySyncStorage`** – Keeps state in memory with manual persistence via callbacks (previous built-in behavior). **We recommend switching to `SQLiteSyncStorage` if your environment supports SQLite** (Cloudflare Durable Objects, Node.js, Bun, Deno). It provides automatic persistence, lower memory usage, and faster startup times.
Why SQLite? - **Automatic persistence**: Data survives process restarts without manual snapshot handling - **Lower memory usage**: No need to keep entire documents in memory - **Faster startup**: No need to load the document into memory before accepting socket connections - **Simpler code**: No more `onChange` callbacks and manual persistence logic
Platform support | Platform | Wrapper | SQLite Library | | -------------------------- | -------------------------------- | --------------------------------- | | Cloudflare Durable Objects | `DurableObjectSqliteSyncWrapper` | Built-in `ctx.storage` | | Node.js/Deno | `NodeSqliteWrapper` | `better-sqlite3` or `node:sqlite` | See the [Cloudflare template](https://github.com/tldraw/tldraw-sync-cloudflare) and the [Node server example](https://github.com/tldraw/tldraw/tree/main/templates/simple-server-example) respectively. Bun support should be straightforward to add.
Migration guide Existing code continues to work, however we have deprecated the following `TLSocketRoom` options: - `initialSnapshot` - `onDataChange` These are replaced by the new `storage` option. We've also deprecated the `TLSocketRoom.updateStore` method, which has been supplanted by `storage.transaction`. Before: ```ts const existingSnapshot = loadExistingSnapshot() const room = new TLSocketRoom({ initialSnapshot: existingSnapshot, onDataChange: () => { persistSnapshot(room.getCurrentSnapshot()) }, }) ``` If you want to keep the same behavior with in-memory document storage and manual persistence: ```ts import { InMemorySyncStorage, TLSocketRoom } from '@tldraw/sync-core' const room = new TLSocketRoom({ storage: new InMemorySyncStorage({ snapshot: existingSnapshot, onChange() { saveToDatabase(storage.getSnapshot()) }, }), }) ``` However, we recommend switching to SQLite. Users of our Cloudflare template should follow the migration guide on the [sync docs page](https://tldraw.dev/docs/sync). If you're using `TLSocketRoom` on Node, creating the room should end up looking something like this: ```ts import Database from 'better-sqlite3' import { SQLiteSyncStorage, NodeSqliteWrapper, TLSocketRoom, RoomSnapshot } from '@tldraw/sync-core' async function createRoom(roomId: string) { const db = new Database(`path/to/${roomId}.db`) const sql = new NodeSqliteWrapper(db) let snapshot: RoomSnapshot | undefined = undefined if (!SQLiteSyncStorage.hasBeenInitialized(sql)) { // This db hasn't been used before, so if it's a pre-existing // document, load the legacy room snapshot snapshot = await loadExistingSnapshot() } const storage = new SQLiteSyncStorage({ sql, snapshot }) return new TLSocketRoom({ storage, onSessionRemoved(room, args) { if (args.numSessionsRemaining === 0) { room.close() db.close() } }, }) } ```
--- ### Optimized draw shape encoding ([#7364](https://github.com/tldraw/tldraw/pull/7364), [#7710](https://github.com/tldraw/tldraw/pull/7710)) Draw and highlight shape point data is now stored using a compact delta-encoded binary format instead of JSON arrays. This reduces storage size by approximately 80% while preserving stroke fidelity.
Breaking change details If you were reading or writing draw shape data programatically you might need to update your code to use the new format. - `TLDrawShapeSegment.points` renamed to `.path` and changed from `VecModel[]` to `string` (base64-encoded) - Added `scaleX` and `scaleY` properties to draw and highlight shapes - New exports: `b64Vecs` encoding utilities, e.g. `getPointsFromDrawSegment` helper. Use this if you need to manually read/write point data. Existing documents are automatically migrated.
--- ### Reactive inputs ([#7312](https://github.com/tldraw/tldraw/pull/7312)) Refactored `editor.inputs` to use reactive atoms via the new `InputsManager` class. All input state is now accessed via getter methods (e.g., `editor.inputs.getCurrentPagePoint()`, `editor.inputs.getShiftKey()`). Direct property access is deprecated but still supported for backwards compatibility. ## API changes - 💥 **`DefaultTopPanel`** export removed from `tldraw`. The top panel component for displaying the offline indicator is now handled internally by `PeopleMenu`. ([#7568](https://github.com/tldraw/tldraw/pull/7568)) - 💥 **`TextDirection`** export removed from `tldraw`. Use TipTap's native `TextDirection` extension instead. The `richTextValidator` now includes an optional `attrs` property - a migration may be necessary for older clients/custom shapes. ([#7304](https://github.com/tldraw/tldraw/pull/7304)) - Add `tlenvReactive` atom to `@tldraw/editor` for reactive environment state tracking, including coarse pointer detection that updates when users switch between mouse and touch input. ([#7296](https://github.com/tldraw/tldraw/pull/7296)) - Add `hideAllTooltips()` helper function for programmatically dismissing tooltips. ([#7288](https://github.com/tldraw/tldraw/pull/7288)) - Add `zoomToFitPadding` option to `TldrawOptions` to customize the default padding used by zoom-to-fit operations. ([#7602](https://github.com/tldraw/tldraw/pull/7602)) - Add `snapThreshold` option to `TldrawOptions` for configuring the snap distance, defaulting to 8 screen pixels. ([#7543](https://github.com/tldraw/tldraw/pull/7543)) - Add `resizeChildren` configuration option to `FrameShapeUtil` to allow frame children to be resized proportionally when the frame is resized. ([#7526](https://github.com/tldraw/tldraw/pull/7526)) - Add `Editor.canEditShape()` and `Editor.canCropShape()` methods to centralize shape permission checks. Add `ShapeUtil.canEditWhileLocked()` for shapes that remain editable when locked. ([#7361](https://github.com/tldraw/tldraw/pull/7361)) - Add `editor.getDebouncedZoomLevel()` and `editor.getEfficientZoomLevel()` methods for improved zoom performance on dense canvases. Add `debouncedZoom` and `debouncedZoomThreshold` options. ([#7235](https://github.com/tldraw/tldraw/pull/7235)) - Add configurable `showTextOutline` option to `TextShapeUtil`, `ArrowShapeUtil`, and `GeoShapeUtil` via `.configure()` pattern. ([#7314](https://github.com/tldraw/tldraw/pull/7314)) - Export freehand stroke utilities: `getStroke`, `getStrokeOutlinePoints`, and `setStrokePointRadii`. ([#7400](https://github.com/tldraw/tldraw/pull/7400)) (contributed by [@VimHax](https://github.com/VimHax)) - Add `Box.isValid()` method to check for finite coordinates. ([#7532](https://github.com/tldraw/tldraw/pull/7532)) - Add `spacebarPanning` option to control whether spacebar activates pan mode. ([#7312](https://github.com/tldraw/tldraw/pull/7312)) - Introduce pluggable `TLSyncStorage` API for `TLSocketRoom`. The `initialSnapshot` and `onDataChange` options are now deprecated in favor of the new `storage` option. ([#7123](https://github.com/tldraw/tldraw/pull/7123)) - Export `DefaultLabelColorStyle` which is necessary for rich text in custom shapes. ([#7114](https://github.com/tldraw/tldraw/pull/7114)) ### Improvements - Improve coarse pointer detection by replacing CSS media queries with a reactive `data-coarse` attribute that updates when users switch between mouse and touch input. ([#7404](https://github.com/tldraw/tldraw/pull/7404)) - Add CSS containment to main toolbar and text measurement element for improved rendering performance. ([#7406](https://github.com/tldraw/tldraw/pull/7406)) ([#7407](https://github.com/tldraw/tldraw/pull/7407)) - Improve cross-realm support by scoping canvas event listeners to the editor container's ownerDocument. ([#7113](https://github.com/tldraw/tldraw/pull/7113)) - Simplify ImmutableMap implementation for better code clarity. ([#7431](https://github.com/tldraw/tldraw/pull/7431)) - Improve code readability in number validator by using `Number.isFinite()` instead of arithmetic trick. ([#7374](https://github.com/tldraw/tldraw/pull/7374)) - Upgrade to React 19 with all necessary type and configuration changes for compatibility. ([#7317](https://github.com/tldraw/tldraw/pull/7317)) - Improve signal graph traversal performance by eliminating per-recursion closure allocations. ([#7430](https://github.com/tldraw/tldraw/pull/7430)) - Optimize object utility functions. ([#7432](https://github.com/tldraw/tldraw/pull/7432)) - Use in-place sorting in parentsToChildren derivation. ([#7433](https://github.com/tldraw/tldraw/pull/7433)) - Optimize notVisibleShapes derivation with inlined bounds checks. ([#7429](https://github.com/tldraw/tldraw/pull/7429)) - Cache label size measurements with WeakCache for improved geo shape performance. ([#7412](https://github.com/tldraw/tldraw/pull/7412)) - Optimize validators with fast paths and production inlining. ([#7373](https://github.com/tldraw/tldraw/pull/7373)) ### Bug fixes - Fix migrations for draw and highlight shapes to be idempotent, preventing errors when migrations run multiple times. ([#7389](https://github.com/tldraw/tldraw/pull/7389)) - Fix dot detection in draw and highlight shapes after the point compression change. ([#7365](https://github.com/tldraw/tldraw/pull/7365)) - Fix clicking a shape's text label while editing to re-focus the input and select all text. ([#7342](https://github.com/tldraw/tldraw/pull/7342)) - Fix pasting at cursor to correctly account for frames and parent containers. ([#7277](https://github.com/tldraw/tldraw/pull/7277)) - Fix editing mode to exit when dragging causes the text input to blur. ([#7291](https://github.com/tldraw/tldraw/pull/7291)) - Fix CommonJS build issues with TipTap imports in rich text module. ([#7282](https://github.com/tldraw/tldraw/pull/7282)) - Fix iOS automatically zooming in on input fields by ensuring 16px minimum font size. ([#7118](https://github.com/tldraw/tldraw/pull/7118)) - Fix `distanceToLineSegment` returning squared distance instead of actual distance, causing hit testing (eraser, scribble select) to be too strict. ([#7610](https://github.com/tldraw/tldraw/pull/7610)) (contributed by [@arpit-goblins](https://github.com/arpit-goblins)) - Fix `zoomToSelection` to toggle between 100% zoom and zoom-to-fit behavior. ([#7536](https://github.com/tldraw/tldraw/pull/7536)) - Fix export of SVG markers by handling fragment-only URLs correctly. ([#7506](https://github.com/tldraw/tldraw/pull/7506)) (contributed by [@PidgeyBE](https://github.com/PidgeyBE)) - Restore wheel and pinch canvas event emission. ([#6834](https://github.com/tldraw/tldraw/pull/6834)) (contributed by [@swdev33](https://github.com/swdev33)) - Fix context menu submenu flickering when hovered. ([#6837](https://github.com/tldraw/tldraw/pull/6837)) (contributed by [@swdev33](https://github.com/swdev33)) - Fix rotated shape positions not being restored after flipping twice. ([#7359](https://github.com/tldraw/tldraw/pull/7359)) - Fix keyboard shortcuts and clipboard events not working when `hideUi` is true. ([#7367](https://github.com/tldraw/tldraw/pull/7367)) - Fix elbow arrows routing incorrectly when using dynamic sizing at high zoom levels. ([#7424](https://github.com/tldraw/tldraw/pull/7424)) - Allow fullscreen for embed shapes. ([#7417](https://github.com/tldraw/tldraw/pull/7417)) - Move mobile rotate handle to bottom for image and video shapes to accommodate the contextual toolbar. ([#6727](https://github.com/tldraw/tldraw/pull/6727)) - Fix dropdown menu items incorrectly displaying an icon on the right side. ([#7533](https://github.com/tldraw/tldraw/pull/7533)) - Fix zoom menu showing debounced zoom level for canvases with many shapes. ([#7626](https://github.com/tldraw/tldraw/pull/7626)) - Fix extra line appearing after bullet and ordered lists in text shapes. ([#7643](https://github.com/tldraw/tldraw/pull/7643)) (contributed by [@sahiee-dev](https://github.com/sahiee-dev)) - Fix "Back to content" button not appearing when selected shapes are off-screen. ([#7649](https://github.com/tldraw/tldraw/pull/7649)) - Fix dotted freehand lines becoming invisible at minimum zoom on Chrome. ([#7650](https://github.com/tldraw/tldraw/pull/7650)) - Fix menu bar stretching to full width on mobile viewports instead of fitting content. ([#7568](https://github.com/tldraw/tldraw/pull/7568)) -------- # v4.2.0 This month's release includes many bug fixes and small API additions, along with a major version bump of our TipTap rich text editor. ## What's new ### TipTap v3 ([#5717](https://github.com/tldraw/tldraw/pull/5717)) We've upgraded TipTap from v2 to v3. If you've done any customization to our standard TipTap kit, please refer to TipTap's guide [How to upgrade Tiptap v2 to v3](https://tiptap.dev/docs/guides/upgrade-tiptap-v2) for breaking changes you might experience. ## API changes - Add `Editor.setTool`/`Editor.removeTool` for dynamically altering the editor's tool state chart. ([#6909](https://github.com/tldraw/tldraw/pull/6909)) ([#7134](https://github.com/tldraw/tldraw/pull/7134)) - Allow using custom socket implementations with `useSync` via a new `connect` option. ([#6859](https://github.com/tldraw/tldraw/pull/6859)) (contributed by [@Digital39999](https://github.com/Digital39999)) - Add support for nested property queries in the store. ([#6981](https://github.com/tldraw/tldraw/pull/6981)) - Add `createBookmarkFromUrl` helper for easier bookmark shape creation. ([#6894](https://github.com/tldraw/tldraw/pull/6894)) - Add custom reference points for handle angle snapping. ([#6987](https://github.com/tldraw/tldraw/pull/6987)) (contributed by [@naaa760](https://github.com/naaa760)) - Add new "lined-fill" style, accessible via Option+Shift+F. ([#7034](https://github.com/tldraw/tldraw/pull/7034)) - Add `onInteractionEnd` callback option. ([#6919](https://github.com/tldraw/tldraw/pull/6919)) - Add `allowReferrer` option for window opening functions. ([#7004](https://github.com/tldraw/tldraw/pull/7004)) - Remove defunct Excalidraw embed definition. ([#6897](https://github.com/tldraw/tldraw/pull/6897)) ## Improvements - Use window.prompt for renaming frames on mobile. ([#6838](https://github.com/tldraw/tldraw/pull/6838)) - Optimize string append operations in sync protocol. ([#7007](https://github.com/tldraw/tldraw/pull/7007)) (contributed by [@quasor](https://github.com/quasor)) ## Bug fixes - Fix Replit embed URL handling. ([#6892](https://github.com/tldraw/tldraw/pull/6892)) - Fix accessibility issue that caused a misleading warning in the console. ([#6904](https://github.com/tldraw/tldraw/pull/6904)) - Fix convert-to-bookmark action. ([#6894](https://github.com/tldraw/tldraw/pull/6894)) - Fix dropdown menu pointer handling. ([#7021](https://github.com/tldraw/tldraw/pull/7021)) - Fix iOS Safari image uploads. ([#7037](https://github.com/tldraw/tldraw/pull/7037)) - Fix Alt+Tab conflict on Windows. ([#7005](https://github.com/tldraw/tldraw/pull/7005)) - Fix text focus issues. ([#7043](https://github.com/tldraw/tldraw/pull/7043)) - Fix `TldrawEditor` usability without `TldrawUiContextProvider`. ([#7053](https://github.com/tldraw/tldraw/pull/7053)) - Fix cross-realm clipboard functionality. ([#7026](https://github.com/tldraw/tldraw/pull/7026)) - Fix iOS ink rendering via coalesced events. ([#6917](https://github.com/tldraw/tldraw/pull/6917)) - Fix menu-open dragging behavior. ([#6918](https://github.com/tldraw/tldraw/pull/6918)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v4.2.0) --- ## Patch releases ### v4.2.1 - Fix CommonJS/cjs builds that were broken in v4.2.0. ([#7282](https://github.com/tldraw/tldraw/pull/7282)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v4.2.1) -------- # v4.1.0 This month's release introduces a new shader starter kit for WebGL integration, along with API additions for embed control, minimap filtering, and localStorage-backed atoms. ## What's new ### Shader starter kit ([#6847](https://github.com/tldraw/tldraw/pull/6847)) A new template demonstrating WebGL shader integration with tldraw for dynamic, interactive backgrounds that respond to canvas interactions. Includes four complete examples: - **Fluid simulation** - Navier-Stokes dynamics - **Rainbow** - Animated gradients - **Shadows** - Raymarching and signed distance fields - **Minimal** - Bare-bones template for custom shaders Features configurable parameters, localStorage persistence, and full TypeScript support. ## API changes - Add `embedOnPaste` option to `EmbedDefinition` for opting out of automatic embed-on-paste behavior. ([#6874](https://github.com/tldraw/tldraw/pull/6874)) - Add `hideInMinimap` option to `ShapeUtil` for excluding shapes from the minimap. ([#6327](https://github.com/tldraw/tldraw/pull/6327)) - Add `snapType?: 'point' | 'align'` to `TLHandle` for finer control over handle snapping. The `canSnap` property is now deprecated. ([#6883](https://github.com/tldraw/tldraw/pull/6883)) - Expose `Editor#getShapePageBounds` and `isRecordsDiffEmpty` as public methods. ([#6871](https://github.com/tldraw/tldraw/pull/6871)) - Add `localStorageAtom` to `@tldraw/state` for atoms backed by localStorage with cross-tab syncing. ([#6876](https://github.com/tldraw/tldraw/pull/6876)) - Add inline style picker component variants. ([#6920](https://github.com/tldraw/tldraw/pull/6920)) ## Improvements - Make bookmark titles clickable. ([#6326](https://github.com/tldraw/tldraw/pull/6326)) - Optimize mobile top bar rendering. ([#6895](https://github.com/tldraw/tldraw/pull/6895)) - Add numpad Enter support for entering edit mode. ([#6830](https://github.com/tldraw/tldraw/pull/6830)) - Consolidate preferences menu items. ([#6802](https://github.com/tldraw/tldraw/pull/6802)) ## Bug fixes - Fix accessibility shortcut typo. ([#6811](https://github.com/tldraw/tldraw/pull/6811)) - Fix focus mode action missing. ([#6812](https://github.com/tldraw/tldraw/pull/6812)) - Fix arrow rendering edge case. ([#6799](https://github.com/tldraw/tldraw/pull/6799)) - Fix empty window opening on anchor click. ([#6817](https://github.com/tldraw/tldraw/pull/6817)) - Fix missing translation key. ([#6826](https://github.com/tldraw/tldraw/pull/6826)) - Fix shape index race condition. ([#6884](https://github.com/tldraw/tldraw/pull/6884)) - Fix zero geometry vertices edge case. ([#6885](https://github.com/tldraw/tldraw/pull/6885)) - Fix style panel button overflow. ([#6920](https://github.com/tldraw/tldraw/pull/6920)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v4.1.0) --- ## Patch releases ### v4.1.1 - Update the formatting of the `npm create tldraw` command in the CLI output. [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v4.1.1) ### v4.1.2 - Move `InFrontOfTheCanvas` component back out of the `.tl-canvas` element. ([#7021](https://github.com/tldraw/tldraw/pull/7021)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v4.1.2) -------- # v4.0.0 This major release introduces new starter kits, a CLI tool, WCAG 2.2 Level AA accessibility compliance, and significant API enhancements for building custom canvas applications. ## What's new ### npm create tldraw ([#6753](https://github.com/tldraw/tldraw/pull/6753)) A new CLI tool for quickly scaffolding tldraw projects. Run `npm create tldraw` to initialize projects using templates and starter kits. ### Starter kits Five new MIT-licensed starter kits demonstrate different applications of tldraw's canvas: - **[agent](https://tldraw.dev/starter-kits/agent)** - Cursor-style chatbot interface where conversations occur on the canvas with AI assistance - **[workflow](https://tldraw.dev/starter-kits/workflow)** - Node-and-wire visual programming interface for automation workflows and state machines - **[branching-chat](https://tldraw.dev/starter-kits/branching-chat)** - Multi-path conversation explorer for managing conversation branches - **[chat](https://tldraw.dev/starter-kits/chat)** - Canvas-based image annotation with integrated chatbot - **[multiplayer](https://tldraw.dev/starter-kits/multiplayer)** - Collaborative whiteboard foundation built on tldraw sync ### Licensing ([#6707](https://github.com/tldraw/tldraw/pull/6707)) Production deployments now require a license key. Development and localhost environments remain exempt. Available licenses include: - Free 100-day trial license - Commercial license for commercial projects - Hobby license for non-commercial use ### Accessibility ([#6695](https://github.com/tldraw/tldraw/pull/6695)) Achieves WCAG 2.2 Level AA compliance with an accessibility mode, improved keyboard shortcuts, comprehensive aria-labels, and scrollable menus. ### Drag from toolbar ([#6681](https://github.com/tldraw/tldraw/pull/6681)) Create shapes by dragging directly from the toolbar, eliminating the click-then-draw workflow. ### Custom shape clipping ([#6649](https://github.com/tldraw/tldraw/pull/6649)) Shapes can now clip their children, enabling complex visual hierarchies and container-style shapes. ### Vertical toolbar support ([#6623](https://github.com/tldraw/tldraw/pull/6623)) The toolbar supports vertical orientation for alternative layout configurations. ### Rich text arrows ([#6594](https://github.com/tldraw/tldraw/pull/6594)) Arrow labels support rich text formatting including bold, italic, and text styling. ## API changes - 💥 **CSS variables** now start with `--tl-` prefix. Update custom CSS: `--color-background` → `--tl-color-background`, `--space-4` → `--tl-space-4`. ([#6712](https://github.com/tldraw/tldraw/pull/6712)) - 💥 **`Geometry2D.isLabel`** replaced with `excludeFromShapeBounds` flag. ([#6668](https://github.com/tldraw/tldraw/pull/6668)) - 💥 **`open-url` event** now uses `destinationUrl` instead of `url`. ([#6641](https://github.com/tldraw/tldraw/pull/6641)) - 💥 **Arrow shapes** now use `richText` instead of `text` property. Data migrates automatically, but direct access to `arrow.props.text` must update to `arrow.props.richText`. ([#6594](https://github.com/tldraw/tldraw/pull/6594)) - 💥 **`@tldraw/ai` module** removed. Use the [agent starter kit](https://tldraw.dev/starter-kits/agent) instead. - 💥 **Event propagation behavior** changed. Use `editor.markEventAsHandled()` for custom event handling. ([#6592](https://github.com/tldraw/tldraw/pull/6592)) - 💥 **Style panel** redesigned with legacy picker components removed. ([#6573](https://github.com/tldraw/tldraw/pull/6573)) - 💥 **Toolbar CSS class names** updated for consistency. ([#6551](https://github.com/tldraw/tldraw/pull/6551)) - Add custom messages in `TLSocketRoom` via `sendCustomMessage()` and `onCustomMessageReceived`. ([#6614](https://github.com/tldraw/tldraw/pull/6614)) (contributed by [@mootari](https://github.com/mootari)) - Add `Editor.getShapesAtPoint()` with flexible margin options for precise hit testing. ([#6724](https://github.com/tldraw/tldraw/pull/6724)) - Add `editor.toImageDataUrl()` for generating image data URLs directly from shapes. ([#6658](https://github.com/tldraw/tldraw/pull/6658)) - Add `ShapeUtil.isExportBoundsContainer` and `canCull` methods for controlling export behavior and rendering optimization. ([#6649](https://github.com/tldraw/tldraw/pull/6649)) - Add `EditorAtom` for managing UI state outside React components. ([#6687](https://github.com/tldraw/tldraw/pull/6687)) - Add enhanced handle drag callbacks with timing events for custom drag interactions. ([#6702](https://github.com/tldraw/tldraw/pull/6702)) ## Bug fixes - Fix arrow labels being cut off in exports. ([#6783](https://github.com/tldraw/tldraw/pull/6783)) - Fix PNG physical pixel dimensions parsing. ([#6771](https://github.com/tldraw/tldraw/pull/6771)) - Fix pointer events on mobile firing inconsistently. ([#6738](https://github.com/tldraw/tldraw/pull/6738)) - Fix Chrome embed positioning at non-100% zoom levels. ([#6724](https://github.com/tldraw/tldraw/pull/6724)) - Fix hollow shapes not being properly bound-to by arrows. ([#6705](https://github.com/tldraw/tldraw/pull/6705)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v4.0.0) --- ## Patch releases ### v4.0.1 - Fix template exports. ([#6804](https://github.com/tldraw/tldraw/pull/6804)) - Fix documentation. ([#6805](https://github.com/tldraw/tldraw/pull/6805)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v4.0.1) ### v4.0.2 - Fix focus mode SDK issue that caused problems when using focus mode in the SDK. ([#6815](https://github.com/tldraw/tldraw/pull/6815)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v4.0.2) ### v4.0.3 - Add Claude 4.5 Sonnet to agent starter kit. ([#6852](https://github.com/tldraw/tldraw/pull/6852)) - Ensure templates don't use internal functions. ([#6871](https://github.com/tldraw/tldraw/pull/6871)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v4.0.3) ### v4.0.4 - Fix shape index jitter for the first shape created, preventing potential index collisions. ([#6884](https://github.com/tldraw/tldraw/pull/6884)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v4.0.4) -------- # v3.9.0 This release focuses on bug fixes and performance enhancements, laying groundwork for v3.10 features. ## API changes - 💥 **`store.createSelectedComputedCache`** removed; use `store.createCache` with custom selector `computed` instead. - 💥 **`createComputerCache` API** modified: third argument now accepts options object with `areRecordsEqual` and `areResultsEqual` properties instead of single equality function. ## Improvements - Improve layout operations including align, distribute, flip, and stack with better compatibility for arrows and overlapping shapes. - Add new `AtomMap` class to accelerate shape, binding, and record creation/deletion, available as a utility for building custom reactive maps. - Add horizontal padding to text-bound arrows for improved visual appearance. ## Bug fixes - Fix pasted image size calculations. - Remove `canvas-size` dependency resolving bundler compatibility issues. - Fix SVG copy mimetype. - Fix text shape cloning crash. - Fix temporary image preview display during uploads. - Recognize `https://localhost` as development environment for licensing. [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v3.9.0) -------- # v3.8.0 This release delivers performance enhancements, UI improvements, and developer experience upgrades alongside bug fixes. ## API changes - 💥 **`maxDrawShapePoints`** moved to `DrawShapeUtil.configure({ maxPoints })`. - 💥 **Asset upload** now returns `{ src, meta? }` object instead of string. - 💥 **JSON export option** removed; `useImageOrVideoAssetUrl` requires width parameter. - 💥 **`TldrawUiToasts` and `TldrawUiDialogs`** renamed to `DefaultToasts` and `DefaultDialogs`. - Add new `Editor.toImage` method for refined export functionality. - Add custom content handlers for pasted tldraw and excalidraw content. - Add "before-event" listener for custom input event handling. - Add `onCrop` method for shape-specific cropping customization. ## Improvements - Add `ShapeUtil.configure` utility for passing options to shape utilities. - Allow note shapes to resize by scale. - Add geometric tool shortcut (`g` key) for quick selection. - Add URL drag-and-drop to create bookmark shapes on canvas. - Expand support to 40+ languages via i18n enhancements. - Add React 19 compatibility. - Improve frame performance through computation relocation. ## Bug fixes - Fix dialog and edit menu glitches. - Fix mousewheel scrolling on elements. - Fix image export width. - Fix text paste behavior via keyboard shortcuts. [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v3.8.0) --- ## Patch releases ### v3.8.1 - Fix `TldrawImage` not functioning properly with `format=png`. ([#5429](https://github.com/tldraw/tldraw/pull/5429)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v3.8.1) -------- # v3.7.0 This release delivers bug fixes and performance enhancements, including customization options for presence data synchronization. ## What's new ### Presence sync customization ([#5149](https://github.com/tldraw/tldraw/pull/5149)) Developers can now customize what presence data is synced between clients, or disable presence syncing entirely. This enables optimization for high-latency connections and privacy-focused applications. ## API changes - Allow `expandSelectionOutlinePx` to return a `Box` object to enable asymmetric expansion across different sides. - Modify behavior when using `editor.updateShape` to properly handle undefined values. ## Bug fixes - Fix React Strict Mode listener bug affecting `store.listen`. - Fix image rotation and cropping functionality issues. - Fix CSS import failures during export/print operations. - Fix text measurement div leakage during development hot reloads. - Fix popover menu viewport overflow problems. - Fix GitHub Gist URL validation. - Fix image dimension limits for pasted content. - Fix pages menu and quick actions rendering. [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v3.7.0) --- ## Patch releases ### v3.7.1 - Pass custom migrations to `useLocalStore`. ([#5204](https://github.com/tldraw/tldraw/pull/5204)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v3.7.1) ### v3.7.2 - Fix pasting files copied from the local filesystem with cmd-v. ([#5225](https://github.com/tldraw/tldraw/pull/5225)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v3.7.2) -------- # v3.6.0 This release focuses on developer experience improvements with expanded helper functions and various bug fixes across the editor, embed system, and export functionality. ## What's new ### Expanded helper functions ([#5041](https://github.com/tldraw/tldraw/pull/5041)) Actions and toasts overrides now have access to a wider range of helper functions, including clipboard interactions, toast notifications, export utilities, printing, and more. This makes it easier to create custom actions and tools that integrate deeply with tldraw's functionality. ## API changes - 💥 **`setEmbedDefinitions`** changed from an instance method to a static method on the `EmbedShapeUtil` class. Update your embed definitions to use `EmbedShapeUtil.setEmbedDefinitions()` instead of calling it on an instance. ([#5027](https://github.com/tldraw/tldraw/pull/5027)) - 💥 **`ExtractOptionalKeys` and `ExtractRequiredKeys`** utility types removed. Use the new utility type for creating optional properties instead. ([#5055](https://github.com/tldraw/tldraw/pull/5055)) ## Improvements - Add utility type for making undefined properties optional, simplifying type definitions for shape props and other optional configurations. ([#5055](https://github.com/tldraw/tldraw/pull/5055)) - Make notes properly snap to the grid after their position is updated, improving alignment consistency. ([#5010](https://github.com/tldraw/tldraw/pull/5010)) - Add incremental derivation example demonstrating advanced computed value patterns. ([#5038](https://github.com/tldraw/tldraw/pull/5038)) ## Bug fixes - Fix asset resolution when copying and pasting multiple items, including proper handling of video assets. ([#5061](https://github.com/tldraw/tldraw/pull/5061)) - Fix text clipping in scaled frames during export, ensuring all text content is visible in exported images. ([#5022](https://github.com/tldraw/tldraw/pull/5022)) - Fix concurrent export operations interfering with each other's font loading. ([#5022](https://github.com/tldraw/tldraw/pull/5022)) - Fix long-press point accuracy to ensure touch interactions register at the correct coordinates. ([#5032](https://github.com/tldraw/tldraw/pull/5032)) - Fix export naming for single unnamed frames, which now receive appropriate default names. ([#4918](https://github.com/tldraw/tldraw/pull/4918)) - Fix custom embeds not rendering correctly on initial mount. ([#5027](https://github.com/tldraw/tldraw/pull/5027)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v3.6.0) --- ## Patch releases ### v3.6.1 - Fix bugs in the editor, state-react, and tldraw packages. ([#5132](https://github.com/tldraw/tldraw/pull/5132)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v3.6.1) -------- # v3.5.0 This release introduces enhancements to grid snapping during shape creation, improves layering mechanics, and provides better control over export functionality. ## What's new ### Grid snapping for shape creation ([#4894](https://github.com/tldraw/tldraw/pull/4894)) Shapes now automatically align to the grid when drawn in grid mode. The new `maybeSnapToGrid` function enables snapping for both click-created and drag-created shapes. ### Improved layering actions ([#4898](https://github.com/tldraw/tldraw/pull/4898)) The "bring forward" and "send backward" actions now only consider nearby overlapping shapes, making layer management more intuitive when working with complex canvases. ## API changes - Add `scale` and `pixelRatio` parameters to export utilities for more precise control over export dimensions and quality. - Expose font size and stroke size APIs. - Add socket close reason for rate limiting. - Add option to toggle double-click text creation. ## Improvements - Improve panning performance for note-heavy canvases and zoomed-out views. - Improve page menu hover interaction. - Add custom React provider support in SVG exports. - Switch default theme to light mode. - Improve frame heading right-click behavior. ## Bug fixes - Fix off-screen shape zoom-to-edit. - Fix erasing state stickiness. - Fix frame heading drag interactions. - Fix Safari sleep-related crashes. [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v3.5.0) --- ## Patch releases ### v3.5.1 - Fix long press on inset canvases. ([#5037](https://github.com/tldraw/tldraw/pull/5037)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v3.5.1) -------- # v3.4.0 This release addresses UI bugs, enhances image/video performance, and improves Excalidraw content compatibility. ## API changes - 💥 **`id` DOM attribute** on shapes removed in favor of a `data-shape-id` attribute on shape wrappers. - Add `labelColor` property to note shapes. - Add `useUniqueSafeId` and `useSharedSafeId` utilities for managing DOM IDs in tldraw components. ## Improvements - Improve tooltip wording in the style panel. - Prevent arrow label indicators from displaying behind labels. - Limit page name length in the move-to-page menu. - Improve image and video rendering performance. ## Bug fixes - Fix re-render loops caused by inline `options` in the Tldraw component. - Fix toolbar button outline border-radius alignment. - Fix color preservation when pasting Excalidraw content. - Fix unhighlighted menu triggers. - Fix drag event type handling. - Fix duplicate image creation on canvas drops. - Fix link indicator visibility on sticky notes. - Fix URL parsing in embed dialogs. - Fix cross-instance rendering conflicts. - Fix menu options in read-only mode. [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v3.4.0) --- ## Patch releases ### v3.4.1 - Fix arrows being clipped incorrectly when multiple tldraw instances or exports are present in the DOM. ([#4819](https://github.com/tldraw/tldraw/pull/4819)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v3.4.1) -------- # v3.3.0 This release introduces sync improvements, readonly mode support, and various performance enhancements. ## What's new ### Readonly mode Servers can now restrict client editing while preserving presence updates using the new "readonly" mode. This enables use cases like view-only sharing and presentation modes where users can see each other's cursors but cannot modify the document. ### Sync server enhancements New `TLSocketRoom` methods (`closeSession`, `getRecord`, and `getSessions`) provide finer control over sync connections and room state management. ## API changes - Add editor option for quick action shortcut placement. - Add `editor.getIsReadonly()` helper method. ## Improvements - Pass wheel events through toolbar elements for improved scrolling/zooming. - Allow Command/Control modifier keys to enable multi-select (previously shift-only). - Allow text tool to be locked. - Improve draw shape rendering performance during zoom interactions. ## Bug fixes - Fix Safari arrow rendering. - Fix image drop navigation errors. - Fix watermark layering. - Fix geometry calculations. - Fix readonly mode label editing prevention. [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v3.3.0) --- ## Patch releases ### v3.3.1 - Fix meta key incorrectly triggering the shift key. ([#4703](https://github.com/tldraw/tldraw/pull/4703)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v3.3.1) ### v3.3.2 - Fix dropped images being created twice. ([#4727](https://github.com/tldraw/tldraw/pull/4727)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v3.3.2) ### v3.3.3 - Fix image duplication when dropping onto the canvas. ([#4789](https://github.com/tldraw/tldraw/pull/4789)) - Fix additional keyboard modifier issues. ([#4789](https://github.com/tldraw/tldraw/pull/4789)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v3.3.3) -------- # v3.2.0 This release contains no code changes. It was published to align version numbers across packages. See the [v3.1.0 release notes](/releases/v3.1.0) for information about changes since v3.0.x. [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v3.2.0) -------- # v3.15.0 This release introduces `npm create tldraw` for bootstrapping new projects, along with API additions, accessibility improvements, and performance optimizations. ## What's new ### npm create tldraw Developers can now initialize new tldraw projects by running `npm create tldraw` in their terminal, selecting from available starter templates. ## API changes - Add handle interaction callbacks: `onHandleDragStart`, `onHandleDragEnd`, and cancellation callbacks (`onTranslateCancel`, `onResizeCancel`, `onRotateCancel`, `onHandleDragCancel`). - Add JSX icon support for custom icons in tool overrides, action overrides, buttons, and menu items. - Add `StateNode.addChild` method enabling dynamic tool functionality additions. - Convert `DefaultSpinner` component to SVG format, now accepts standard SVG properties. - Export `HeartToolbarItem` component. ## Improvements - Enhance "Select All" functionality to intelligently select within a shape's common parent context (e.g., selecting shapes within a frame without selecting the frame itself). - Add user preference option to disable keyboard shortcuts. - Prevent frame drops. - Optimize the `useValue` and `useReactor` hooks. - Enhance frame rendering efficiency. - Expand `aria-hidden` application. - Improve keyboard navigation. - Add proper `role="radiogroup"` assignment for toggle groups. - Correct aria slider values. ## Bug fixes - Fix HTML entity escaping in pasted content. - Fix text measurement accuracy. - Fix arrow rendering between circles. - Fix SVG text outline rendering. - Fix image toolbar camera movement interactions. [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v3.15.0) --- ## Patch releases ### v3.15.1 - Fix room change event handling in the sync core library. ([#6543](https://github.com/tldraw/tldraw/pull/6543)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v3.15.1) ### v3.15.2 - Fix editor remounting in a loop when given custom assetUrls. ([#6605](https://github.com/tldraw/tldraw/pull/6605)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v3.15.2) ### v3.15.3 - Enhance callback functionality for shape utilities. ([#6634](https://github.com/tldraw/tldraw/pull/6634)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v3.15.3) ### v3.15.4 - Fix potential bug in TLSyncClient. ([#6660](https://github.com/tldraw/tldraw/pull/6660)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v3.15.4) ### v3.15.5 - Show license flags message as a warning. ([#6843](https://github.com/tldraw/tldraw/pull/6843)) - Fix expired internal license verification. ([#6843](https://github.com/tldraw/tldraw/pull/6843)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v3.15.5) -------- # v3.14.0 This release introduces contextual toolbars for image and video shapes, enhanced cropping options, and a new PathBuilder API. ## API changes - 💥 **`Editor#getShapePageGeometry`** removed. - 💥 **`Editor#getShapesAtPoint`** now returns shapes in descending index order. - 💥 **Locked shapes** cannot be duplicated; pasting locked shapes unlocks them. - 💥 **`ShapeUtil.canDropShapes`** removed—drag-and-drop participation now requires implementing handlers. - Add `TldrawUiContextualToolbar` component enabling developers to create floating toolbars. - Add `PathBuilder` API for constructing tldraw-style inky and dashed SVGs. - Add arrow binding configuration for controlling when arrows should be exact and/or bind. - Add `measureScrollWidth` option for text measurement. - Add `defaultAutoplay` boolean property for `VideoShapeUtil`. ## Improvements - Add image and video contextual toolbar with floating controls for enhanced interaction. - Add download functionality for image and video shapes to download original files. - Add advanced image cropping options. - Improve context menu keyboard support. - Improve style panel keyboard navigation. - Improve focus management. - Optimize copy operations. - Optimize arrow rendering with labels. - Optimize shape resizing. - Optimize keyboard interactions. - Optimize arrow dragging. - Improve text measurement caching. ## Bug fixes - Fix page menu scrolling behavior. - Fix undo functionality for sticky creation. - Fix bookmark hyperlink handling. - Fix SVG output and vector calculations. - Fix frame resizing with multiple selections. - Fix HTML copy-paste positioning. - Fix keyboard shortcuts and text overflow issues. [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v3.14.0) --- ## Patch releases ### v3.14.1 - Fix text measurement bug where styles could leak from one measurement to the next. ([#6388](https://github.com/tldraw/tldraw/pull/6388)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v3.14.1) ### v3.14.2 - Fix HTML entities being escaped in clipboard operations. ([#6396](https://github.com/tldraw/tldraw/pull/6396)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v3.14.2) -------- # v3.13.0 This release introduces elbow arrows for technical diagramming and continues accessibility improvements toward WCAG compliance. ## What's new ### Elbow arrows The arrow shape now supports a new elbow connector style. These arrows travel between points using straight lines joined at right angles rather than curved paths, making them ideal for technical diagrams. Access this option through the arrow tool's line style settings. ## API changes - 💥 **`ShapeUtil.canEditInReadOnly`** renamed to `ShapeUtil.canEditInReadonly` (note capitalization change). - 💥 **Arrow target highlights** migrated from `setHintingShapes` to a custom `TldrawOverlays` component; users of `` must pass this component to the `Overlays` slot. - Add text measurement API that accepts arbitrary style parameters. - Add new `Overlays` component for camera-following canvas overlays. - Add `hasCustomTabBehavior` prop to `RichTextLabel` for custom tab logic. ## Improvements - Auto-select link text when editing shape links. - Snap pasted text and embeds to grid when enabled. - Allow Figma embeds to work with selection links. - Show visual block indicating label placement when editing arrow labels. - Include background color in single frame exports. - Allow frames to be double-click resized to fit contents. - Allow style panel to focus with keyboard shortcut. - Add proper labels to more UI icons and handles. - Add container navigation shortcuts for moving selections in/out of frames and groups. - Make embed shapes keyboard-tabbable. - Add keyboard navigation to toolbars throughout the application. - Show rich text editing shortcuts in the help menu. - Improve performance of programmatic rotation of selected shapes. - Improve performance of multi-shape dragging operations. - Optimize selection evaluation to prevent unnecessary re-evaluations. ## Bug fixes - Fix flattened shape backgrounds. - Fix screenreader behavior. - Fix tool consistency. - Fix text rendering. - Fix selection accuracy. - Fix arrow flickering during rotation. [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v3.13.0) --- ## Patch releases ### v3.13.1 - Show elbow arrow outline indicator on hover when creating elbow arrows. ([#6099](https://github.com/tldraw/tldraw/pull/6099)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v3.13.1) ### v3.13.2 - Fix LoadingScreen context bug where custom asset URL configuration was ignored. ([#6283](https://github.com/tldraw/tldraw/pull/6283)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v3.13.2) ### v3.13.3 - Fix overriding builtin tools not working. ([#6330](https://github.com/tldraw/tldraw/pull/6330)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v3.13.3) ### v3.13.4 - Fix cross-realm functionality issues. ([#6338](https://github.com/tldraw/tldraw/pull/6338)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v3.13.4) -------- # v3.12.0 This release focuses on accessibility improvements and API enhancements, with no breaking changes. ## API changes - Add new `getShapeVisibility` prop replacing the deprecated `isShapeHidden`, allowing hidden children to override parent visibility states. - Allow frames to display colorful borders and labels by configuring `FrameShapeUtil` with `showColors: true`. - Add `Geometry2d` helper methods including `intersectLineSegment`, `intersectCircle`, `transform`, and filtering options. - Export two Tiptap extensions individually for rich text customization. ## Improvements - Add keyboard-based selection movement between shapes using Tab and Cmd/Ctrl+Arrow keys. - Add screen reader announcements for tool and shape selection changes. - Add keyboard resizing capability via Cmd/Ctrl+Alt+Shift with +/- keys. - Improve semantic HTML5 tags and proper ARIA roles throughout the UI. - Simplify keyboard shortcut syntax (e.g., `'?!l'` becomes `'alt+shift+l'`). - Add atomic `Store.mergeRemoteChanges` with correct scope-triggered side effects. - Add smoother drawing on slower CPUs via `getCoalescedEvents`. - Add YouTube embed support for time/loop parameters. - Add optional asset URL overrides for unused Embed shape icons. ## Bug fixes - Fix Firefox SVG pasting. - Fix TailwindCSS text export styling. - Fix image pasting efficiency. - Fix Miro shape compatibility. - Fix Safari trackpad zoom. - Fix performance regressions in rich text and iPad drawing. [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v3.12.0) --- ## Patch releases ### v3.12.1 - Fix group bounds containing text shapes. ([#5911](https://github.com/tldraw/tldraw/pull/5911)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v3.12.1) ### v3.12.2 - Restore DPR constrained shape dimensions. ([#6034](https://github.com/tldraw/tldraw/pull/6034)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v3.12.2) -------- # v3.11.0 This release addresses rich text issues following v3.10, adds zoom improvements, and introduces accessibility enhancements. ## API changes - 💥 **`editor.user.getName()`** no longer returns "New user" when unnamed; returns empty string instead. - 💥 **`defaultUserPreferences.name`** changed from "New user" to empty string. - Export `RichTextSVG` from the package. ## Improvements - Add a new minimum zoom step at 5%. - Add keyboard shortcuts (Shift +/Shift -) for zooming toward your cursor. - Add option to hit Enter to continue editing after selection in the style panel. - Improve rich text rendering performance with many shapes. - Improve hiding/showing shape indicators on large projects. - Add page navigation shortcuts (option + arrows). - Add support for satellite mode in Google Map embeds. - Add focus rings for accessibility. - Add nonce support for the editor security. ## Bug fixes - Fix rich text numbered list geometry bounds. - Fix React 19 StrictMode compatibility. - Fix export styling issues. - Fix missing internationalization strings for rich text elements. [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v3.11.0) --- ## Patch releases ### v3.11.1 - Fix application of zoomSpeed setting to pinch gestures. ([#5696](https://github.com/tldraw/tldraw/pull/5696)) - Fix unexpected borders in exports from Tailwind CSS pages. ([#5696](https://github.com/tldraw/tldraw/pull/5696)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v3.11.1) ### v3.11.2 - Fix sync core bug. ([#6667](https://github.com/tldraw/tldraw/pull/6667)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v3.11.2) -------- # v3.10.0 This release introduces rich text as a first-class primitive within the Editor, alongside various performance improvements and bug fixes. ## What's new ### Rich text support The SDK now offers rich text as a first-class primitive. The implementation utilizes TipTap with its StarterKit extension plus additional customizations. Developers can configure this functionality through a `textOptions` property to customize TipTap and modify extensions. ## API changes - 💥 **`text` property** on most shapes replaced with `richText`. When setting values, use `richText: toRichText('some string')` instead of `text: 'some string'`. When retrieving values, use `renderPlaintextFromRichText(props.text)` rather than `props.text`. - Add asset rehydration for .tldr files containing embedded base64 data. - Add `BrokenAssetIcon` display on file upload failures. - Add public collaboration hooks (`usePeerIds`, `usePresence`). - Add `userId` parameter to collaboration components. ## Bug fixes - Fix performance regression affecting document loading. - Fix Firefox export/style embedding for foreignObjects. - Fix shape reparenting order preservation. - Fix resize functionality. - Fix Safari file pasting issues. - Fix SSR environment compatibility (core-js import removal). - Fix IME text duplication in Chrome. [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v3.10.0) --- ## Patch releases ### v3.10.1 - Fix API reference links in state packages. ([#5610](https://github.com/tldraw/tldraw/pull/5610)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v3.10.1) ### v3.10.2 - Add `textOptions` to `` component. ([#5650](https://github.com/tldraw/tldraw/pull/5650)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v3.10.2) ### v3.10.3 - Fix Inter font being embedded in exports. ([#5676](https://github.com/tldraw/tldraw/pull/5676)) - Reduce excessive styling in exported content. ([#5676](https://github.com/tldraw/tldraw/pull/5676)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v3.10.3) -------- # v3.1.0 This release introduces shape visibility control and server-side data manipulation capabilities, alongside API enhancements and bug fixes. ## What's new ### Shape visibility control ([#4570](https://github.com/tldraw/tldraw/pull/4570)) The new `isShapeHidden` predicate option prevents shapes from being rendered or reacting to pointer events. This is useful for implementing permission systems in collaborative applications where certain shapes should be invisible to specific users. ### Server-side document manipulation ([#4581](https://github.com/tldraw/tldraw/pull/4581)) The tldraw sync server now supports server-side document manipulation through the `updateShapes` method, enabling integration with third-party services and automated document updates. ## API changes - Add option to `Editor.rotateShapesBy` specifying rotation center point. - Add `useAsset` hook for resolving responsive asset versions. ## Bug fixes - Fix arrow label text measurement calculations. - Fix arrow collaborator indicators overlapping labels. - Fix binding processing error handling. - Fix watermark opacity and animation behavior. [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v3.1.0) -------- # v3.0.0 This release introduces a revised licensing model alongside deep links, enhanced image export, custom embeds, and a new text search API. ## What's new ### Licensing The most significant change involves updated licenses permitting use in both commercial and non-commercial projects when displaying a "Made with tldraw" watermark. Users can now purchase Business Licenses to remove the watermark, with details available at [tldraw.dev](https://tldraw.dev). ([#4449](https://github.com/tldraw/tldraw/pull/4449), [#4517](https://github.com/tldraw/tldraw/pull/4517), [#4561](https://github.com/tldraw/tldraw/pull/4561)) ### Deep links New APIs enable creation of shareable URLs pointing to specific canvas locations, such as particular shapes or pages, with automatic URL updates as users navigate. ```typescript // Create a deep link to a specific shape const url = editor.createDeepLink({ shapeId: 'shape-id', viewport: 'fit', }) // The URL updates automatically as you navigate editor.on('change', () => { const currentUrl = editor.getCurrentDeepLink() }) ``` See the [deep links guide](https://tldraw.dev/docs/editor#Deep-links) for more information. ([#4498](https://github.com/tldraw/tldraw/pull/4498)) ### Enhanced image export Custom shapes now export as images by default through HTML/CSS embedding within SVG files, eliminating the need for developers to implement custom SVG rendering methods. ```typescript // Custom shapes automatically export as images class MyShapeUtil extends ShapeUtil { // No need to implement toSvg() anymore component(shape: MyShape) { return
{/* ... */}
} } ``` ### Custom embeds API Developers can now customize which external websites (YouTube, Google Maps, CodeSandbox, etc.) appear as embeddable content, or add entirely new embed types. ```typescript // Add a custom embed type const customEmbedDef = { type: 'custom', title: 'My Custom Embed', hostnames: ['mysite.com'], toEmbedUrl: (url: string) => `https://mysite.com/embed/${url}`, fromEmbedUrl: (url: string) => url.replace('/embed/', '/') } ``` ### Text search via getText API A new `getText` API provides reliable access to human-readable shape content, facilitating text search implementation within applications. ```typescript // Search through all shapes for text content const searchResults = editor.getCurrentPageShapes().filter((shape) => { const text = editor.getText(shape.id) return text?.toLowerCase().includes(searchTerm.toLowerCase()) }) ``` ## API changes - 💥 **`TLRotationSnapshot`** type removed from the public API. Use `editor.getShapePageTransform(shape).rotation()` instead. - 💥 **`onEditorMount`** callback in `createTLStore` renamed to `onMount` for consistency. - 💥 **`Editor.mark()`** deprecated in favor of `Editor.markHistoryStoppingPoint()` for clearer intent. - 💥 **`TLSvgOptions`** type renamed to `TLImageExportOptions` to better reflect its broader use in image export. - 💥 **Focus event behavior**: Calling `updateInstanceState({isFocused: true})` now triggers standard focus events consistently. Use `editor.focus()` for reliable focus behavior. - Add `editor.getText(shapeId)` method for accessing shape text content. - Add `editor.createDeepLink(options)` for generating shareable URLs. - Add `embedDefs` prop to Tldraw component for customizing embed types. - Expose additional shape export utilities for custom image generation. ## Improvements - Improve bookmark rendering for URLs without preview images. ([#4460](https://github.com/tldraw/tldraw/pull/4460)) - Improve handling of asset storage and persistence. ([#4542](https://github.com/tldraw/tldraw/pull/4542)) - Improve documentation search functionality. ([#4485](https://github.com/tldraw/tldraw/pull/4485)) - Refine watermark appearance and behavior. ([#4589](https://github.com/tldraw/tldraw/pull/4589), [#4622](https://github.com/tldraw/tldraw/pull/4622)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v3.0.0) --- ## Patch releases ### v3.0.1 - Fix documentation search functionality and article issues. ([#4515](https://github.com/tldraw/tldraw/pull/4515)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v3.0.1) ### v3.0.2 - Fix build caching issue causing "You have multiple versions of tldraw libraries installed" errors. ([#4525](https://github.com/tldraw/tldraw/pull/4525)) - Fix container null error. ([#4524](https://github.com/tldraw/tldraw/pull/4524)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v3.0.2) ### v3.0.3 - Fix bugs in the editor and tldraw packages. ([#4541](https://github.com/tldraw/tldraw/pull/4541)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v3.0.3) -------- # v2.4.0 This release introduces our sync engine as a general-use library, new animation options for shapes, support for image flipping, and many bug fixes and developer experience enhancements. ## What's new ### Sync ([#4031](https://github.com/tldraw/tldraw/pull/4031)) For the first time, we're releasing our real-time collaboration engine—the one we developed for tldraw.com—as a general library. The SDK still supports any backend for collaboration, but we hope this will be the easiest option for developers. See the new `sync` package in the repository and the multiplayer-demo example. ### Interpolation ([#4162](https://github.com/tldraw/tldraw/pull/4162)) You can use `Editor.animateShapes` to animate shapes on the canvas. Previously only position and rotation would animate. Now you can implement `ShapeUtil.getInterpolatedProps` to describe how your custom shape's other properties should animate. ```ts override getInterpolatedProps( startShape: Shape, endShape: Shape, t: number ): Shape['props'] { return { ...endShape.props, w: lerp(startShape.props.w, endShape.props.w, t), h: lerp(startShape.props.h, endShape.props.h, t), } } ``` ### Editor.run ([#4042](https://github.com/tldraw/tldraw/pull/4042)) The new `Editor.run` method runs a function within additional context. By default, the function runs inside a transaction, meaning all changes settle at once—improving performance and avoiding unnecessary renders. You can also use options to ignore history or ignore locked shapes. ```ts editor.run( () => { editor.createShapes(myShapes) editor.sendToBack(myShapes) editor.selectNone() }, { history: 'ignore' } ) ``` ### Assets As part of our work on sync, we have a new system for handling large assets like images and videos. Provide a [`TLAssetStore`](https://tldraw.dev/reference/tlschema/TLAssetStore) to control how assets are uploaded and retrieved. Use [`Editor.uploadAsset`](https://tldraw.dev/reference/editor/Editor#uploadAsset) and [`Editor.resolveAssetURL`](https://tldraw.dev/reference/editor/Editor#resolveAssetUrl) in your shapes and tools. ## API changes - 💥 **`editor.history.ignore(cb)`** replaced with `editor.run(cb, {history: 'ignore'})`. - 💥 **`editor.batch`** deprecated, replaced with `editor.run`. - 💥 **`@tldraw/state` imports**: If you're importing from `@tldraw/state` directly, the `track` function and all hooks (e.g. `useValue`) have moved to `@tldraw/state-react`. ([#4170](https://github.com/tldraw/tldraw/pull/4170)) - Add `DefaultMenuPanel` export. ([#4193](https://github.com/tldraw/tldraw/pull/4193)) - Make `fileSize` property of `TLImageAsset` and `TLVideoAsset` optional. ([#4206](https://github.com/tldraw/tldraw/pull/4206)) - Allow passing partial `TLEditorSnapshot` to `TldrawImage` and `useTLStore`. ([#4190](https://github.com/tldraw/tldraw/pull/4190)) - Make `EffectScheduler` and `useStateTracking` public. ([#4155](https://github.com/tldraw/tldraw/pull/4155)) - Add `setDefaultValue` to `StyleProp`. ([#4044](https://github.com/tldraw/tldraw/pull/4044)) - Add `ShapeUtil.getInterpolatedProps`. ([#4162](https://github.com/tldraw/tldraw/pull/4162)) - Add `Editor.run`, replacing `Editor.batch`. ([#4042](https://github.com/tldraw/tldraw/pull/4042)) ## Improvements - Add horizontal and vertical flipping for images. ([#4113](https://github.com/tldraw/tldraw/pull/4113)) - Allow custom tools to decide whether they are affected by shape lock. ([#4208](https://github.com/tldraw/tldraw/pull/4208)) - Serve icons as a single SVG instead of many individual requests. ([#4150](https://github.com/tldraw/tldraw/pull/4150)) - Make paste-at-point behavior based on a user preference. ([#4104](https://github.com/tldraw/tldraw/pull/4104)) - Show toast when uploading an unsupported file type or file that's too large. ([#4114](https://github.com/tldraw/tldraw/pull/4114)) - Show toast when pasting fails due to missing clipboard permissions. ([#4117](https://github.com/tldraw/tldraw/pull/4117)) - Add `ShapeIndicators` component for custom logic about when to display indicators. ([#4083](https://github.com/tldraw/tldraw/pull/4083)) - Animate shape opacity changes. ([#4242](https://github.com/tldraw/tldraw/pull/4242)) ## Bug fixes - Fix font style export to SVG. ([#4195](https://github.com/tldraw/tldraw/pull/4195)) - Fix `force` flag for camera methods. ([#4214](https://github.com/tldraw/tldraw/pull/4214)) - Show user's color scheme in menu by default. ([#4184](https://github.com/tldraw/tldraw/pull/4184)) - Fix padding for dynamically scaled text shapes. ([#4140](https://github.com/tldraw/tldraw/pull/4140)) - Fix `cameraOptions` via React causing editor to re-mount. ([#4089](https://github.com/tldraw/tldraw/pull/4089)) - Allow high-res images to be uploaded. ([#4198](https://github.com/tldraw/tldraw/pull/4198)) - Prevent locked shapes from being updated, grouped, or ungrouped programmatically. ([#4042](https://github.com/tldraw/tldraw/pull/4042)) - Fix `snapshots` prop in `createTLStore`. ([#4233](https://github.com/tldraw/tldraw/pull/4233)) - Fix grid backgrounds with multiple tldraw instances. ([#4132](https://github.com/tldraw/tldraw/pull/4132)) - Fix inputs staying in place while viewport-following. ([#4108](https://github.com/tldraw/tldraw/pull/4108)) - Fix bookmarks rendering across devices. ([#4118](https://github.com/tldraw/tldraw/pull/4118)) - Fix `InFrontOfTheCanvas` component stack order. ([#4024](https://github.com/tldraw/tldraw/pull/4024)) - Fix frame headers not stopping edit on focus loss. ([#4092](https://github.com/tldraw/tldraw/pull/4092)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v2.4.0) --- ## Patch releases ### v2.4.1 - Fix `assets` prop on `` and `` components not being respected. ([#4285](https://github.com/tldraw/tldraw/pull/4285)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v2.4.1) ### v2.4.2 - Fix bugs and improve the sync engine and related packages. ([#4309](https://github.com/tldraw/tldraw/pull/4309)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v2.4.2) ### v2.4.3 - Fix bugs in the tldraw package. ([#4328](https://github.com/tldraw/tldraw/pull/4328)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v2.4.3) ### v2.4.4 - Fix bugs in the editor, sync, tldraw, and tlschema packages. ([#4352](https://github.com/tldraw/tldraw/pull/4352)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v2.4.4) ### v2.4.5 - Fix unhandled promise rejection during strict mode in the editor. ([#4407](https://github.com/tldraw/tldraw/pull/4407)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v2.4.5) ### v2.4.6 - Improve rendering performance in the store and tldraw packages. ([#4434](https://github.com/tldraw/tldraw/pull/4434)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v2.4.6) -------- # v2.3.0 This release focuses on image and video storage improvements, a new fonts/icons CDN, image performance optimizations, and a new flatten feature. ## What's new ### Image and video storage improvements ([#3836](https://github.com/tldraw/tldraw/pull/3836)) When using local-only storage, images and videos are now stored in a separate IndexedDB table instead of as base64-encoded blobs in the room's JSON. This significantly improves performance and reduces the size of room data. ### Fonts and icons CDN ([#3923](https://github.com/tldraw/tldraw/pull/3923)) Improved our CDN for assets (fonts and icons). We were using unpkg before, but now we're using Cloudflare directly for more fine-grained control and better performance. ([#3927](https://github.com/tldraw/tldraw/pull/3927)) ### Image level-of-detail ([#3827](https://github.com/tldraw/tldraw/pull/3827)) For higher-resolution images (over a couple megabytes), the image gets transformed to an appropriate size depending on your viewport, zoom level, and network speed. This helps with bandwidth and browser memory usage when you have multiple high-res images on the board. ### Flatten ([#3933](https://github.com/tldraw/tldraw/pull/3933)) You can now select multiple shapes and flatten them into a single image. For those moments when you need to press things together. ### Security improvements ([#3884](https://github.com/tldraw/tldraw/pull/3884)) Locked down referrer network requests to make sure we weren't leaking tldraw rooms to external media/iframe requests. ([#3881](https://github.com/tldraw/tldraw/pull/3881)) ## API changes - Add fill-fill style, accessible via `Alt`+`F`. ([#3966](https://github.com/tldraw/tldraw/pull/3966)) - Make `ArrowBindingUtil` public. ([#3913](https://github.com/tldraw/tldraw/pull/3913)) - Add `getSnapshot` and `loadSnapshot` methods to `Editor` class. ([#3912](https://github.com/tldraw/tldraw/pull/3912)) ## Improvements - Allow users to use system appearance (dark/light) mode. ([#3703](https://github.com/tldraw/tldraw/pull/3703)) - Remove ability to rename document while in readonly mode. ([#3911](https://github.com/tldraw/tldraw/pull/3911)) - Add delay and easing to edge scrolling. ([#3950](https://github.com/tldraw/tldraw/pull/3950)) ## Bug fixes - Fix copy/paste for older versions of Firefox. ([#4008](https://github.com/tldraw/tldraw/pull/4008)) - Fix copy/paste in Firefox 127+. ([#4003](https://github.com/tldraw/tldraw/pull/4003)) - Fix not allowing editing locked shapes when switching edit modes. ([#4007](https://github.com/tldraw/tldraw/pull/4007)) - Fix text shape measurement in React strict mode. ([#4001](https://github.com/tldraw/tldraw/pull/4001)) - Fix border color for following user. ([#3975](https://github.com/tldraw/tldraw/pull/3975)) - Fix scale issue with new draw lines. ([#3971](https://github.com/tldraw/tldraw/pull/3971)) - Fix edge scrolling at odd browser zoom levels. ([#3973](https://github.com/tldraw/tldraw/pull/3973)) - Fix appearance of solid-style heart shapes. ([#3963](https://github.com/tldraw/tldraw/pull/3963)) - Fix position of multiple assets when pasted/dropped onto canvas. ([#3965](https://github.com/tldraw/tldraw/pull/3965)) - Fix indicator for stylus-drawn draw shapes. ([#3962](https://github.com/tldraw/tldraw/pull/3962)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v2.3.0) -------- # v2.2.0 This release introduces the bindings system, camera constraints, and configurable options—major features that unlock new types of applications you can build with tldraw. ## What's new ### Bindings ([#3326](https://github.com/tldraw/tldraw/pull/3326)) Bindings allow you to create relationships between shapes. Our default arrow shapes are a great example: each end of the arrow can bind to another shape. When that shape moves, so does the arrow. Before this change, arrows were hard-coded into the library. Now, with the bindings system, you can create arrows, constraint systems, visual programming environments, and much more. Check out the [bindings guide](https://tldraw.dev/docs/editor#Bindings) for more information. ([#3780](https://github.com/tldraw/tldraw/pull/3780)) ([#3797](https://github.com/tldraw/tldraw/pull/3797)) ([#3800](https://github.com/tldraw/tldraw/pull/3800)) ([#3871](https://github.com/tldraw/tldraw/pull/3871)) ### Camera constraints ([#3282](https://github.com/tldraw/tldraw/pull/3282)) You can now limit the camera to a fixed area of the canvas. This is useful for creating experiences that don't quite fit the "infinite canvas" paradigm: document annotators, image editors, slideshow creators, and more. See the [camera constraints guide](https://tldraw.dev/docs/editor#Camera-options) for more information. ([#3747](https://github.com/tldraw/tldraw/pull/3747)) ([#3814](https://github.com/tldraw/tldraw/pull/3814)) ### Configurable options ([#3799](https://github.com/tldraw/tldraw/pull/3799)) You can now override many options which were previously hard-coded constants. Pass an `options` prop into the tldraw component to change the maximum number of pages, grid steps, or other previously hard-coded values. See [`TldrawOptions`](https://tldraw.dev/reference/editor/TldrawOptions) for details. ([#3900](https://github.com/tldraw/tldraw/pull/3900)) ### 💥 Undo/redo changes The history system has been significantly reworked: 1. **History options simplified**: `squashing`, `ephemeral`, and `preserveRedoStack` flags have been consolidated. Use `editor.history.ignore(fn)` or `editor.history.batch(fn, {history: 'record-preserveRedoStack'})` instead. 2. **Automatic recording**: Everything that touches the store is now recorded in undo/redo (unless part of `mergeRemoteChanges`). Use `editor.history.ignore(fn)` for changes you don't want recorded. 3. **Side effects captured**: Changes in side-effects are now captured by undo/redo. Wrap in `editor.history.ignore` for the old behavior. ## API changes - 💥 **`canBind`** now accepts an options object instead of just the shape. See [`TLShapeUtilCanBindOpts`](https://tldraw.dev/reference/editor/TLShapeUtilCanBindOpts). - 💥 **`editor.sideEffects.registerBatchCompleteHandler`** replaced with `editor.sideEffects.registerOperationCompleteHandler`. ([#3748](https://github.com/tldraw/tldraw/pull/3748)) - 💥 **`editor.getArrowInfo(shape)`** replaced with `getArrowInfo(editor, shape)`. - 💥 **`editor.getArrowsBoundTo(shape)`** removed—use `editor.getBindingsToShape(shape, 'arrow')` instead. - 💥 **Arrow shape `start` and `end` properties** are now always points. Use `getArrowBindings(editor, shape)` to check for bindings. - 💥 **Types renamed**: `ShapeProps` → `RecordProps`, `ShapePropsType` → `RecordPropsType`, `TLShapePropsMigrations` → `TLPropsMigrations`, `SchemaShapeInfo` → `SchemaPropsInfo`. - Add `editor.blur` method. ([#3875](https://github.com/tldraw/tldraw/pull/3875)) - Add better defaults for `createTLStore`. ([#3886](https://github.com/tldraw/tldraw/pull/3886)) - Add `getSnapshot` and `loadSnapshot` for easier document persistence. See [State Snapshots](https://tldraw.dev/docs/persistence#State-Snapshots). ([#3811](https://github.com/tldraw/tldraw/pull/3811)) - Add `select` option to `Editor.groupShapes` and `Editor.ungroupShapes`. ([#3690](https://github.com/tldraw/tldraw/pull/3690)) - `InFrontOfTheCanvas` now has access to the editor's UI context. ([#3782](https://github.com/tldraw/tldraw/pull/3782)) - `useEditor` and other context-based hooks now throw an error when used out-of-context. ([#3750](https://github.com/tldraw/tldraw/pull/3750)) - Add `defaultShapeSchemas` for custom multiplayer implementations. ([#3613](https://github.com/tldraw/tldraw/pull/3613)) ## Improvements - Add a heart shape to the geo shape set. ([#3787](https://github.com/tldraw/tldraw/pull/3787)) - Improve rendering for bookmarks without preview images. ([#3856](https://github.com/tldraw/tldraw/pull/3856)) - Improve undo/redo UX around image cropping. ([#3891](https://github.com/tldraw/tldraw/pull/3891)) - Increase default limit of shapes per page from 2000 to 4000. ([#3716](https://github.com/tldraw/tldraw/pull/3716)) - Expand accepted image types to include webp, webm, apng, and avif. ([#3730](https://github.com/tldraw/tldraw/pull/3730)) - Prune unused assets when loading `.tldr` files. ([#3689](https://github.com/tldraw/tldraw/pull/3689)) - Improve handling of mouse-type devices that support pressure (e.g., Wacom tablets). ([#3639](https://github.com/tldraw/tldraw/pull/3639)) - Change text shapes to be left-aligned by default. ([#3627](https://github.com/tldraw/tldraw/pull/3627)) - Add Desmos graph embed type. ([#3608](https://github.com/tldraw/tldraw/pull/3608)) ## Bug fixes - Fix 'insert media' undo removing other changes. ([#3910](https://github.com/tldraw/tldraw/pull/3910)) - Fix referrer being sent for bookmarks and images. ([#3881](https://github.com/tldraw/tldraw/pull/3881)) - Fix minimum drag distance being wrong when zoomed. ([#3873](https://github.com/tldraw/tldraw/pull/3873)) - Fix cropped images not exporting properly. ([#3837](https://github.com/tldraw/tldraw/pull/3837)) - Fix spacebar and middle mouse button panning. ([#3791](https://github.com/tldraw/tldraw/pull/3791)) ([#3792](https://github.com/tldraw/tldraw/pull/3792)) - Fix cursor and shapes wiggling when following someone's viewport. ([#3695](https://github.com/tldraw/tldraw/pull/3695)) - Fix cross-browser focus management issues. ([#3718](https://github.com/tldraw/tldraw/pull/3718)) - Fix imports in Astro. ([#3742](https://github.com/tldraw/tldraw/pull/3742)) - Fix copy/paste for patterned shapes as SVG/PNG. ([#3708](https://github.com/tldraw/tldraw/pull/3708)) - Fix RTL text layout for SVG exports. ([#3680](https://github.com/tldraw/tldraw/pull/3680)) - Fix clicking on minimap sometimes not changing viewport. ([#3617](https://github.com/tldraw/tldraw/pull/3617)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v2.2.0) --- ## Patch releases ### v2.2.1 - Improve documentation and make `ArrowBindingUtil` public. ([#3958](https://github.com/tldraw/tldraw/pull/3958)) - Add `editor.getSnapshot()` and `editor.loadSnapshot()` methods. ([#3958](https://github.com/tldraw/tldraw/pull/3958)) - Fix CSS styling for bookmark elements. ([#3958](https://github.com/tldraw/tldraw/pull/3958)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v2.2.1) ### v2.2.2 - Fix text measurement breaking when `Tldraw` was used with React strict mode. ([#4004](https://github.com/tldraw/tldraw/pull/4004)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v2.2.2) ### v2.2.3 - Fix copy/paste functionality in Firefox 127+. ([#4006](https://github.com/tldraw/tldraw/pull/4006)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v2.2.3) ### v2.2.4 - Fix copy/paste functionality for older versions of Firefox. ([#4011](https://github.com/tldraw/tldraw/pull/4011)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v2.2.4) -------- # v2.1.0 This release includes completely redesigned sticky notes, an overhaul to our migration system, and significant performance improvements. ## What's new ### New stickies ([#3249](https://github.com/tldraw/tldraw/pull/3249)) Sticky notes have been completely redesigned with a fresh look and improved functionality. ### 💥 New migrations ([#3220](https://github.com/tldraw/tldraw/pull/3220)) The migrations system has been overhauled for better reliability and developer experience. - The `Migrations` type is now called `LegacyMigrations` - The serialized schema format (returned by `StoreSchema.serialize()` and `Store.getSnapshot()`) has changed - `compareRecordVersions` and `RecordVersion` have been removed - `compareSchemas` is gone—use `schema.getMigrationsSince(prevSchema)` instead - `defineMigrations` has been deprecated. See [updating legacy shape migrations](https://tldraw.dev/docs/persistence#Updating-legacy-shape-migrations-defineMigrations) for upgrade instructions - `migrate` has been removed ### 💥 Input buffering ([#3223](https://github.com/tldraw/tldraw/pull/3223)) Events are now buffered and sent to state nodes every tick, instead of immediately. This unlocks big performance improvements but could introduce subtle issues with custom tools—make sure to test any custom tools thoroughly. ### 💥 React-powered SVG exports ([#3117](https://github.com/tldraw/tldraw/pull/3117)) If any of your shapes implement `toSvg` for exports, you'll need to replace your implementation with a new version that returns JSX instead of manually constructing SVG DOM nodes. `editor.getSvg` is deprecated. Use `editor.getSvgElement` or `editor.getSvgString` instead. ### 💥 Component-based toolbar customization ([#3067](https://github.com/tldraw/tldraw/pull/3067)) If you're using the `toolbar` callback to override toolbar items, switch to using the new `Toolbar` component override. See the [custom toolbar example](https://tldraw.dev/examples/ui/custom-toolbar) for details. ## API changes - 💥 **`getRenderingShapes`** no longer returns `isCulled`—use `getCulledShapes` instead. - Add `Editor.getStyleForNextShape`. ([#3039](https://github.com/tldraw/tldraw/pull/3039)) - Add `usePreloadAssets` export. ([#3545](https://github.com/tldraw/tldraw/pull/3545)) ## Improvements - Improve color contrast. ([#3486](https://github.com/tldraw/tldraw/pull/3486)) - Add long press event. ([#3275](https://github.com/tldraw/tldraw/pull/3275)) - Add severity colors and icons to toasts. ([#2988](https://github.com/tldraw/tldraw/pull/2988)) - Improve handling of broken images/videos. ([#2990](https://github.com/tldraw/tldraw/pull/2990)) - Improve performance of draw shapes. ([#3464](https://github.com/tldraw/tldraw/pull/3464)) - Use WebGL to draw the minimap. ([#3510](https://github.com/tldraw/tldraw/pull/3510)) - Improve reactivity bookkeeping performance. ([#3471](https://github.com/tldraw/tldraw/pull/3471)) ([#3487](https://github.com/tldraw/tldraw/pull/3487)) - Improve selection/erasing performance. ([#3454](https://github.com/tldraw/tldraw/pull/3454)) - Improve performance of text shapes on iOS/Safari. ([#3429](https://github.com/tldraw/tldraw/pull/3429)) - Reduce rendered DOM nodes for geo shapes and arrows. ([#3283](https://github.com/tldraw/tldraw/pull/3283)) - Improve shape rendering performance. ([#3176](https://github.com/tldraw/tldraw/pull/3176)) ## Bug fixes - Fix copy error sound in Safari. ([#3536](https://github.com/tldraw/tldraw/pull/3536)) - Fix arrow label positioning overlapping bound shapes. ([#3512](https://github.com/tldraw/tldraw/pull/3512)) - Fix cursor chat button appearing when not in select tool. ([#3485](https://github.com/tldraw/tldraw/pull/3485)) - Fix alt-duplicating shapes sometimes not working. ([#3488](https://github.com/tldraw/tldraw/pull/3488)) - Fix camera sliding after pinch. ([#3462](https://github.com/tldraw/tldraw/pull/3462)) - Fix text shapes overflowing their bounds when resized. ([#3327](https://github.com/tldraw/tldraw/pull/3327)) - Fix incorrectly rotated handles on rotated cropping images. ([#3093](https://github.com/tldraw/tldraw/pull/3093)) - Fix videos not being sized correctly. ([#3047](https://github.com/tldraw/tldraw/pull/3047)) - Fix `localStorage` crash in React Native webviews. ([#3043](https://github.com/tldraw/tldraw/pull/3043)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v2.1.0) --- ## Patch releases ### v2.1.1 - Fix missing export for `createShapePropsMigrationIds`, part of the new migrations API. ([#3594](https://github.com/tldraw/tldraw/pull/3594)) - Add exports for `defaultEditorAssetUrls`, `PORTRAIT_BREAKPOINT`, `useDefaultColorTheme`, and `getPerfectDashProps`. ([#3594](https://github.com/tldraw/tldraw/pull/3594)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v2.1.1) ### v2.1.2 - Revert a performance optimization that caused computed caches to sometimes not invalidate correctly, leading to stale data and crashes. ([#3611](https://github.com/tldraw/tldraw/pull/3611)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v2.1.2) ### v2.1.3 - Expose migrations, validators, and versions from tlschema. ([#3613](https://github.com/tldraw/tldraw/pull/3613)) - Add `defaultShapeSchemas` which can be passed directly to `createTLSchema`. ([#3613](https://github.com/tldraw/tldraw/pull/3613)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v2.1.3) ### v2.1.4 - Fix text selection flakiness when clicking into text shapes. ([#3643](https://github.com/tldraw/tldraw/pull/3643)) - Fix edit→edit not working correctly when unfilled geo shapes are on top of other shapes. ([#3643](https://github.com/tldraw/tldraw/pull/3643)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v2.1.4) -------- # v2.0.0 This is the initial public release of the tldraw SDK—a TypeScript library for creating infinite canvas experiences in React. After an extensive alpha and beta period, the SDK is ready for production use. ## What's new ### The editor At the heart of tldraw is the `Editor` class, a single object that manages all editor state and provides the API for programmatic control. The editor maintains document state through a reactive store system containing JSON-serializable records. ```tsx import { Tldraw } from 'tldraw' function App() { return ( { // Full programmatic control editor.createShapes([{ type: 'geo', x: 100, y: 100 }]) editor.selectAll() editor.zoomToFit() }} /> ) } ``` ### Default shapes The SDK ships with a complete set of default shapes: - **Geo shapes**: Rectangle, ellipse, triangle, diamond, pentagon, hexagon, octagon, star, rhombus, oval, trapezoid, arrow-shapes, cloud, and x-box - **Draw**: Freehand drawing with pressure sensitivity support - **Arrow**: Connectable arrows with labels, multiple arrowhead styles, and curved/straight/elbow routing - **Text**: Rich text with font, size, and alignment options - **Note**: Sticky notes with customizable colors - **Image & Video**: Media embedding with cropping support - **Frame**: Grouping containers that clip their contents - **Line**: Multi-point lines with various spline options - **Highlight**: Transparent highlight strokes - **Embed**: Web content embedding (YouTube, Figma, Google Maps, and more) - **Bookmark**: URL previews with metadata ### Default tools A full set of tools for interacting with the canvas: - **Select**: Selection, multi-select, resize, rotate, and transform shapes - **Hand**: Pan the canvas - **Draw**: Freehand drawing - **Eraser**: Remove shapes by drawing over them - **Arrow, Line, Geo, Text, Note, Frame, Highlight**: Shape creation tools - **Laser**: Temporary pointer for presentations - **Zoom**: Zoom in/out with click or marquee ### State management The SDK uses a reactive signals system for state management. All editor state is observable, with automatic dependency tracking to prevent unnecessary re-renders. ```tsx import { track, useEditor } from 'tldraw' const SelectedShapeCount = track(() => { const editor = useEditor() return
{editor.getSelectedShapeIds().length} selected
}) ``` ### The store Document data lives in a `TLStore`—a reactive client-side database that supports: - JSON-serializable records for shapes, pages, assets, and instance state - Reactive updates via signals - Snapshot export/import for persistence - Schema migrations for backwards compatibility ### Tool system Tools are implemented as hierarchical state machines using `StateNode`. Events flow through a state chart, enabling complex multi-step interactions: ```tsx class MyTool extends StateNode { static id = 'my-tool' onPointerDown(info) { const point = this.editor.inputs.currentPagePoint this.editor.createShape({ type: 'geo', x: point.x, y: point.y }) } } ``` ### Shape system Every shape type has a `ShapeUtil` class defining its behavior—geometry, rendering, interactions, and more. Create custom shapes by extending `ShapeUtil`: ```tsx class CardShapeUtil extends ShapeUtil { static type = 'card' getGeometry(shape) { return new Rectangle2d({ width: shape.props.w, height: shape.props.h }) } component(shape) { return
{shape.props.title}
} } ``` ### User interface A complete, responsive UI system with: - Toolbar with tool selection and shape-specific options - Style panel for colors, fills, fonts, and more - Context menus with shape actions - Keyboard shortcuts dialog - Page management - Zoom controls and minimap - Actions menu and quick actions bar - Help menu and debug panel All UI components can be overridden or extended via the `components` prop. ### Features - **Multi-page documents**: Create and manage multiple pages per document - **Undo/redo**: Full history management with marks and batching - **Copy/paste**: Between pages, documents, and external applications - **Export**: SVG, PNG, and JSON export - **Zoom & pan**: Pinch, scroll, keyboard shortcuts, and programmatic control - **Grid & snapping**: Align shapes to grid and each other - **Grouping**: Group shapes together - **Locking**: Prevent shape modification - **Duplication**: Alt-drag to duplicate - **Alignment & distribution**: Align and distribute selected shapes - **Flip**: Horizontal and vertical flipping - **Styles**: Color, fill, dash, size, font, and more - **Dark mode**: Full dark mode support - **Localization**: 30+ languages supported - **Accessibility**: Keyboard navigation and screen reader support - **Touch support**: Full touch and pen input support - **Pressure sensitivity**: For supported devices [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v2.0.0) --- ## Patch releases ### v2.0.1 - Avoid randomness at init time, improving consistency for SSR and testing scenarios. ([#3076](https://github.com/tldraw/tldraw/pull/3076)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v2.0.1) ### v2.0.2 - Fix JPG export functionality. ([#3199](https://github.com/tldraw/tldraw/pull/3199)) [View release on GitHub](https://github.com/tldraw/tldraw/releases/tag/v2.0.2) -------- # Next release This release adds 2D canvas rendering for shape indicators, R-tree spatial indexing for faster queries, telestrator-style laser behavior, a preference for inverting mouse wheel zoom direction, and improved sync performance. It also includes various bug fixes for collaborator indicators, hidden shape handling, and spatial indexing. ## What's new ### 2D canvas rendering for shape indicators ([#7708](https://github.com/tldraw/tldraw/pull/7708)) Shape indicators (selection outlines, hover states) now render using a 2D canvas instead of SVG elements. This significantly improves performance when selecting or hovering over many shapes, with up to 25x faster rendering in some scenarios. Custom shapes can opt into canvas indicators by implementing the new `getIndicatorPath()` method on their ShapeUtil: ```tsx class MyShapeUtil extends ShapeUtil { getIndicatorPath(shape: MyShape): TLIndicatorPath | null { return { path: new Path2D(), // optional clip path for complex shapes like arrows with labels } } // Return false to use the new canvas indicators (default is true for backwards compatibility) useLegacyIndicator(): boolean { return false } } ``` ### Invert mouse wheel zoom direction ([#7732](https://github.com/tldraw/tldraw/pull/7732)) Added a new user preference to invert mouse wheel zoom direction. Some users prefer "natural" scrolling behavior where scrolling down zooms out, which this option now enables. Access it via Menu → Preferences → Input device → Invert mouse zoom. ### R-tree spatial indexing ([#7676](https://github.com/tldraw/tldraw/pull/7676)) Shape queries now use an R-tree (RBush) for O(log n) lookups instead of O(n) iteration. This significantly improves performance of brushing, scribble selection, and erasing operations, especially with many shapes on the canvas. The spatial index is maintained internally and accessed through existing public methods like `editor.getShapesAtPoint()` and `editor.getShapeAtPoint()`. ### Telestrator-style laser pointer ([#7681](https://github.com/tldraw/tldraw/pull/7681)) The laser pointer now behaves like a telestrator: all strokes remain visible while you're drawing and fade together when you stop. Previously, each stroke segment would fade independently, creating a trailing effect. New API additions for controlling laser sessions: ```tsx // End the active laser session manually editor.scribbles.endLaserSession() // Check if a scribble belongs to the active session editor.scribbles.isScribbleInLaserSession(scribbleId) ``` New options in `TldrawOptions`: - `laserSessionTimeoutMs` (default: 2000ms) - Inactivity duration before the laser session ends - `laserMaxSessionDurationMs` (default: 60000ms) - Maximum duration for a laser session ## API changes - Remove `editor.spatialIndex` from public API. The spatial index is now internal; use `editor.getShapesAtPoint()` and `editor.getShapeAtPoint()` for shape queries. ([#7699](https://github.com/tldraw/tldraw/pull/7699)) - Add `ShapeUtil.getIndicatorPath()` method and `TLIndicatorPath` type for canvas-based indicator rendering. Add `ShapeUtil.useLegacyIndicator()` to control whether shapes use SVG or canvas indicators. ([#7708](https://github.com/tldraw/tldraw/pull/7708)) - Add `isZoomDirectionInverted` to `TLUserPreferences` interface and `UserPreferencesManager.getIsZoomDirectionInverted()` method. Add `ToggleInvertZoomItem` component export and `toggle-invert-zoom` action. ([#7732](https://github.com/tldraw/tldraw/pull/7732)) - Add `complete` to `TL_SCRIBBLE_STATES` enum and `ScribbleManager.complete(id)` method for marking scribbles as complete before fading. ([#7760](https://github.com/tldraw/tldraw/pull/7760)) - Add `ScribbleManager.endLaserSession()` and `ScribbleManager.isScribbleInLaserSession()` methods for controlling laser sessions. Add `laserSessionTimeoutMs` and `laserMaxSessionDurationMs` to `TldrawOptions`. ([#7681](https://github.com/tldraw/tldraw/pull/7681)) - Add `FpsScheduler` class to create FPS-throttled function queues with configurable target rates. ([#7418](https://github.com/tldraw/tldraw/pull/7418)) ## Improvements - Add R-tree spatial indexing for O(log n) shape queries, improving performance of brushing, selection, and erasing with many shapes. ([#7676](https://github.com/tldraw/tldraw/pull/7676)) - Improve laser pointer to keep all strokes visible during a session (telestrator pattern), with strokes fading together when drawing stops. ([#7681](https://github.com/tldraw/tldraw/pull/7681)) - Improve laser pointer strokes with proper taper when lifting the pointer by adding a 'complete' state to the scribble lifecycle. ([#7760](https://github.com/tldraw/tldraw/pull/7760)) - Reduce network traffic by squashing pending push requests before sending, so rapid edits result in fewer network calls. ([#7724](https://github.com/tldraw/tldraw/pull/7724)) - Reduce solo-mode network traffic by using a dedicated FPS-based scheduler that throttles to 1 FPS when no collaborators are present. ([#7657](https://github.com/tldraw/tldraw/pull/7657)) - Improve performance by separating UI and network scheduling into independent queues with configurable target FPS. ([#7418](https://github.com/tldraw/tldraw/pull/7418)) - Improve frame label sizing on smaller viewports and when zoomed out. ([#7746](https://github.com/tldraw/tldraw/pull/7746)) ## Bug fixes - Fix `zoomToFit` and `getCurrentPageBounds` to ignore hidden shapes when computing bounds. ([#7770](https://github.com/tldraw/tldraw/pull/7770)) - Fix collaborator shape indicators not rendering after the canvas indicator change. ([#7759](https://github.com/tldraw/tldraw/pull/7759)) - Fix rich text content not updating correctly with message squashing due to reference comparison. ([#7758](https://github.com/tldraw/tldraw/pull/7758)) - Fix keyboard shortcut menu item labels to use consistent ellipsis formatting. ([#7757](https://github.com/tldraw/tldraw/pull/7757)) - Fix spatial index not removing shapes when moved to a different page. ([#7700](https://github.com/tldraw/tldraw/pull/7700))