Skip to main content

Excalidraw Component API

The Excalidraw component is the main React component that renders the complete Excalidraw editor. This page provides a comprehensive API reference for all available props, callbacks, and imperative API methods.

Import

import { Excalidraw } from "@excalidraw/excalidraw";

Props Reference

Core Props

onChange
function
Callback fired when elements, appState, or files change. This is the primary way to track changes to the scene.
onChange?: (
  elements: readonly OrderedExcalidrawElement[],
  appState: AppState,
  files: BinaryFiles,
) => void;
Parameters:
  • elements - Array of all elements in the scene (ordered by z-index)
  • appState - Current application state
  • files - Binary files (images) used in the scene
onIncrement
function
Called on every state increment, both durable (user actions) and ephemeral (temporary states like dragging).
onIncrement?: (event: DurableIncrement | EphemeralIncrement) => void;
Use this for fine-grained change tracking or implementing custom undo/redo.
initialData
object | function | Promise
Initial scene data to load when the component mounts. Can be an object, function, or Promise.
initialData?:
  | (() => MaybePromise<ExcalidrawInitialDataState | null>)
  | MaybePromise<ExcalidrawInitialDataState | null>;
ExcalidrawInitialDataState structure:
{
  elements?: ExcalidrawElement[];
  appState?: Partial<AppState>;
  scrollToContent?: boolean;
  libraryItems?: LibraryItems;
  files?: BinaryFiles;
}
excalidrawAPI
function
Callback to receive the Excalidraw imperative API instance. Use this to programmatically control the editor.
excalidrawAPI?: (api: ExcalidrawImperativeAPI) => void;
See Imperative API section below for available methods.
children
React.ReactNode
Custom components to render inside Excalidraw. Can include MainMenu, WelcomeScreen, Footer, Sidebar, or any custom React components.
children?: React.ReactNode;

Appearance Props

theme
'light' | 'dark'
Sets the editor theme. When not provided, users can toggle between themes using the theme button.
theme?: Theme; // "light" | "dark"
viewModeEnabled
boolean
default:"false"
When true, renders the editor in view-only mode with no editing capabilities. Useful for displaying existing diagrams.
viewModeEnabled?: boolean;
zenModeEnabled
boolean
default:"false"
When true, hides the UI chrome (toolbars, menus) for a distraction-free experience. Users can still toggle this manually.
zenModeEnabled?: boolean;
gridModeEnabled
boolean
default:"false"
When true, shows a grid on the canvas. Elements can snap to grid when this is enabled.
gridModeEnabled?: boolean;
objectsSnapModeEnabled
boolean
When true, enables snapping to other objects on the canvas.
objectsSnapModeEnabled?: boolean;
name
string
Name of the document/scene. Used as the default filename when exporting.
name?: string;

Behavior Props

autoFocus
boolean
default:"false"
When true, automatically focuses the canvas on mount, enabling immediate keyboard interaction.
autoFocus?: boolean;
detectScroll
boolean
default:"true"
When true, detects scrolling outside the canvas to prevent accidental page scrolls.
detectScroll?: boolean;
handleKeyboardGlobally
boolean
default:"false"
When true, keyboard shortcuts work globally instead of only when canvas is focused.
handleKeyboardGlobally?: boolean;
Use with caution as this may interfere with other keyboard interactions on the page.
renderScrollbars
boolean
Controls whether to render scrollbars on the canvas. By default, scrollbars are rendered.
renderScrollbars?: boolean;

Collaboration Props

isCollaborating
boolean
default:"false"
Indicates whether the editor is in collaboration mode. This affects UI elements and behavior.
isCollaborating?: boolean;
onPointerUpdate
function
Callback fired when the user’s pointer position changes. Essential for implementing real-time collaboration.
onPointerUpdate?: (payload: {
  pointer: { x: number; y: number; tool: "pointer" | "laser" };
  button: "down" | "up";
  pointersMap: Gesture["pointers"];
}) => void;
Payload:
  • pointer.x, pointer.y - Scene coordinates of the pointer
  • pointer.tool - Current tool (“pointer” or “laser”)
  • button - Mouse button state
  • pointersMap - Map of all active pointers (for multi-touch)

Event Callbacks

onPaste
function
Called when paste is triggered. Return true to prevent the default paste behavior.
onPaste?: (
  data: ClipboardData,
  event: ClipboardEvent | null,
) => Promise<boolean> | boolean;
ClipboardData structure:
  • text - Plain text from clipboard
  • elements - Excalidraw elements if pasting from another Excalidraw instance
  • files - File objects if pasting images
