Documentation Index
Fetch the complete documentation index at: https://mintlify.com/tldraw/tldraw/llms.txt
Use this file to discover all available pages before exploring further.
The Tldraw and TldrawEditor components are the primary React components for integrating tldraw into your application.
Tldraw
The complete “batteries included” tldraw component with UI, shapes, and tools.
import { Tldraw } from 'tldraw'
import 'tldraw/tldraw.css'
function App() {
return (
<div style={{ position: 'fixed', inset: 0 }}>
<Tldraw />
</div>
)
}
Props
store
TLStore | TLStoreWithStatus
A store to use for the editor’s data. If not provided, a new store will be created.const store = createTLStore({ shapeUtils: [...] })
<Tldraw store={store} />
shapeUtils
TLAnyShapeUtilConstructor[]
Array of custom shape utility classes. These will be merged with the default shapes.<Tldraw shapeUtils={[MyCustomShapeUtil]} />
bindingUtils
TLAnyBindingUtilConstructor[]
Array of custom binding utility classes for managing shape relationships.
Array of custom tool classes. These will be merged with the default tools.<Tldraw tools={[MyCustomTool]} />
Custom React components to override default UI elements.<Tldraw
components={{
Toolbar: MyCustomToolbar,
KeyboardShortcutsDialog: null, // Disable keyboard shortcuts dialog
Scribble: MyCustomScribble
}}
/>
Callback that fires when the editor is mounted and ready.<Tldraw
onMount={(editor) => {
console.log('Editor ready!', editor)
editor.createShape({ type: 'geo', x: 100, y: 100 })
}}
/>
The initial active tool or state. Defaults to ‘select’.<Tldraw initialState="draw" />
Whether to automatically focus the editor when it mounts. Defaults to true.
Whether to infer dark mode from the user’s system preferences. Defaults to false.
Hide all UI elements. Useful when you want to build a completely custom UI.
Custom URLs for assets like icons and fonts.const assetUrls = {
icons: '/custom-icons/',
fonts: '/custom-fonts/'
}
<Tldraw assetUrls={assetUrls} />
Custom embed definitions for embedding external content.const customEmbeds = [
{
type: 'myembed',
title: 'My Custom Embed',
hostnames: ['mysite.com'],
// ... more configuration
}
]
<Tldraw embeds={customEmbeds} />
MIME types to accept for image uploads. Defaults to common image formats.
MIME types to accept for video uploads. Defaults to common video formats.
Maximum dimension (width or height) for uploaded images. Images larger than this will be resized.
Maximum file size in bytes for uploaded assets.
Complete example
import { Tldraw } from 'tldraw'
import 'tldraw/tldraw.css'
function MyApp() {
return (
<div style={{ position: 'fixed', inset: 0 }}>
<Tldraw
onMount={(editor) => {
// Add initial shapes
editor.createShapes([
{
type: 'geo',
x: 100,
y: 100,
props: { w: 100, h: 100, geo: 'rectangle' }
}
])
}}
components={{
Toolbar: () => <div>My Custom Toolbar</div>
}}
hideUi={false}
inferDarkMode={true}
/>
</div>
)
}
TldrawEditor
The core editor component without UI. Use this when you want complete control over the interface.
import { TldrawEditor } from '@tldraw/editor'
import '@tldraw/editor/editor.css'
function App() {
return (
<TldrawEditor
shapeUtils={defaultShapeUtils}
bindingUtils={defaultBindingUtils}
tools={defaultTools}
>
<YourCustomUI />
</TldrawEditor>
)
}
Props
store
TLStore | TLStoreWithStatus
required
A store instance for the editor’s data. Can be created with createTLStore.const store = createTLStore({
shapeUtils: defaultShapeUtils,
bindingUtils: defaultBindingUtils
})
<TldrawEditor store={store} />
shapeUtils
TLAnyShapeUtilConstructor[]
required
Array of shape utility classes. Unlike Tldraw, you must provide these explicitly.import { defaultShapeUtils } from 'tldraw'
<TldrawEditor shapeUtils={defaultShapeUtils} />
bindingUtils
TLAnyBindingUtilConstructor[]
required
Array of binding utility classes.import { defaultBindingUtils } from 'tldraw'
<TldrawEditor bindingUtils={defaultBindingUtils} />
tools
TLStateNodeConstructor[]
required
Array of tool classes.import { defaultTools } from 'tldraw'
<TldrawEditor tools={defaultTools} />
Custom React components for editor elements (not UI elements).<TldrawEditor
components={{
Scribble: MyCustomScribble,
ShapeIndicators: MyCustomIndicators,
Handles: MyCustomHandles
}}
/>
Callback when the editor is ready.
The initial active tool or state.
Whether to automatically focus the editor.
Editor configuration options including camera and text settings.
Example with custom UI
import { TldrawEditor, useEditor } from '@tldraw/editor'
import { defaultShapeUtils, defaultBindingUtils, defaultTools } from 'tldraw'
import '@tldraw/editor/editor.css'
function CustomToolbar() {
const editor = useEditor()
return (
<div style={{ position: 'absolute', top: 0, left: 0 }}>
<button onClick={() => editor.setCurrentTool('select')}>Select</button>
<button onClick={() => editor.setCurrentTool('draw')}>Draw</button>
<button onClick={() => editor.undo()}>Undo</button>
<button onClick={() => editor.redo()}>Redo</button>
</div>
)
}
function App() {
return (
<div style={{ position: 'fixed', inset: 0 }}>
<TldrawEditor
shapeUtils={defaultShapeUtils}
bindingUtils={defaultBindingUtils}
tools={defaultTools}
>
<CustomToolbar />
</TldrawEditor>
</div>
)
}
Accessing the editor instance
Use the useEditor hook to access the editor instance within child components:
import { useEditor } from '@tldraw/editor'
function MyComponent() {
const editor = useEditor()
const handleClick = () => {
const selectedShapes = editor.getSelectedShapes()
console.log('Selected:', selectedShapes)
}
return <button onClick={handleClick}>Log Selection</button>
}
Store creation
Create a store to persist data or control initialization:
import { createTLStore, defaultShapeUtils, defaultBindingUtils } from 'tldraw'
const store = createTLStore({
shapeUtils: defaultShapeUtils,
bindingUtils: defaultBindingUtils
})
// Load data from storage
const snapshot = localStorage.getItem('my-drawing')
if (snapshot) {
store.loadSnapshot(JSON.parse(snapshot))
}
// Save data to storage
store.listen((changes) => {
const snapshot = store.getSnapshot()
localStorage.setItem('my-drawing', JSON.stringify(snapshot))
})
function App() {
return <Tldraw store={store} />
}