# tldraw v5.4.0 - Product: tldraw (https://whatsnew.fyi/product/tldraw) - Vendor: tldraw - Date: 2026-09-02 - Version: v5.4.0 - Original notes: https://github.com/tldraw/tldraw/releases/tag/v5.4.0 - Permalink: https://whatsnew.fyi/product/tldraw/releases/v5.4.0 What's New is an index, not a publisher: every entry below links to the vendor's own release notes, which are the authoritative source. Entries are labelled where they are hand-curated sample data, pre-releases, or drawn from a secondary source such as a developer blog. Reuse: the summaries, labels and curation here are © What's New. Quote freely with attribution and a link back; wholesale republication of the corpus is not permitted — terms: https://whatsnew.fyi/terms. The vendors' own release notes remain their publishers'. --- - **added** — Add 'center' as an Editor.alignShapes operation that applies center-horizontal and center-vertical operations together - **added** — Add tleditors, a reactive global registry of currently mounted editors - **added** — Add getOrInsert(key, defaultValue) and getOrInsertComputed(key, callback) methods to AtomMap - **added** — Add isPage(record) type guard to @tldraw/tlschema - **added** — Add iterateGraphemes(str) to @tldraw/utils for iterating string grapheme clusters - **added** — Add optional originating event argument to EmojiPickerProps.onSelect - **deprecated** — Deprecate useViewportHeight() hook in favor of reading window.visualViewport directly - **changed** — Shift-click an emoji in a comment's reaction palette to add several reactions without closing the palette - **changed** — Keyboard input now counts as collaborator presence activity to prevent peers from fading out while typing - **changed** — Move exportBackground default into TLInstance record type in @tldraw/tlschema - **changed** — Speed up editor hot paths with set lookups replacing array scans in selection and erasing checks - **changed** — Speed up signal reads in @tldraw/state by eliminating duplicate parent set scans - **changed** — Reduce per-signal memory use and per-flush allocations in @tldraw/state - **changed** — Reduce work and allocations in @tldraw/store history bookkeeping - **fixed** — Fix editor failing to load on browsers lacking Intl.Segmenter such as Firefox before 125 - **fixed** — Fix frame loop stopping permanently when a tick or frame listener threw - **fixed** — Fix crash when computing frame geometry if heading text could not be measured - **fixed** — Fix crash in hit testing when custom frame-like shape uses plain non-group geometry - **fixed** — Fix crash when pressing Enter with frame, video, or embed selected while geo, arrow, or text tool is active - **fixed** — Fix undo after cut also reverting the previous change This release adds a `center` operation to `Editor.alignShapes`, a `tleditors` registry of mounted editors, `iterateGraphemes` to `@tldraw/utils`, and two new reactive methods on `AtomMap`. It also deprecates `useViewportHeight`, speeds up the signals and store layers, and lands a broad reliability pass across the SDK, with over a hundred fixes to undo history, selection and tool interactions, cropping, arrows, the signals and store layers, sync, and local persistence. ##### API changes - 🔜 **`useViewportHeight()`** is deprecated. Read `window.visualViewport` directly instead. The hook returns only the visible viewport's bottom edge, and keeping a panel clear of the software keyboard generally needs the whole visible rectangle. ([#9826](https://github.com/tldraw/tldraw/pull/9826)) - Add `'center'` as an `Editor.alignShapes` operation. It applies the existing `'center-horizontal'` and `'center-vertical'` operations together, so shapes center on both axes in one command. ([#9074](https://github.com/tldraw/tldraw/pull/9074)) - Add `tleditors`, a reactive global registry of currently mounted editors. Use it to reach live editors from outside the React tree, for example from sidebar chrome or a keyboard shortcut handler. ([#9904](https://github.com/tldraw/tldraw/pull/9904)) ```tsx import { tleditors, useValue } from 'tldraw' const mounted = useValue('mounted editors', () => tleditors.getMounted(), []) ``` - Add `getOrInsert(key, defaultValue)` and `getOrInsertComputed(key, callback)` to `AtomMap`, matching the `Map` methods added in newer JavaScript runtimes. Both are reactive, and the callback only runs when the key is absent. ([#9752](https://github.com/tldraw/tldraw/pull/9752)) - Add `isPage(record)` to `@tldraw/tlschema`, a type guard that narrows an unknown record to `TLPage`, matching the guards already exported for the other record types. ([#9774](https://github.com/tldraw/tldraw/pull/9774)) - Add `iterateGraphemes(str)` to `@tldraw/utils`. It iterates a string's grapheme clusters, using `Intl.Segmenter` when it's available and falling back to code-point iteration when it isn't. ([#9896](https://github.com/tldraw/tldraw/pull/9896)) - `EmojiPickerProps.onSelect` now receives the originating event as an optional second argument. Custom reaction palettes can forward it to opt into shift multi-select. ([#9999](https://github.com/tldraw/tldraw/pull/9999)) ##### Improvements - Shift-click an emoji in a comment's reaction palette to add several reactions without the palette closing. A plain click still applies the reaction and closes the palette. ([#9999](https://github.com/tldraw/tldraw/pull/9999)) - Keyboard input now counts as collaborator presence activity, so peers no longer fade out and disappear while someone is typing. ([#9929](https://github.com/tldraw/tldraw/pull/9929)) - Reduce per-pointer-event allocations in `Group2d` and `Editor` hit-testing. ([#8600](https://github.com/tldraw/tldraw/pull/8600)) - Speed up editor hot paths: set lookups replace array scans in the selection side effect and the erasing check, `getCollaborators` makes a single pass over the presence records, and `getShapeUtil` only builds its assert message when the lookup fails. ([#10358](https://github.com/tldraw/tldraw/pull/10358)) - Speed up signal reads in `@tldraw/state`. Capturing a parent used to scan the capturing signal's parent set twice, once to check for the parent and again to add it. ([#9690](https://github.com/tldraw/tldraw/pull/9690)) - Reduce per-signal memory use and per-flush allocations in `@tldraw/state`. ([#10155](https://github.com/tldraw/tldraw/pull/10155)) - Reduce the work and allocations in `@tldraw/store` history bookkeeping, so squashing record diffs and filtering query history no longer build intermediate copies on every tick. ([#9689](https://github.com/tldraw/tldraw/pull/9689), [#9869](https://github.com/tldraw/tldraw/pull/9869)) - Move the `exportBackground` default (`true`) into the `TLInstance` record typ _[Truncated at 4000 characters — full notes: https://github.com/tldraw/tldraw/releases/tag/v5.4.0]_