onDuplicate
function
Called when elements are duplicated via mouse-drag, keyboard, paste, or library insert. Return modified elements to override the default duplication behavior.
onDuplicate?: (
  nextElements: readonly ExcalidrawElement[],
  prevElements: readonly ExcalidrawElement[],
) => ExcalidrawElement[] | void;
Parameters:
  • nextElements - All elements including the duplicates
  • prevElements - Elements before duplication (excludes duplicated elements)
You should return all elements (including deleted ones) if making changes. Do not mutate elements directly.
onPointerDown
function
Called on pointer down events.
onPointerDown?: (
  activeTool: AppState["activeTool"],
  pointerDownState: PointerDownState,
) => void;
onPointerUp
function
Called on pointer up events.
onPointerUp?: (
  activeTool: AppState["activeTool"],
  pointerDownState: PointerDownState,
) => void;
onScrollChange
function
Called when the canvas scroll position or zoom level changes.
onScrollChange?: (scrollX: number, scrollY: number, zoom: Zoom) => void;
Parameters:
  • scrollX - Horizontal scroll position
  • scrollY - Vertical scroll position
  • zoom - Zoom object with value property
onUserFollow
function
Called when the current user follows or unfollows a collaborator.
onUserFollow?: (payload: OnUserFollowedPayload) => void;
OnUserFollowedPayload:
{
  userToFollow: UserToFollow;
  action: "FOLLOW" | "UNFOLLOW";
}

Library & File Management

onLibraryChange
function
Called when the library items change (add, remove, update).
onLibraryChange?: (libraryItems: LibraryItems) => void | Promise<any>;
Use this to persist library items to your backend or local storage.
generateIdForFile
function
Custom function to generate IDs for uploaded files. If not provided, Excalidraw generates random IDs.
generateIdForFile?: (file: File) => string | Promise<string>;
Useful when you need deterministic file IDs or want to integrate with your storage system.
libraryReturnUrl
string
URL to return to after opening the public library. Used in the libraries.excalidraw.com integration.
libraryReturnUrl?: string;
Called when a link element is clicked. Use this to handle link clicks with custom logic.
onLinkOpen?: (
  element: NonDeletedExcalidrawElement,
  event: CustomEvent<{
    nativeEvent: MouseEvent | React.PointerEvent<HTMLCanvasElement>;
  }>,
) => void;
If provided, default link opening behavior is disabled.
Generate a custom link for selected element(s). This enables users to create shareable links to specific elements or groups.
generateLinkForSelection?: (id: string, type: "element" | "group") => string;
Parameters:
  • id - Element ID or group ID
  • type - Whether it’s a single element or a group

Embedding

validateEmbeddable
boolean | string[] | RegExp | RegExp[] | function
Controls which URLs can be embedded as iframe elements.
validateEmbeddable?:
  | boolean
  | string[]
  | RegExp
  | RegExp[]
  | ((link: string) => boolean | undefined);
Options:
  • true - Allow all embeds
  • false - Disable all embeds
  • string[] - Array of allowed domains (e.g., ["youtube.com", "twitter.com"])
  • RegExp or RegExp[] - Regex pattern(s) for allowed URLs
  • function - Custom validation function
Be cautious when allowing embeds as they can pose security risks.
renderEmbeddable
function
Custom renderer for embeddable elements. Override the default iframe rendering.
renderEmbeddable?: (
  element: NonDeleted<ExcalidrawEmbeddableElement>,
  appState: AppState,
) => JSX.Element | null;

Custom UI Rendering

renderTopLeftUI
function
Render custom UI in the top-left corner of the editor (above the toolbar).
renderTopLeftUI?: (
  isMobile: boolean,
  appState: UIAppState,
) => JSX.Element | null;
renderTopRightUI
function
Render custom UI in the top-right corner of the editor.
renderTopRightUI?: (
  isMobile: boolean,
  appState: UIAppState,
) => JSX.Element | null;
renderCustomStats
function
Render custom content in the statistics panel (shown when elements are selected).
renderCustomStats?: (
  elements: readonly NonDeletedExcalidrawElement[],
  appState: UIAppState,
) => JSX.Element;

UI Configuration

