The Problem

Excalidraw solves the friction of creating diagrams that look hand-drawn without requiring design tools. It provides an infinite canvas with a sketch-like rendering style, supporting arrows, shapes, freehand drawing, and export to PNG/SVG. The core pain point is building a customizable whiteboard component that can be embedded in other applications rather than building one from scratch.

What This Does

This is a fork of the popular excalidraw/excalidraw repository (130k+ stars). It contains the core @excalidraw/excalidraw npm package in packages/, a full-featured whiteboard app in excalidraw-app/, and supporting projects. The core package exports a React component that renders the editor, handles drawing state, and supports features like undo/redo, zoom, and shape libraries.

The excalidraw-app/ directory is a PWA with real-time collaboration, end-to-end encryption, and local-first autosave. The repo also includes dev-docs/ (Docusaurus-based documentation), examples/ (integration demos with Next.js and script tags), and scripts/ for build tooling. TypeScript dominates at 312 files plus 290 TSX files.

How It Is Wired

The entry point for the npm package is packages/excalidraw/index.tsx, which exports the main Excalidraw component. The component tree flows through packages/excalidraw/components/ where icons.tsx (88 importers) provides UI icons, and i18n.tsx (91 importers) handles localization. The types.ts file is the most connected module with 122 modules importing it and sits inside a circular dependency cycle.

The measured import graph shows 621 internal modules with 1,955 import edges and 83 modules in circular dependencies. The most unstable module is packages/element/src/index.ts (instability 0.96), which exports 47 modules but is only imported by 2. This means changes to element types ripple outward with high blast radius.

The app boots via the React component, which initializes the canvas, loads initial data from props, and manages state through the actions system in packages/excalidraw/actions/index.ts. This module has 16 importers and 31 imports, making it a central dispatch point for user interactions. The types.ts hub module carries the highest risk: 122 modules depend on it, so any type change forces recompilation across the codebase.

How To Use It

# Clone and install
git clone https://github.com/moses-y/excalidraw
cd excalidraw
yarn install

# Run the dev server
yarn start

The README documents installing the npm package with npm install @excalidraw/excalidraw for embedding into your own app. The repo uses yarn as the package manager, confirmed by yarn.lock files. Docker support exists via Dockerfile and docker-compose.yml.

Real-World Use

A typical integration embeds the editor in a product:

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

function DiagramEditor() {
  return (
    <Excalidraw
      initialData={{ elements: [], appState: { viewBackgroundColor: "#fff" } }}
      onChange={(elements, state) => saveToBackend(elements, state)}
    />
  );
}

The component accepts initialData and onChange callbacks, making it straightforward to persist drawings to your own backend.

Code Health & Issues

Static analysis found 199 findings: 117 high, 74 medium, 8 low. Key issues:

  • Critical - Committed credentials in .env.development - contains a Google API key pattern and a generated VITE_APP_PLUS_EXPORT_PUBLIC_KEY. Rotate immediately, remove from git history, and add a pre-commit secret gate.
  • High - Tracked .env files (.env.development, .env.production, .env.test) - the app loads these at boot, so the values are live. Move to .env.example and add to .gitignore.
  • High - 36 modules in circular import dependencies - types.ts, test-utils.ts, and helpers/api.ts are the main offenders. Breaking these cycles requires extracting shared types.
  • High - Oversized files - types.ts at 846 lines and element/src/bounds.ts are hard to maintain.
  • Medium - CI uses yarn install without --immutable, risking untested dependency sets. No Dependabot configured. A 20.7MB font blob (Xiaolai-Regular.ttf) should move to LFS.

The Bottom Line

This is a solid, well-tested codebase (156 test files) with a mature architecture. The circular dependencies and oversized files are maintenance risks, but the critical issue is the committed credentials—address those before anything else. Use it if you need an embeddable diagram editor; the npm package is production-ready, but this fork requires credential cleanup before deployment.