Project Architecture
Excalidraw is built as a monorepo using Yarn workspaces, with a clear separation between the core library and the application.Monorepo Structure
Core Packages
packages/excalidraw/
The main React component library published to npm as @excalidraw/excalidraw.
- Purpose: Embeddable Excalidraw editor component
- Published: Yes (npm package)
- Entry Point:
packages/excalidraw/index.tsx - Build Output:
packages/excalidraw/dist/
- Infinite canvas-based whiteboard
- Hand-drawn style rendering
- Shape libraries and tools
- Export to PNG, SVG, and
.excalidrawJSON - Customizable UI and theming
- i18n support
packages/common/
Shared utilities and types used across the monorepo.
- Package Name:
@excalidraw/common - Published: Internal package
- Contains: Common utilities, type definitions, color helpers
packages/element/
Element-related functionality and types.
- Package Name:
@excalidraw/element - Published: Internal package
- Contains: Element types, transformations, rendering logic
packages/math/
Mathematical utilities for geometry and calculations.
- Package Name:
@excalidraw/math - Published: Internal package
- Contains: Geometry helpers, vector math, collision detection
packages/utils/
General utility functions.
- Package Name:
@excalidraw/utils - Published: Internal package
- Contains: Helper functions, formatters, validators
Application
excalidraw-app/
The full-featured web application hosted at excalidraw.com.
- Purpose: Production web app showcasing Excalidraw capabilities
- Published: Deployed to Vercel
- Uses:
@excalidraw/excalidrawpackage
- 📡 PWA support (works offline)
- 🤼 Real-time collaboration
- 🔒 End-to-end encryption
- 💾 Local-first storage (autosaves to browser)
- 🔗 Shareable readonly links
excalidraw-app/App.tsx- Main application componentexcalidraw-app/collab/- Collaboration featuresexcalidraw-app/data/- Data persistence logicexcalidraw-app/components/- App-specific UI components
Examples
examples/
Integration examples demonstrating how to use Excalidraw:
examples/with-nextjs/- Next.js integrationexamples/with-script-in-browser/- Plain HTML/JS integration
Package System
Yarn Workspaces
Excalidraw uses Yarn workspaces for monorepo management:- Shared dependencies across packages
- Linking local packages without publishing
- Single
node_modulesat the root
Path Aliases
The monorepo uses TypeScript path aliases for clean imports:tsconfig.json- For TypeScriptvitest.config.mts- For test resolution
Build System
For Packages
Build Tool: esbuild- Fast: Extremely fast bundling
- Output: ESM modules in
dist/directory - Types: Generated with TypeScript compiler
For Application
Build Tool: Vite- Dev Server: Fast HMR with Vite dev server
- Production: Optimized build with code splitting
- Plugins: React, PWA, SVG loader, EJS
Development Workflow
Working on Core Library Features
- Make changes in
packages/excalidraw/ - Changes hot-reload automatically when running
yarn start - Test changes in the dev server at localhost:3000
- Write tests in the same package
- Run
yarn test:updatebefore committing
Working on App-Specific Features
- Make changes in
excalidraw-app/ - Features like collaboration, sharing, PWA
- Test in dev environment
- These features don’t affect the npm package
Working on Internal Packages
- Make changes in
packages/common/,packages/element/, etc. - Run
yarn build:packagesto rebuild - Changes affect both the library and app
- Always run type checks:
yarn test:typecheck
TypeScript Configuration
Strict Mode Enabled
Target Environment
- Target: ESNext
- Module: ESNext
- JSX: react-jsx (React 17+ automatic runtime)
- Lib: DOM, ESNext
Base Configuration
- Root
tsconfig.json- Base configuration for the monorepo packages/tsconfig.base.json- Shared config for packages- Individual
tsconfig.jsonin each package
Testing Architecture
Test Framework
Vitest - Fast unit test framework compatible with JestConfiguration
Defined invitest.config.mts:
Test Location
packages/excalidraw/**/*.test.tsx- Component testspackages/common/tests/- Common utilities testsexcalidraw-app/tests/- App-specific tests
Test Utilities
@testing-library/react- Component testing@testing-library/jest-dom- DOM matchersvitest-canvas-mock- Canvas API mockingfake-indexeddb- IndexedDB mocking
Code Quality Tools
ESLint
Configuration in.eslintrc.json:
- Based on
@excalidraw/eslint-config - Extends
react-apprules - Custom rules for the project
Prettier
Configuration:@excalidraw/prettier-config
- Consistent code formatting
- Runs on pre-commit hook via lint-staged
Husky + lint-staged
Pre-commit Hook (.husky/pre-commit):
State Management
Jotai
Excalidraw uses Jotai for state management:- Atomic state management: Fine-grained reactivity
- Type-safe: Full TypeScript support
- Performant: Only re-renders affected components
Key State Atoms
Defined in:packages/excalidraw/- Editor state atomsexcalidraw-app/app-jotai.ts- App-specific atoms
Styling
SASS/SCSS
Excalidraw uses SASS for styling:- Component-scoped styles
- CSS variables for theming
- Dark mode support
CSS Architecture
packages/excalidraw/index.scss- Main library stylesexcalidraw-app/index.scss- App-specific styles- Component co-located
.scssfiles
Browser Support
Production Targets
Development Targets
Latest versions of Chrome, Firefox, and Safari.Next Steps
Now that you understand the architecture:- Review the Contribution Guidelines for code standards
- Check the Testing Guide to write effective tests
- Start with an Easy task from the roadmap