How tldraw is versioned

We do not follow SemVer.

  • Major version bumps are very rare and we reserve them for special changes that signify a paradigm shift of some kind.
  • Minor version bumps are released on a regular cadence - approximately monthly. They may contain breaking changes. We aim to make breaking changes as minimally disruptive as possible, but tldraw is actively evolving as we add new features. We recommend updating tldraw at a similar pace to our release cadence, and be sure to check the release notes.
  • Patch version bumps are for bugfixes and hotfixes that can't wait for the next cadence release.



textfields: for unfilled geo shapes fix edit->edit (#3577) (#3643)

  • Text labels: fix edit→edit not working as expected when unfilled geo shapes are on 'top' of other shapes.

Describe what your pull request does. If appropriate, add GIFs or images showing the before and after.

🐛 Bug Fix

  • @tldraw/editor, tldraw
    • textfields: for unfilled geo shapes fix edit->edit (#3577) #3643 (@mimecuvalo)

Authors: 1


Expose migrations, validators, and versions from tlschema (#3613)

Previously, we weren't exporting migrations & validators for our default shapes. This meant that it wasn't possible to make your own tlschema with both our default shapes and some of your own (e.g. for custom multiplayer). This fixes that by exposing all the migrations, validators, and versions from tlschema, plus defaultShapeSchemas which can be passed directly to createTLSchema

📚 SDK Changes

  • @tldraw/tlschema
    • Expose migrations, validators, and versions from tlschema #3613 (@SomeHats)

Authors: 1


Revert "[signia] Smart dirty checking of active computeds (#3516)" (#3611)

This performance optimisation introduced a regression where sometimes computed caches wouldn't get invalidated at the correct time, leading to stale data causing crashes. We're reverting the change for now.

🐛 Bug Fix

  • @tldraw/state
    • Revert "[signia] Smart dirty checking of active computeds (#3516)" #3611 (@SomeHats)

🏠 Internal

Authors: 1


fix migration exports (#3594)

We were missing an export createShapePropsMigrationIds, part of the new migrations API introduced in v2.1.0. This release fixes that, and also adds exports for a few extra APIs that we were using in our examples, but weren't exporting properly: defaultEditorAssetUrls, PORTRAIT_BREAKPOINT, useDefaultColorTheme, & getPerfectDashProps

🐛 Bug Fix

⚠️ Pushed to v2.1.x

Authors: 1


New stickies & performance improvements

This tldraw release has loads of performance improvements, plus completely redesigned sticky notes. Check out our release notes for for more details on those.

Breaking changes

New migrations (#3220)
  • The Migrations type is now called LegacyMigrations.

  • The serialized schema format (e.g. returned by StoreSchema.serialize() and Store.getSnapshot()) has changed. You don't need to do anything about it unless you were reading data directly from the schema for some reason. In which case it'd be best to avoid that in the future! We have no plans to change the schema format again (this time was traumatic enough) but you never know.

  • compareRecordVersions and the RecordVersion type have both disappeared. There is no replacement. These were public by mistake anyway, so hopefully nobody had been using it.

  • compareSchemas is gone. Comparing the schemas directly is no longer really possible since we introduced some fuzziness. The best thing to do now to check compatibility is to call schema.getMigraitonsSince(prevSchema) and it will return an error if the schemas are not compatible, an empty array if there are no migrations to apply since the prev schema, and a nonempty array otherwise.

    Generally speaking, the best way to check schema compatibility now is to call store.schema.getMigrationsSince(persistedSchema). This will throw an error if there is no upgrade path from the persistedSchema to the current version.

  • defineMigrations has been deprecated and will be removed in a future release. For upgrade instructions see updating legacy shape migrations

  • migrate has been removed. Nobody should have been using this but if you were you'll need to find an alternative. For migrating tldraw data, you should stick to using schema.migrateStoreSnapshot and, if you are building a nuanced sync engine that supports some amount of backwards compatibility, also feel free to use schema.migratePersistedRecord.

  • the Migration type has changed. If you need the old one for some reason it has been renamed to LegacyMigration. It will be removed in a future release.

  • the Migrations type has been renamed to LegacyMigrations and will be removed in a future release.

  • the SerializedSchema type has been augmented. If you need the old version specifically you can use SerializedSchemaV1

Input buffering (#3223)

Events are now buffered and sent to state nodes every tick, instead of immediately. This unlocks some big performance improvements, but could introduce some subtle issues with any custom tools you might have. Make sure you test any custom tools thoroughly!

React-powered SVG exports (#3117)
  1. 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.
  2. editor.getSvg is deprecated. It still works, but will be going away in a future release. Instead, use editor.getSvgElement or editor.getSvgString.
Component-based toolbar customisation API (#3067)

If you're using the toolbar callback to override the items in the toolbar at the bottom of the default tldraw UI, you need to switch to using the new Toolbar component override.

See the custom toolbar example for more details.


  • All-new sticky notes! (#3249)
  • Improve color contrast. (#3486)
  • Add long press event. (#3275)
  • Add white. It's a secret! (#3321)
  • Add severity colors and icons to toasts. (#2988)
  • Better handling of broken images / videos. (#2990)

API changes

  • Expose Editor.getStyleForNextShape - previously marked as internal. (#3039)
  • Expose usePreloadAssets. (#3545)
  • getRenderingShapes no longer returns isCulled. Instead, use getCulledShapes.

Bug fixes

  • Prevent copy error sound in safari. (#3536)
  • Fix arrow label positioning overlapping the shape the arrow is bound to. (#3512)
  • Fix cursor chat button appearing when not in select tool. (#3485)
  • Fix alt-duplicating shapes sometimes not working. (#3488)
  • Fix camera sliding after pinch. (#3462)
  • Hide edit link context menu option for locked shapes. (#3457)
  • Fix text shapes overflowing their bounds when resized (#3327)
  • Allow fully hiding the debug panel. (#3261)
  • Fix missing title attributes on toolbar items. (#3244)
  • Fix incorrectly rotated handles on rotated cropping images. (#3093)
  • Fix videos not being sized correctly. (#3047)
  • Fix autocomplete, autocapitalize, and autocorrect tags on text inputs. (#3038)
  • Fix cursor chat bubble position. (#3042)
  • Prevent localStorage crash in React Native webviews. (#3043)
  • Fix a rare crash with video shapes. (#3037)

Performance improvements

  • Improve performance of draw shapes. (#3464)
  • Improve icon preloading. (#3507)
  • Use WebGL to draw the minimap. (#3510)
  • Faster reactivity bookkeeping. (#3471, #3487)
  • Faster selection / erasing (#3454)
  • Improve performance of text shapes on iOS / Safari. (#3429)
  • Throttle updates to the hovered shape ID. (#3419)
  • Block browser hit tests while moving camera. (#3418)
  • Faster minimum distance checks. (#3401)
  • Don't trigger pointer move on zoom. (#3305)
  • Reduce rendered dom nodes for geo shape and arrows. (#3283)
  • Don't double squash undo/redo history entries. (#3182)
  • Batch tick events. (#3181)
  • Faster shape rendering. (#3176)
  • Faster selection rotated page bounds / page bounds. (#3178)
  • Prevent unnecessary handles renders. (#3172)
  • Faster rendering. (#2977)


  • Update Romanian translations. (#3269)
  • Update Hungarian translations. (#3049)



🐛 Bug Fix

⚠️ Pushed to v2.0.x

Authors: 2


🐛 Bug Fix

  • @tldraw/editor
    • [patch 2.0.1] Cherry-pick 'Avoid randomness at init time...' #3076 (@ds300)

⚠️ Pushed to v2.0.x

  • fetch main during patch publish (@ds300)
  • cherry-pick tooling changes too i guess (@ds300)

Authors: 1


⚠️ Pushed to main

📝 Documentation

Authors: 1

Edit this page