Open-Source Wikis

/

tldraw

/

How to contribute

/

Debugging

tldraw/tldraw

Debugging

Where to look when things go wrong.

In-editor debug tools

The SDK ships a debug panel: packages/tldraw/src/lib/ui/components/DebugMenu/. The DefaultDebugPanel (packages/tldraw/src/lib/ui/components/DefaultDebugPanel.tsx) shows when the editor is in debug mode and exposes flags. Toggle it from the UI's debug menu.

packages/editor/src/lib/components/GeometryDebuggingView.tsx renders shape geometry, snap lines, and bounds on the canvas — useful when working on hit-testing or snapping.

Logging from the editor

packages/editor/src/lib/editor/managers/PerformanceManager/ collects performance traces. packages/utils/src/lib/PerformanceTracker.ts and packages/utils/src/lib/perf.ts expose helpers used throughout the runtime. Sentry integration lives in apps/dotcom/client/sentry.client.config.ts.

Reactive bugs

Most "stale state" or "doesn't update" bugs trace back to the reactive layer:

  • A component reading a value outside useValue or track doesn't subscribe to it.
  • A computed reading state inside unsafe__withoutCapture won't track that read.
  • A side-effect that mutates within a transact runs once at commit time, not at each put.

The @tldraw/state README in packages/state/ covers the model. The relevant source is in packages/state/src/lib/ (Atom.ts, Computed.ts, EffectScheduler.ts, transactions.ts, capture.ts).

Migration bugs

If a record fails to load, the most common cause is a missing migration step.

  1. Check packages/tlschema/src/store-migrations.ts for store-level migrations.
  2. Check the relevant shape's file (packages/tlschema/src/shapes/<TLKindShape>.ts) for shape-level migrations.
  3. Run yarn vitest run in packages/tlschema and read the failure in migrations.test.ts.

The migration framework is documented in packages/store/src/lib/migrate.ts.

Sync bugs

For multiplayer issues, the most useful files are:

  • packages/sync-core/src/lib/protocol.ts — wire format definitions.
  • packages/sync-core/src/lib/TLSyncRoom.ts — server-side merge engine.
  • packages/sync-core/src/lib/TLSyncClient.ts — client side.
  • packages/sync-core/src/lib/ClientWebSocketAdapter.ts — reconnection and backoff.

Tests for each are alongside the source. The integration test NodeSqliteSyncWrapper.integration.test.ts exercises the persistence path end-to-end.

Failing tests

  • yarn vitest run --grep "<name>" to isolate.
  • For e2e flake, yarn e2e-dotcom-x10 runs Playwright ten times.
  • Snapshot mismatches: prefer regenerating with --update-snapshots only when behavior intentionally changed (the AGENTS.md rule).

TypeScript errors

  • Always use yarn typecheck (the wrapper). internal/scripts/typecheck.ts refreshes generated assets first; bare tsc will fail on missing assets/.tsbuild outputs.
  • For tsserver profiling: yarn profile-tsserver.
  • For compile profiling: yarn profile-typescript.

Hot reload not working

yarn dev runs the dev servers via lazyrepo. If a package isn't rebuilding, check that:

  • The package is listed in yarn dev filters in the root package.json.
  • lazy.config.ts declares the right inputs/outputs for the task.

Sentry

The dotcom client (apps/dotcom/client) uses Sentry via sentry.client.config.ts. Releases are tagged using sentry-release-name.ts and sentry.properties.

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

Debugging – tldraw wiki | Factory