UIOptions
object
Configure which UI elements are displayed and their behavior.
UIOptions?: {
  dockedSidebarBreakpoint?: number;
  canvasActions?: CanvasActions;
  tools?: {
    image?: boolean;
  };
  getFormFactor?: (
    editorWidth: number,
    editorHeight: number,
  ) => "desktop" | "tablet" | "phone";
};
UIOptions.dockedSidebarBreakpoint
number
Minimum editor width in pixels before sidebars can be docked. Below this width, sidebars always render as overlays.
dockedSidebarBreakpoint?: number;
UIOptions.canvasActions
object
Control visibility of canvas action buttons in the menu.
canvasActions?: {
  changeViewBackgroundColor?: boolean;
  clearCanvas?: boolean;
  export?: false | ExportOpts;
  loadScene?: boolean;
  saveToActiveFile?: boolean;
  toggleTheme?: boolean | null;
  saveAsImage?: boolean;
};
ExportOpts:
{
  saveFileToDisk?: boolean;
  onExportToBackend?: (
    exportedElements: readonly NonDeletedExcalidrawElement[],
    appState: UIAppState,
    files: BinaryFiles,
  ) => void;
  renderCustomUI?: (
    exportedElements: readonly NonDeletedExcalidrawElement[],
    appState: UIAppState,
    files: BinaryFiles,
    canvas: HTMLCanvasElement,
  ) => JSX.Element;
}
UIOptions.tools.image
boolean
default:"true"
When false, hides the image tool from the toolbar.
tools?: {
  image?: boolean;
};
UIOptions.getFormFactor
function
Custom function to determine the editor’s form factor. This affects UI layout and behavior.
getFormFactor?: (
  editorWidth: number,
  editorHeight: number,
) => "desktop" | "tablet" | "phone";
If not provided, Excalidraw determines this automatically based on viewport size.

Advanced Props

langCode
string
default:"en"
Language code for internationalization. Supported languages include: en, es, fr, de, pt, ru, zh, ja, ko, ar, hi, it, nl, pl, tr, vi, and more.
langCode?: Language["code"];
aiEnabled
boolean
default:"true"
When false, disables AI features like text-to-diagram and mermaid-to-diagram.
aiEnabled?: boolean;
showDeprecatedFonts
boolean
When true, shows deprecated font options in the font family selector.
showDeprecatedFonts?: boolean;

Imperative API

The imperative API is provided via the excalidrawAPI prop callback:
function App() {
  const [excalidrawAPI, setExcalidrawAPI] = useState(null);

  return (
    <Excalidraw excalidrawAPI={(api) => setExcalidrawAPI(api)} />
  );
}

Scene Methods

updateScene
function
Update elements and/or app state.
updateScene: (sceneData: {
  elements?: readonly ExcalidrawElement[];
  appState?: Partial<AppState>;
  collaborators?: Map<SocketId, Collaborator>;
  captureUpdate?: CaptureUpdateActionType;
}) => void;
resetScene
function
Clear the canvas and reset state.
resetScene: (opts?: {
  resetScroll?: boolean;
  resetZoom?: boolean;
}) => void;
getSceneElements
function
Get current non-deleted elements.
getSceneElements: () => readonly NonDeletedExcalidrawElement[];
getSceneElementsIncludingDeleted
function
Get all elements including deleted ones.
getSceneElementsIncludingDeleted: () => readonly ExcalidrawElement[];
getSceneElementsMapIncludingDeleted
function
Get elements as a Map for efficient lookup.
getSceneElementsMapIncludingDeleted: () => Map<string, ExcalidrawElement>;
applyDeltas
function
Apply incremental updates to elements.
applyDeltas: (
  elementDeltas: readonly ExcalidrawElementDelta[],
  options?: {
    captureUpdate?: CaptureUpdateActionType;
  },
) => void;
mutateElement
function
Mutate a single element.
mutateElement: (
  element: ExcalidrawElement,
  updates: Partial<ExcalidrawElement>,
  captureUpdate?: CaptureUpdateActionType,
) => void;

State Methods

getAppState
function
Get the current app state.
getAppState: () => AppState;
getName
function
Get the scene name.
getName: () => string;

File Methods

getFiles
function
Get binary files (images) used in the scene.
getFiles: () => BinaryFiles;
addFiles
function
Add binary files to the scene.
addFiles: (data: BinaryFileData[]) => void;

Library Methods

updateLibrary
function
Update library items programmatically.
updateLibrary: (opts: {
  libraryItems: LibraryItems;
  merge?: boolean;
  prompt?: boolean;
  openLibraryMenu?: boolean;
  defaultStatus?: "published" | "unpublished";
}) => Promise<LibraryItems>;

UI Methods

setActiveTool
function
Change the active tool programmatically.
setActiveTool: (tool: {
  type: ToolType | "custom";
  customType?: string;
  locked?: boolean;
}) => void;
ToolType: “selection” | “lasso” | “rectangle” | “diamond” | “ellipse” | “arrow” | “line” | “freedraw” | “text” | “image” | “eraser” | “hand” | “frame” | “magicframe” | “embeddable” | “laser”
setCursor
function
Set a custom cursor.
setCursor: (cursor: string) => void;
resetCursor
function
Reset to the default cursor.
resetCursor: () => void;
toggleSidebar
function
Toggle a sidebar’s visibility.
toggleSidebar: (opts: {
  name: SidebarName;
  tab?: SidebarTabName;
  force?: boolean;
}) => boolean;
setToast
function
Show a toast notification.
setToast: (toast: {
  message: string;
  closable?: boolean;
  duration?: number;
} | null) => void;

