TLSyncClient

See source code
Table of contents

Main client-side synchronization engine for collaborative tldraw applications.

TLSyncClient manages bidirectional synchronization between a local tldraw Store and a remote sync server. It uses an optimistic update model where local changes are immediately applied for responsive UI, then sent to the server for validation and distribution to other clients.

The synchronization follows a git-like push/pull/rebase model:

  • Push: Local changes are sent to server as diff operations
  • Pull: Server changes are received and applied locally
  • Rebase: Conflicting changes are resolved by undoing local changes, applying server changes, then re-applying local changes on top
class TLSyncClient<R extends UnknownRecord, S extends Store<R> = Store<R>> {}

Example

import { createTLStore } from '@tldraw/store'
import { ClientWebSocketAdapter, TLSyncClient } from '@tldraw/sync-core'

// Create store and socket
const store = createTLStore({ schema: mySchema })
const socket = new ClientWebSocketAdapter('ws://localhost:3000/sync')

// Create sync client
const syncClient = new TLSyncClient({
  store,
  socket,
  presence: atom(null),
  onLoad: () => console.log('Connected and loaded'),
  onSyncError: (reason) => console.error('Sync failed:', reason),
})

// Changes to store are now automatically synchronized
store.put([{ id: 'shape1', type: 'geo', x: 100, y: 100 }])
// Advanced usage with presence and custom messages
const syncClient = new TLSyncClient({
  store,
  socket,
  presence: atom({ cursor: { x: 0, y: 0 }, userName: 'Alice' }),
  presenceMode: atom('full'),
  onCustomMessageReceived: (data) => {
    if (data.type === 'chat') {
      showChatMessage(data.message, data.from)
    }
  },
  onAfterConnect: (client, { isReadonly }) => {
    if (isReadonly) {
      showNotification('Connected in read-only mode')
    }
  },
})

Constructor

Creates a new TLSyncClient instance to manage synchronization with a remote server.

Parameters

NameDescription

config

{
  didCancel?(): boolean
  onAfterConnect?(
    self: TLSyncClient<R, S>,
    details: {
      isReadonly: boolean
    }
  ): void
  onCustomMessageReceived?: TLCustomMessageHandler
  onLoad(self: TLSyncClient<R, S>): void
  onSyncError(reason: string): void
  presence: Signal<null | R>
  presenceMode?: Signal<TLPresenceMode>
  socket: TLPersistentClientSocket<any, any>
  store: S
}

Configuration object for the sync client

  • store - The local tldraw store to synchronize
  • socket - WebSocket adapter for server communication
  • presence - Reactive signal containing current user's presence data
  • presenceMode - Optional signal controlling presence sharing (defaults to 'full')
  • onLoad - Callback fired when initial sync completes successfully
  • onSyncError - Callback fired when sync fails with error reason
  • onCustomMessageReceived - Optional handler for custom messages
  • onAfterConnect - Optional callback fired after successful connection
  • self - The TLSyncClient instance
  • details - Connection details including readonly status
  • didCancel - Optional function to check if sync should be cancelled

Methods

close( )

Closes the sync client and cleans up all resources.

Call this method when you no longer need the sync client to prevent memory leaks and close the WebSocket connection. After calling close(), the client cannot be reused.

close(): void

Example

// Clean shutdown
syncClient.close()

Prev
TLSocketRoom
Next
ArrowBindingUtil