A CLAUDE.md is just a markdown file at the root of your repo. Copy the content below into your own project's CLAUDE.md to give your agent the same context.
npx versuz@latest install jgraph-drawio-desktop --kind=claude-mdcurl -o CLAUDE.md https://raw.githubusercontent.com/jgraph/drawio-desktop/HEAD/CLAUDE.md# CLAUDE.md - AI Assistant Guide for draw.io Desktop
## Project Overview
Draw.io Desktop is an Electron-based desktop application that wraps the core draw.io diagramming editor (included as a git submodule). It enables creating flowcharts, UML diagrams, and more, with a security-first design that isolates diagram data from the internet.
**Repository:** https://github.com/jgraph/drawio-desktop
**License:** Apache 2.0
**Current Version:** 29.6.1
## Quick Reference
```bash
# Clone (MUST be recursive for submodule)
git clone --recursive https://github.com/jgraph/drawio-desktop.git
# Install dependencies
npm install
# Run application
npm start
# Run with DevTools enabled
DRAWIO_ENV=dev npm start
# Sync version before building (required)
npm run sync
# Build for specific platforms
npm run release-win # Windows x64
npm run release-linux # Linux (AppImage, deb, rpm)
npm run release-appx # Windows Store
```
## Project Structure
```
drawio-desktop/
├── src/main/
│ ├── electron.js # Main Electron process (2,700+ lines)
│ ├── electron-preload.js # IPC bridge with contextBridge
│ └── disableUpdate.js # Generated by sync script
├── drawio/ # Git submodule - core draw.io editor
│ └── src/main/webapp/ # Web application loaded in Electron
├── build/ # Build resources
│ ├── notarize.mjs # macOS Quick Look setup, signing + notarization
│ ├── fuses.cjs # Electron security fuses
│ ├── quicklook-preview.html # Quick Look preview page (viewer-static.min.js)
│ ├── quicklook-entitlements.plist # Sandbox entitlements for .appex
│ └── entitlements.mac.plist
├── doc/
│ └── RELEASE_PROCESS.md # Release workflow documentation
├── electron-builder-*.json # Platform-specific build configs
├── sync.cjs # Version sync script
└── package.json
```
## Tech Stack
- **Runtime:** Node.js 20+
- **Framework:** Electron 39.x
- **Language:** JavaScript (ES6 modules)
- **Build Tool:** electron-builder
- **Package Manager:** npm
## Key Files
| File | Purpose |
|------|---------|
| `src/main/electron.js` | Main process: window management, IPC handlers, menus, auto-update |
| `src/main/electron-preload.js` | Secure IPC bridge between renderer and main process |
| `sync.cjs` | Pre-build script that syncs version from `drawio/VERSION` |
| `electron-builder-*.json` | Platform-specific build configurations |
## Code Style
- **ES6 modules** with `import`/`export`
- **Tab indentation**
- **Allman brace style** (opening brace on new line)
- **camelCase** for variables, **PascalCase** for classes
- No ESLint/Prettier - manual style consistency
- Sparse comments; code clarity preferred
## Git Conventions
### Branches
- `dev` - Main development branch (PR target)
- `release` - Production releases
- `releases/v*.*.*` - Version-specific release branches
### Commit Messages
- Lowercase sentence style without period
- Issue references: `[jgraph/drawio-desktop#XXXX]`
- Examples:
- `Fixes paste error`
- `Adds buffer as dependency [jgraph/drawio-desktop#2301]`
- `Prepare release v29.3.0`
### Version Tags
Format: `v{MAJOR}.{MINOR}.{PATCH}` (e.g., `v29.3.0`)
Tags trigger CI/CD build workflows.
## Build Process
1. **Sync version:** `npm run sync` reads `drawio/VERSION` and updates `package.json`
2. **Install:** `npm ci` for clean install
3. **Build:** `electron-builder` with platform-specific config
4. **Post-build:** Security fuses applied, Quick Look extension assembled (macOS), notarization (macOS)
> **CI override:** The release build workflows check out the private `jgraph/drawio-dev` repo at its `release` branch, copy the built `*.min.js` **and** `VERSION` into the public `drawio/` submodule tree, then run `npm run sync` as normal. This lets CI ship from an internal release that is ahead of the public `drawio` tag without any change to `sync.cjs`. Out-of-tree builders (who have no access to `drawio-dev`) fall through to the public submodule's `VERSION` as before.
### Platform Build Commands
| Command | Target |
|---------|--------|
| `npm run release-win` | Windows x64 (NSIS + MSI) |
| `npm run release-win32` | Windows 32-bit |
| `npm run release-win-arm64` | Windows ARM64 |
| `npm run release-linux` | Linux (AppImage, deb, rpm) |
| `npm run release-appx` | Windows Store |
| `npm run release-snap` | Snap package |
## Architecture Notes
### Security Model
- **Content Security Policy** prevents remote script execution
- **contextBridge** exposes only specific APIs to renderer
- **validateSender()** ensures IPC calls originate from local draw.io
- No external transmission of diagram data
### IPC Pattern
The preload script uses a request/response pattern with unique IDs:
```javascript
// Renderer sends request
electron.request({action: 'save', data: ...}, callbackId);
// Main process handles and responds via IPC
ipcMain.on('request', (e, data) => { ... });
```
### macOS Quick Look Preview
- Pressing Space in Finder shows a rendered preview of `.drawio` files
- Uses `quicklookjs` to embed a Quick Look App Extension (`.appex`) in the app bundle
- The `.appex` loads `viewer-static.min.js` (with embedded shapes) in a WKWebView
- **Build flow:** `afterPack` (fuses.cjs) applies security fuses, then `afterSign` (notarize.mjs) assembles the `.appex`, signs it with sandbox entitlements, re-signs the outer `.app`, and notarizes
- The `.appex` is inserted in `afterSign` (not `afterPack`) so it is never present unsigned during electron-builder's signing verification
- Quick Look extensions require `app-sandbox`, but Electron helpers must not be sandboxed — so the `.appex` gets different entitlements than `entitlementsInherit`
- The UTI `com.jgraph.drawio` is declared via `extendInfo` in `electron-builder-linux-mac.json`
- `viewer-static.min.js` is saved to `build/` during CI before the cleanup step removes it from the drawio submodule; for local dev, it's read from the submodule directly
### Auto-Update
- Checks GitHub releases on startup
- Disable via `DRAWIO_DISABLE_UPDATE=true` or `--disable-update` flag
- Flatpak detection disables updates automatically
### Data Storage
- **macOS:** `~/Library/Application Support/draw.io`
- **Windows:** `%APPDATA%\draw.io\`
- Uses `electron-store` for persistent settings
## Testing
No automated tests. Manual testing documented in `doc/RELEASE_PROCESS.md`:
- Launch, create diagram, add shapes, save, open
- Export (PNG, PDF, SVG)
- Undo/redo functionality
- About dialog verification
## CI/CD Workflows
| Workflow | Trigger | Purpose |
|----------|---------|---------|
| `electron-builder.yml` | Version tag | macOS/Linux builds |
| `electron-builder-win.yml` | Version tag | Windows builds |
| `prepare-release.yml` | Manual | Automated release prep |
| `hash-gen.yml` | Manual | Generate checksums |
## Important Constraints
1. **Recursive clone required** - drawio submodule must be initialized
2. **Run `npm run sync` before building** - Updates version from submodule
3. **Version source of truth** - `drawio/VERSION` for public builds; `drawio-dev/VERSION` is copied over `drawio/VERSION` at CI time so the internal release number wins for packaged builds
4. **Closed to contributions** - PRs not accepted; maintained by JGraph
5. **Node 20+ required** - ES6 modules without transpilation
## Development Tips
- Set `DRAWIO_ENV=dev` to auto-open DevTools
- Use `npm start --enable-logging` for verbose output
- If using symlink instead of submodule, also symlink `node_modules`
- Main process logs to console; check terminal for errors
## Key Dependencies
| Package | Purpose |
|---------|---------|
| `electron` | Desktop app framework |
| `electron-builder` | Build/package tool |
| `electron-updater` | Auto-update mechanism |
| `electron-store` | Persistent storage |
| `@cantoo/pdf-lib` | PDF export |
| `commander` | CLI argument parsing |
| `quicklookjs` | macOS Quick Look preview extension (dev) |