diff --git a/onboarding.md b/onboarding.md
new file mode 100644
index 0000000..f2eb75d
--- /dev/null
+++ b/onboarding.md
@@ -0,0 +1,620 @@
+# Excalidraw Developer Onboarding Guide
+
+Welcome to the Excalidraw team! This document will get you from zero to productive as quickly as possible.
+
+---
+
+## Table of Contents
+
+1. [What is Excalidraw?](#what-is-excalidraw)
+2. [Repository Overview](#repository-overview)
+3. [Architecture](#architecture)
+4. [Package Reference](#package-reference)
+5. [Development Setup](#development-setup)
+6. [Development Workflow](#development-workflow)
+7. [Testing](#testing)
+8. [Build System](#build-system)
+9. [State Management](#state-management)
+10. [Rendering Pipeline](#rendering-pipeline)
+11. [Key Concepts](#key-concepts)
+12. [CI/CD Pipeline](#cicd-pipeline)
+13. [Common Tasks](#common-tasks)
+
+---
+
+## What is Excalidraw?
+
+Excalidraw is an open-source virtual whiteboard for sketching hand-drawn-like diagrams. It has two main forms:
+
+- **The Library** (`@excalidraw/excalidraw`) — a React component published to npm, embeddable in any application
+- **The App** (excalidraw.com) — the full-featured web application built on top of the library, with real-time collaboration, Firebase storage, and sharing
+
+---
+
+## Repository Overview
+
+The project is a **Yarn monorepo** with the following top-level layout:
+
+```
+excalidraw/
+├── packages/ # Core npm packages
+│ ├── excalidraw/ # Main React library (@excalidraw/excalidraw)
+│ ├── common/ # Shared utilities (@excalidraw/common)
+│ ├── element/ # Element logic (@excalidraw/element)
+│ ├── math/ # 2D geometry (@excalidraw/math)
+│ └── utils/ # Export utilities (@excalidraw/utils)
+├── excalidraw-app/ # The web application (excalidraw.com)
+├── examples/ # Integration examples
+│ ├── with-nextjs/
+│ └── with-script-in-browser/
+├── scripts/ # Build and release scripts
+├── dev-docs/ # Developer documentation
+├── public/ # Static assets
+├── .github/workflows/ # CI/CD pipelines
+└── firebase-project/ # Firebase config
+```
+
+### Workspace Structure
+
+```mermaid
+graph TD
+ A[Root Workspace] --> B[packages/*]
+ A --> C[excalidraw-app]
+ A --> D[examples/*]
+ B --> E[@excalidraw/common]
+ B --> F[@excalidraw/math]
+ B --> G[@excalidraw/element]
+ B --> H[@excalidraw/excalidraw]
+ B --> I[@excalidraw/utils]
+```
+
+---
+
+## Architecture
+
+### Package Dependency Graph
+
+Packages form a strict dependency hierarchy. **Never create circular dependencies.**
+
+```mermaid
+graph BT
+ common["@excalidraw/common
(utilities, constants, colors)"]
+ math["@excalidraw/math
(2D geometry)"]
+ element["@excalidraw/element
(element logic, rendering)"]
+ utils["@excalidraw/utils
(export utilities)"]
+ excalidraw["@excalidraw/excalidraw
(main React library)"]
+ app["excalidraw-app
(web application)"]
+
+ math --> common
+ element --> common
+ element --> math
+ excalidraw --> common
+ excalidraw --> math
+ excalidraw --> element
+ utils --> common
+ app --> excalidraw
+ app --> element
+ app --> common
+```
+
+### High-Level Application Architecture
+
+```mermaid
+graph TD
+ subgraph Browser
+ subgraph excalidraw-app
+ AppComponent["App.tsx
(App Shell)"]
+ Collab["collab/
(Real-time Collaboration)"]
+ Share["share/
(Link Sharing)"]
+ end
+
+ subgraph "@excalidraw/excalidraw Library"
+ ExcalidrawComp["<Excalidraw />
Main Component"]
+ Actions["actions/
(46 user actions)"]
+ Components["components/
(UI Components)"]
+ Renderer["renderer/
(Canvas Rendering)"]
+ Scene["scene/
(Scene Management)"]
+ State["Jotai Atoms
(App State)"]
+ end
+
+ subgraph "Core Packages"
+ ElementPkg["@excalidraw/element
(shapes, bounds, binding)"]
+ MathPkg["@excalidraw/math
(geometry)"]
+ CommonPkg["@excalidraw/common
(utils, constants)"]
+ end
+ end
+
+ subgraph "External Services"
+ Firebase["Firebase
(persistence)"]
+ RoomServer["excalidraw-room
(Socket.io)"]
+ Sentry["Sentry
(error tracking)"]
+ end
+
+ AppComponent --> ExcalidrawComp
+ Collab --> RoomServer
+ AppComponent --> Firebase
+ ExcalidrawComp --> Actions
+ ExcalidrawComp --> Components
+ ExcalidrawComp --> Renderer
+ Renderer --> Scene
+ Scene --> ElementPkg
+ ElementPkg --> MathPkg
+ ElementPkg --> CommonPkg
+ AppComponent --> Sentry
+```
+
+---
+
+## Package Reference
+
+### `@excalidraw/common`
+
+Shared utilities and constants used by all other packages.
+
+| File | Purpose |
+|------|---------|
+| `constants.ts` | App-wide constant values |
+| `colors.ts` | Color palette and manipulation |
+| `utils.ts` | General-purpose utilities |
+| `appEventBus.ts` | Cross-component event bus |
+
+### `@excalidraw/math`
+
+Pure 2D geometry — no DOM, no React, no side effects.
+
+| Module | Purpose |
+|--------|---------|
+| `point.ts` | Point type and operations |
+| `vector.ts` | Vector math |
+| `line.ts`, `segment.ts` | Line and segment geometry |
+| `curve.ts` | Bezier curve math |
+| `angle.ts` | Angle and rotation |
+| `polygon.ts`, `rectangle.ts`, `ellipse.ts` | Shape geometry |
+
+### `@excalidraw/element`
+
+All element-level logic: creation, mutation, binding, selection, rendering.
+
+| File | Purpose |
+|------|---------|
+| `newElement.ts` | Factory functions for creating elements |
+| `mutateElement.ts` | Immutable-style element mutation |
+| `bounds.ts` | Bounding box calculations |
+| `collision.ts` | Hit-testing and collision detection |
+| `binding.ts` | Arrow-to-shape binding logic |
+| `elbowArrow.ts` | Smart elbow arrow routing |
+| `textElement.ts` | Text measurement and wrapping |
+| `resizeElements.ts` | Resize and transform logic |
+| `selection.ts` | Selection state and operations |
+| `groups.ts` | Grouping elements |
+| `zindex.ts` | Layer ordering |
+| `Scene.ts` | In-memory scene graph |
+
+### `@excalidraw/excalidraw` (Main Library)
+
+The heart of the project. Key areas:
+
+```
+packages/excalidraw/src/
+├── index.tsx # Public API exports
+├── App.tsx # Main component (~10k lines)
+├── types.ts # All TypeScript types
+├── appState.ts # AppState shape and defaults
+├── history.ts # Undo/redo
+├── actions/ # 46 user-facing actions
+├── components/ # React UI components
+├── renderer/ # Canvas rendering
+├── scene/ # Scene compositing
+├── data/ # Serialization & persistence
+├── fonts/ # Font loading & subsetting
+├── locales/ # 70+ i18n JSON files
+├── hooks/ # Custom React hooks
+├── eraser/ # Eraser tool
+├── lasso/ # Lasso selection
+└── wysiwyg/ # Inline text editor
+```
+
+### `@excalidraw/utils`
+
+Export utilities: convert scenes to PNG, SVG, and other formats.
+
+### `excalidraw-app`
+
+The full web app. Adds on top of the library:
+
+| Directory | Purpose |
+|-----------|---------|
+| `collab/` | WebSocket real-time collaboration |
+| `share/` | URL-based sharing and link generation |
+| `components/` | App-specific UI (menus, dialogs) |
+| `data/` | IndexedDB persistence |
+| `app-language/` | Language detection and loading |
+
+---
+
+## Development Setup
+
+### Prerequisites
+
+- **Node.js** >= 18.0.0
+- **Yarn** 1.22.x (`npm install -g yarn`)
+
+### First-Time Setup
+
+```bash
+# Clone the repository
+git clone https://github.com/excalidraw/excalidraw.git
+cd excalidraw
+
+# Install all dependencies (all workspaces)
+yarn install
+
+# Start the development server
+yarn start
+# App runs at http://localhost:3001
+```
+
+### Environment Variables
+
+The app uses Vite env variables. Defaults are in `.env.development`:
+
+| Variable | Purpose |
+|----------|---------|
+| `VITE_APP_BACKEND_V2_GET_URL` | Backend API for scene loading |
+| `VITE_APP_WS_SERVER_URL` | WebSocket server for collaboration |
+| `VITE_APP_AI_BACKEND` | AI features backend |
+| `VITE_APP_PORT` | Dev server port (default: 3001) |
+| `VITE_APP_ENABLE_TRACKING` | Enable analytics |
+
+For local overrides, create `.env.development.local` (git-ignored).
+
+---
+
+## Development Workflow
+
+### Where to Make Changes
+
+```mermaid
+flowchart TD
+ Q1{What are you changing?}
+ Q1 -->|Drawing logic, element behavior| P1["packages/element/"]
+ Q1 -->|2D geometry or math| P2["packages/math/"]
+ Q1 -->|Shared utility or constant| P3["packages/common/"]
+ Q1 -->|UI component in the editor| P4["packages/excalidraw/src/components/"]
+ Q1 -->|User action
e.g. duplicate, align| P5["packages/excalidraw/src/actions/"]
+ Q1 -->|Canvas rendering| P6["packages/excalidraw/src/renderer/"]
+ Q1 -->|Collaboration or sharing| P7["excalidraw-app/collab/"]
+ Q1 -->|App-level feature| P8["excalidraw-app/"]
+ Q1 -->|Export: PNG, SVG| P9["packages/utils/"]
+```
+
+### Typical Feature Flow
+
+1. **Identify the layer** — use the decision tree above
+2. **Read existing code** before writing new code
+3. **Write or update tests** for your change
+4. **Run the linter and type checker** before committing
+5. **Run tests** — `yarn test:update`
+6. **Open a PR** with a conventional commit title (e.g. `feat(editor): add snap to grid`)
+
+### Commit Message Convention
+
+```
+():
+
+Types: feat, fix, refactor, test, docs, chore, perf
+Scope: editor, element, math, collab, app, export, ...
+
+Examples:
+ feat(editor): add snap to objects
+ fix(element): correct rotated arrow binding point
+ perf(renderer): reduce redraws on pointer move
+```
+
+---
+
+## Testing
+
+### Test Stack
+
+- **Runner**: Vitest v3
+- **Environment**: jsdom (simulated browser DOM)
+- **Mocks**: Canvas mocked via `vitest-canvas-mock`
+- **Snapshots**: Vitest snapshot testing
+
+### Test Locations
+
+```
+packages/excalidraw/tests/ # Main component and integration tests
+packages/element/src/__tests__/ # Element logic unit tests
+packages/math/src/__tests__/ # Math utility tests
+packages/common/src/ # Common util tests (co-located)
+excalidraw-app/tests/ # App-level integration tests
+```
+
+### Test Commands
+
+```bash
+yarn test:app # Run all tests
+yarn test:app --watch # Watch mode during development
+yarn test:update # Run tests AND update snapshots (use before committing)
+yarn test:coverage # Generate coverage report
+yarn test:ui # Open interactive Vitest UI
+```
+
+### Quality Checks
+
+```bash
+yarn test:typecheck # TypeScript type checking
+yarn test:code # ESLint
+yarn test:other # Prettier formatting
+yarn test:all # Run everything (what CI runs)
+yarn fix # Auto-fix all formatting and lint issues
+```
+
+### Coverage Thresholds
+
+| Metric | Minimum |
+|--------|---------|
+| Lines | 60% |
+| Branches | 70% |
+| Functions | 63% |
+| Statements | 60% |
+
+---
+
+## Build System
+
+### Tools
+
+| Layer | Tool |
+|-------|------|
+| Web App | Vite + Rollup |
+| npm Packages | esbuild + Sass |
+| Type generation | TypeScript compiler (`tsc`) |
+
+### Build Order
+
+Packages must be built in dependency order:
+
+```mermaid
+graph LR
+ A["build:common"] --> B["build:math"]
+ B --> C["build:element"]
+ C --> D["build:excalidraw"]
+ D --> E["build:app"]
+```
+
+```bash
+# Build everything in order
+yarn build:packages # builds common → math → element → excalidraw
+yarn build:app # builds the web application
+```
+
+### Package Build Output
+
+Each package outputs to `dist/`:
+
+```
+packages/excalidraw/dist/
+├── dev/ # Unminified with sourcemaps (development)
+├── prod/ # Minified (production)
+└── types/ # TypeScript .d.ts declarations
+```
+
+---
+
+## State Management
+
+Excalidraw uses a hybrid state model:
+
+```mermaid
+graph TD
+ subgraph "Global State"
+ Jotai["Jotai Atoms
(app-level state)"]
+ AppState["AppState
(tool, zoom, scroll, selection...)"]
+ end
+
+ subgraph "Element State"
+ Scene["Scene.ts
(in-memory element store)"]
+ Store["store.ts
(undo/redo deltas)"]
+ end
+
+ subgraph "Persistence"
+ LocalStorage["LocalStorage
(browser)"]
+ IndexedDB["IndexedDB
(idb-keyval)"]
+ Firebase["Firebase
(cloud)"]
+ end
+
+ subgraph "React"
+ Context["ExcalidrawAPIProvider
(imperative API)"]
+ Hooks["useAppStateValue
useExcalidrawAPI
useOnAppStateChange"]
+ end
+
+ Jotai --> AppState
+ AppState --> Scene
+ Scene --> Store
+ Scene --> LocalStorage
+ Scene --> IndexedDB
+ Scene --> Firebase
+ Context --> Hooks
+ Jotai --> Context
+```
+
+### Key Types
+
+- **`AppState`** — everything about the editor UI: active tool, zoom level, scroll position, selected elements, etc.
+- **`ExcalidrawElement`** — the base type for all drawn elements (rectangles, arrows, text, etc.)
+- **`ExcalidrawImperativeAPI`** — the programmatic API surface exposed to host applications via `useExcalidrawAPI()`
+
+---
+
+## Rendering Pipeline
+
+Excalidraw uses **two separate canvases** layered on top of each other:
+
+```mermaid
+sequenceDiagram
+ participant User
+ participant React
+ participant InteractiveCanvas
+ participant StaticCanvas
+ participant RoughJS
+
+ User->>React: pointer event (draw/move)
+ React->>InteractiveCanvas: render selection handles,
cursor, in-progress shapes
+ React->>StaticCanvas: render all committed elements
+ StaticCanvas->>RoughJS: generate hand-drawn stroke paths
+ RoughJS-->>StaticCanvas: canvas draw calls
+ StaticCanvas-->>User: final frame
+```
+
+- **Static Canvas** — renders all committed elements. Redrawn only when elements change. Produces the "hand-drawn" look via [Rough.js](https://roughjs.com/).
+- **Interactive Canvas** — renders selection handles, resize handles, the element being currently drawn, and cursor effects. Updates on every pointer move.
+
+This split is critical for performance: moving the cursor does not re-render every element.
+
+---
+
+## Key Concepts
+
+### Elements
+
+Every object on the canvas is an `ExcalidrawElement`. All elements share:
+
+```typescript
+{
+ id: string, // Unique stable ID
+ type: string, // "rectangle" | "ellipse" | "arrow" | "text" | ...
+ x: number, y: number, // Position (top-left)
+ width: number, height: number,
+ angle: number, // Rotation in radians
+ strokeColor: string,
+ backgroundColor: string,
+ roughness: number, // 0=smooth, 3=very rough
+ opacity: number,
+ isDeleted: boolean, // Soft delete (kept for collab sync)
+ version: number, // Incremented on every change (for sync)
+ ...
+}
+```
+
+**Elements are immutable** — always use `mutateElement()` rather than direct assignment, which ensures version tracking and scene invalidation.
+
+### Actions
+
+User actions (duplicate, align, change color, etc.) are registered in `packages/excalidraw/src/actions/`. Each action:
+
+1. Has a `name`
+2. Optionally renders a UI panel (`PanelComponent`)
+3. Has a `perform` function that receives `elements`, `appState`, and `app` and returns updated state
+
+This decoupled pattern keeps `App.tsx` from growing unbounded with one-off handler code.
+
+### Collaboration Model
+
+```mermaid
+sequenceDiagram
+ participant Client A
+ participant RoomServer as excalidraw-room (Socket.io)
+ participant Client B
+ participant Firebase
+
+ Client A->>RoomServer: join room
+ Client B->>RoomServer: join room
+ Client A->>Firebase: persist scene
+ Client A->>RoomServer: broadcast element delta
+ RoomServer->>Client B: forward delta
+ Client B->>Client B: apply delta to local scene
+```
+
+Real-time sync goes over Socket.io (room server). Long-term persistence goes to Firebase. The client reconciles incoming deltas using element `version` numbers to resolve conflicts.
+
+---
+
+## CI/CD Pipeline
+
+```mermaid
+graph TD
+ subgraph "On Pull Request"
+ PR1["Prettier check
(yarn test:other)"]
+ PR2["ESLint
(yarn test:code)"]
+ PR3["TypeScript
(yarn test:typecheck)"]
+ PR4["Conventional PR title
(semantic-pr-title)"]
+ PR5["Bundle size check
(size-limit)"]
+ PR6["Test coverage report"]
+ end
+
+ subgraph "On Merge to master"
+ M1["Run all tests
(yarn test:app)"]
+ M2["Auto-publish to npm
(autorelease)"]
+ M3["Build Docker image"]
+ M4["Upload Sentry sourcemaps"]
+ end
+
+ PR1 & PR2 & PR3 & PR4 & PR5 & PR6 --> Merge[Merge to master]
+ Merge --> M1 & M2 & M3 & M4
+```
+
+### Pre-commit Hooks
+
+Husky runs `lint-staged` automatically before each commit:
+- **`*.{js,ts,tsx}`** → ESLint `--fix`
+- **`*.{css,scss,json,md,html,yml}`** → Prettier `--write`
+
+You should never need to fix lint issues manually — just commit and the hook fixes them.
+
+---
+
+## Common Tasks
+
+### Add a New Element Type
+
+1. Define the type in `packages/excalidraw/src/types.ts`
+2. Add factory in `packages/element/src/newElement.ts`
+3. Add rendering logic in `packages/element/src/renderElement.ts`
+4. Add bounds calculation in `packages/element/src/bounds.ts`
+5. Register the tool in `App.tsx` and the toolbar
+
+### Add a New Action
+
+1. Create a file in `packages/excalidraw/src/actions/`
+2. Implement `register()` with `name`, `perform`, and optionally `PanelComponent`
+3. Register it in `packages/excalidraw/src/actions/manager.ts`
+
+### Add a New Translation String
+
+1. Add the key and English text to `packages/excalidraw/src/locales/en.json`
+2. Run the locales coverage check: `yarn test:locales`
+3. Other languages will show the English fallback until translators update them
+
+### Debug Rendering Issues
+
+The two-canvas architecture means:
+- **Visual glitch on static elements** → look at `renderer/renderElement.ts` and the static scene
+- **Handle/cursor issue** → look at `renderer/renderInteractiveScene.ts`
+- **Layout/bounds wrong** → look at `packages/element/src/bounds.ts`
+
+### Run a Single Test File
+
+```bash
+yarn test:app packages/excalidraw/tests/your-test.test.tsx
+```
+
+### Check Bundle Size Impact
+
+```bash
+cd packages/excalidraw
+yarn size-limit
+```
+
+---
+
+## Getting Help
+
+- **Dev docs**: `dev-docs/` in this repository
+- **GitHub Issues**: for bug reports and feature discussions
+- **PR Reviews**: all PRs require at least one approval before merge
+- **Conventional Commits**: PR titles are validated — use `feat:`, `fix:`, `refactor:`, etc.
+
+Good luck, and welcome to the team!