Menu

Overview

Relevant source files

This page introduces the Excalidraw project, its purpose as a virtual whiteboard application, and the overall structure of the monorepo. It provides a high-level view of how the codebase is organized, the distinction between the npm library and the hosted application, and the foundational architecture. For detailed information about specific subsystems, refer to the child pages: Monorepo Structure and Workspaces, Package Architecture, Build System and Scripts, and Deployment and Distribution.

What is Excalidraw?

Excalidraw is an open-source virtual whiteboard application that enables users to create hand-drawn style diagrams, wireframes, and sketches. The project is distributed in two forms:

  1. npm Package (@excalidraw/excalidraw): A React component library that can be embedded into other applications
  2. Hosted Application (excalidraw.com): A full-featured web application with real-time collaboration, end-to-end encryption, and PWA support

The core library provides an infinite canvas-based whiteboard with support for various drawing tools (rectangles, ellipses, arrows, lines, free-draw), image embedding, shape libraries, localization, and export to multiple formats (PNG, SVG, .excalidraw JSON).

Sources: README.md58-88

Monorepo Structure

The Excalidraw codebase is organized as a Yarn workspaces monorepo, defined in package.json1-94 This structure separates concerns between reusable packages and the hosted application while enabling efficient development and build processes.

Workspace Configuration

The monorepo defines three workspace categories in package.json5-8:

Workspace PatternPurposeExample Packages
packages/*Core reusable packages published to npm@excalidraw/common, @excalidraw/excalidraw
excalidraw-appHosted application at excalidraw.comApplication with collaboration features
examples/*Integration examples and demosBrowser integration examples

Sources: package.json1-9 tsconfig.json20-32

Core Package Architecture

The monorepo contains five core packages with strict dependency ordering to prevent circular dependencies. This layered architecture ensures clean separation of concerns and enables independent versioning.

Package Descriptions

PackageLocationPrimary Responsibilities
@excalidraw/commonpackages/common/Shared constants, type utilities, common helpers
@excalidraw/mathpackages/math/Geometric calculations (curves, vectors, rectangles, points)
@excalidraw/elementpackages/element/Element data structures, binding system, delta store
@excalidraw/excalidrawpackages/excalidraw/Core React library, canvas rendering, actions, UI components
@excalidraw/utilspackages/utils/General-purpose utility functions

TypeScript Path Aliases

The tsconfig.json21-31 defines path aliases for all packages, enabling clean imports:

Sources: package.json55-59 tsconfig.json20-32

Library vs Application

The codebase produces two distinct artifacts with different purposes and feature sets:

@excalidraw/excalidraw (npm Library)

The core library package published to npm provides a React component that can be integrated into any application. It includes:

  • Canvas-based infinite whiteboard
  • Drawing tools (rectangle, ellipse, diamond, arrow, line, free-draw, eraser)
  • Element manipulation (selection, transformation, styling)
  • Image support
  • Shape libraries
  • Localization (i18n)
  • Export to PNG, SVG, clipboard
  • Undo/Redo history
  • Zoom and panning

The library is framework-agnostic in the sense that it can be embedded in any React application but does not include collaboration or persistence features.

excalidraw-app (Hosted Application)

The application in excalidraw-app/ extends the core library with additional features for the hosted service at excalidraw.com:

  • Real-time collaboration via WebSocket
  • End-to-end encryption
  • PWA support (offline capability)
  • Local-first persistence (localStorage, IndexedDB)
  • Shareable readonly links
  • Firebase integration for scene storage

Build Scripts

ScriptPurposePackages Built
build:packagesBuild all core packages sequentiallycommon → math → element → excalidraw
build:appBuild hosted applicationexcalidraw-app
build:app:dockerBuild for Docker deploymentexcalidraw-app (optimized)

Sources: README.md58-88 package.json51-65

High-Level System Architecture

The following diagram shows how the major components interact at runtime:

Key Components

  • App.tsx: Root React component that initializes the application, loads scene data, and coordinates all subsystems
  • AppState: Contains UI state, selected tool, viewport, and other application-level state
  • Scene: Manages the collection of ExcalidrawElement objects representing the drawing
  • Store: Implements delta-based state updates with durable (history-recorded) and ephemeral increments
  • ActionManager: Central registry for all user actions (drawing, editing, styling)
  • Renderer: Filters, sorts, and renders elements to canvas layers
  • Binding System: Manages relationships between elements (arrows bound to shapes, text bound to containers)

Sources: package.json1-94 README.md1-131 tsconfig.json1-36

Build and Development Infrastructure

The monorepo uses modern JavaScript tooling for development and production builds:

Development Commands

CommandDescription
yarn startStart Vite dev server for excalidraw-app
yarn testRun Vitest tests
yarn test:typecheckRun TypeScript compiler for type checking
yarn test:codeRun ESLint on all TypeScript/JavaScript files
yarn build:packagesBuild all packages in dependency order

Sources: package.json46-89 tsconfig.json1-36

Deployment and Distribution

Excalidraw is distributed through multiple channels:

npm Registry

The @excalidraw/excalidraw package is published to npm for integration into other applications. The release process is managed by scripts/release.js with support for multiple channels:

Release Channelnpm TagPurpose
release:testtestExperimental builds
release:nextnextPre-release versions
release:latestlatestStable releases

Docker Container

The hosted application is containerized using a multi-stage Docker build defined in Dockerfile1-21:

  1. Build Stage: Node.js 18 image that installs dependencies and builds the application
  2. Runtime Stage: nginx:1.27-alpine serving static files

The Docker image supports multiple architectures (amd64, arm64, arm/v7) and is published to DockerHub via .github/workflows/publish-docker.yml1-31

Hosted Service

The application at excalidraw.com is built using yarn build:app and deployed as a static site with:

  • PWA manifest for offline support
  • Service worker for caching
  • Firebase backend for collaboration

Sources: Dockerfile1-21 .github/workflows/publish-docker.yml1-31 package.json83-86 docker-compose.yml1-23