Skip to main content

Overview

The AppState is a comprehensive interface that represents the entire UI and editor state of an Excalidraw instance. It manages everything from the currently active tool and selected elements to zoom levels, theme preferences, and dialog visibility.

AppState Structure

The AppState contains over 100 properties organized into logical categories:
packages/excalidraw/types.ts

Core State Categories

Manages the currently active tool and its configuration:
packages/excalidraw/types.ts

Default App State

Excalidraw provides a getDefaultAppState() function that initializes all properties:
packages/excalidraw/appState.ts

Style Properties

AppState stores default styles that apply to newly created elements:
packages/excalidraw/types.ts

UI State Management

Dialogs and Menus

packages/excalidraw/types.ts

Toast Notifications

Collaboration State

packages/excalidraw/types.ts

State Persistence

Excalidraw provides functions to filter AppState for different storage contexts:
packages/excalidraw/appState.ts
The storage behavior is controlled by APP_STATE_STORAGE_CONF in appState.ts:

Canvas State Types

Excalidraw defines specialized AppState subsets for different rendering contexts:

Static Canvas State

packages/excalidraw/types.ts

Interactive Canvas State

packages/excalidraw/types.ts
These specialized types ensure that rendering functions only access the state properties they need.

Helper Functions

packages/excalidraw/appState.ts

Updating App State

When using the Excalidraw component, update state through the imperative API:
Never mutate AppState directly. Always create new state objects or use the updateScene API.

Observable App State

For performance optimization, Excalidraw tracks observable state that external components may need to react to:
packages/excalidraw/types.ts

Frame Rendering State

Search and Navigation State

packages/excalidraw/types.ts

Cropping State

Export State

Best Practices

  • Always create new state objects rather than mutating existing ones
  • Use the updateScene API for state changes that should trigger re-renders
  • Batch multiple state changes in a single updateScene call
  • Filter state appropriately when persisting to storage
  • Use specialized canvas state types to minimize re-renders
  • Subscribe to observable state changes only for necessary UI updates
  • Avoid deep state comparisons in hot paths
  • Use memoization for derived state calculations
  • Never store local UI state in collaboration sync
  • Keep collaborator data lightweight
  • Use proper socket ID typing for type safety
  • Handle collaborator state cleanup on disconnect
  • Elements - Element structure and management
  • Scene - Scene state management and element collections
  • Collaboration - Multi-user state synchronization