CodeVetter
← All unpacks
CodeVetter · Repo Unpack evidence

excalidraw/excalidraw

Scanned commit 31df3e6ef2 dated 2026-09-22 — last upstream commit. Generated by codevetter 1.12.0 on 2026-09-22.

github.com/excalidraw/excalidraw ↗ · 1000 files · 12.3 MB

Excalidraw Editor | Blog | Documentation | Excalidraw+ An open source virtual hand-drawn style whiteboard.

Deep analysis by cli:grok via the grok CLI on 2026-09-22 (369s) — every claim below links to its cited source files.

Overview

Excalidraw is a Yarn-workspace monorepo that publishes a React whiteboard component (@excalidraw/excalidraw 0.18.0) and ships the excalidraw.com app in excalidraw-app/. The editor is an infinite canvas of hand-drawn elements (roughjs) with local-first autosave, optional real-time collaboration, and end-to-end AES-GCM encryption of scenes before they leave the browser. The hosted app adds Firebase persistence, a Socket.IO portal, shareable encrypted links, a PWA, and AI diagram helpers; the library itself is meant to be embedded by other products.

System map

The runtime splits into a publishable editor (packages/excalidraw) and a Vite app (excalidraw-app) that mounts it. Geometry and the element model live in @excalidraw/element, @excalidraw/math, and @excalidraw/common; export helpers live in @excalidraw/utils. The app talks to three external systems configured only by Vite env vars: a Socket.IO collab server, Firebase (Firestore scenes plus Storage blobs), and an HTTP share backend. Production is a static Vite build deployed to Vercel or an nginx image; package publishes go through scripts/release.js on the release branch.

Feature catalog

The editor is a tool-driven canvas plus a large ActionName command set (clipboard, z-order, align, frames, text binding, zoom, theme, export). The host app layers collaboration rooms, encrypted share links, local autosave, PWA install, Excalidraw+ chrome, and two AI surfaces (text-to-diagram and diagram-to-code). Embedders get the same canvas through props, the imperative API, and the Next.js and browser-script examples.

All 13 feature catalog claims →

Data flow

A scene is an ordered list of elements plus AppState, with image bytes kept in a separate BinaryFiles map. Local edits pass through the Store, which both feeds undo history and the public onChange/onIncrement callbacks. The app then fans changes into localStorage, IndexedDB, and — when a room is open — an encrypted socket broadcast plus a Firebase transaction. Anything loaded back in goes through restoreElements/restoreAppState and, for multiplayer, reconcileElements on version plus versionNonce.

Behavior traces

Three flows dominate the app: boot (service worker, Sentry, scene restore), a local drawing gesture (pointer down through action finalize into the store), and collaboration (room key, socket join, encrypted broadcast, Firebase reconcile). Local persistence is a side effect of onChange and is explicitly paused for the whole time a room is open.

Testing signals

Tests are Vitest 3 on jsdom, with Testing Library, vitest-canvas-mock, and fake-indexeddb. Coverage thresholds are enforced (lines 60, branches 70, functions 63, statements 60). The editor and element packages are heavily tested, including snapshots; the collaboration suite is a single file that mocks Firebase and socket.io and its own comment says multi-client cases are missing. CI runs unit tests on master pushes, and lint, types, prettier, and coverage on pull requests.

Risk map

The serious boundary is collaboration storage: Firestore and Storage rules allow public get and write, and confidentiality is entirely the AES-GCM room key that also sits in the URL hash. The editor class in App.tsx is a single very large state owner, so small input bugs have a wide blast radius. Several legacy paths (zero-IV decrypt, CRA service worker, index-node canvas script) are still in tree. Collaboration, Firebase, and the AI backends are the least tested production paths.

All 14 risk map claims →

Extension points

New editor commands are actions registered through register() and ActionManager, or at runtime via the imperative registerAction. Hosts extend rendering and behavior through Excalidraw props (UI slots, embeddables, tools, initial data) rather than forks. Persistence of libraries is an adapter interface. AI diagram-to-code is a setPlugins hook. Locale files and the library URL allowlist are data extension points.

All 14 extension points claims →

Contributor handoff

Work in packages/* for editor behavior and excalidraw-app/ for collab, Firebase, share links, and PWA. Read AGENTS.md before touching DOM or types. Run yarn test:typecheck and the relevant vitest file; refresh snapshots with yarn test:update only when the assertion change is intentional. Do not import jotai directly, do not bump element version by hand, and do not assume the collab socket server or Firebase rules are covered by tests.

Languages

LanguageFilesShare of source
TypeScript65986%
JSON95docs/config
Sass8211%
Markdown51docs/config
JavaScript263%
YAML14docs/config
CSS3docs/config
HTML2docs/config

Start reading here

Probable source entrypoint: packages/ — inferred from the directory tree and manifest, not the upstream docs.

Source roots

packages/ (795 files)

Source layout — packages/

PathFiles
packages/element/88
packages/excalidraw/65
packages/fractional-indexing/4
packages/tsconfig.base.json1

Repository structure

Top-level pathFiles
packages/795
dev-docs/58
excalidraw-app/51
examples/28
.github/16
scripts/13
firebase-project/6
public/4

Docs found: AGENTS.mdCLAUDE.mdCONTRIBUTING.mdREADME.md

Package

package.json — excalidraw-monorepo, 34 declared dependencies.

@babel/preset-env@excalidraw/eslint-config@excalidraw/prettier-config@types/chai@types/jest@types/lodash.throttle@types/react@types/react-dom@types/socket.io-client@vitejs/plugin-react@vitest/coverage-v8@vitest/ui

CI & config entrypoints

Structural health signals

Average score 6.5/10 across 96 analyzed source files; 49 hotspots surfaced.

These are deterministic review leads — size, churn, and structural signals — not proof of a bug in this project.

Recent history