Utility Methods

refresh
function
Force re-render of the scene.
refresh: () => void;
scrollToContent
function
Scroll to view specific elements.
scrollToContent: (
  elements?: readonly ExcalidrawElement[],
  opts?: {
    fitToViewport?: boolean;
    animate?: boolean;
    duration?: number;
  },
) => void;
getEditorInterface
function
Get the editor interface details.
getEditorInterface: () => EditorInterface;
EditorInterface:
{
  formFactor: "desktop" | "tablet" | "phone";
  isMobile: boolean;
  canFitSidebar: boolean;
}
updateFrameRendering
function
Control frame rendering settings.
updateFrameRendering: (opts: {
  enabled: boolean;
  name?: boolean;
  outline?: boolean;
  clip?: boolean;
}) => void;
Use this in conjunction with viewModeEnabled to disable frame rendering.
registerAction
function
Register a custom action.
registerAction: (action: Action) => void;
history.clear
function
Clear undo/redo history.
history: {
  clear: () => void;
};
id
string
Unique ID of the Excalidraw instance.
id: string;

Event Listeners

The API also provides methods to subscribe to events. All event listener methods return an unsubscribe function.
onChange
function
Listen to changes. Returns unsubscribe function.
onChange: (
  callback: (
    elements: readonly ExcalidrawElement[],
    appState: AppState,
    files: BinaryFiles,
  ) => void,
) => UnsubscribeCallback;
onIncrement
function
Listen to increments. Returns unsubscribe function.
onIncrement: (
  callback: (event: DurableIncrement | EphemeralIncrement) => void,
) => UnsubscribeCallback;
onPointerDown
function
Listen to pointer down events. Returns unsubscribe function.
onPointerDown: (
  callback: (
    activeTool: AppState["activeTool"],
    pointerDownState: PointerDownState,
    event: React.PointerEvent<HTMLElement>,
  ) => void,
) => UnsubscribeCallback;
onPointerUp
function
Listen to pointer up events. Returns unsubscribe function.
onPointerUp: (
  callback: (
    activeTool: AppState["activeTool"],
    pointerDownState: PointerDownState,
    event: PointerEvent,
  ) => void,
) => UnsubscribeCallback;
onScrollChange
function
Listen to scroll/zoom changes. Returns unsubscribe function.
onScrollChange: (
  callback: (scrollX: number, scrollY: number, zoom: Zoom) => void,
) => UnsubscribeCallback;
onUserFollow
function
Listen to user follow events. Returns unsubscribe function.
onUserFollow: (
  callback: (payload: OnUserFollowedPayload) => void,
) => UnsubscribeCallback;

Complete Example

import { useState, useEffect } from "react";
import { Excalidraw } from "@excalidraw/excalidraw";

function App() {
  const [excalidrawAPI, setExcalidrawAPI] = useState(null);

  // Handle changes
  const handleChange = (elements, appState, files) => {
    console.log("Scene updated", { elements, appState, files });
  };

  // Use API after it's ready
  useEffect(() => {
    if (excalidrawAPI) {
      // Subscribe to changes
      const unsubscribe = excalidrawAPI.onChange((elements, appState, files) => {
        console.log("API onChange", elements.length);
      });

      // Set active tool
      excalidrawAPI.setActiveTool({ type: "rectangle" });

      // Show toast
      excalidrawAPI.setToast({
        message: "Welcome to Excalidraw!",
        duration: 3000,
      });

      return () => unsubscribe();
    }
  }, [excalidrawAPI]);

  return (
    <div style={{ height: "100vh" }}>
      <Excalidraw
        excalidrawAPI={(api) => setExcalidrawAPI(api)}
        onChange={handleChange}
        initialData={{
          elements: [],
          appState: {
            viewBackgroundColor: "#ffffff",
          },
        }}
        theme="light"
        name="My Diagram"
        gridModeEnabled={false}
        UIOptions={{
          canvasActions: {
            changeViewBackgroundColor: true,
            clearCanvas: true,
            export: { saveFileToDisk: true },
            loadScene: true,
            toggleTheme: true,
          },
        }}
      />
    </div>
  );
}

export default App;

Type Definitions

For complete TypeScript type definitions, see the source:
import type {
  ExcalidrawProps,
  ExcalidrawImperativeAPI,
  ExcalidrawElement,
  AppState,
  BinaryFiles,
  LibraryItems,
} from "@excalidraw/excalidraw/types";

See Also