drawio-desktop

Official electron build of draw.io

62,506 stars JavaScript Markdown Skills API Spec #diagram-editor#electron-app#graphics#javascript-applications
AI Prompts & Specs

Repository: jgraph/drawio-desktop


Stars: 60498

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

text
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)

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, not package.json
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) |


README.md

About
-----

drawio-desktop is a diagramming desktop app based on Electron that wraps the core draw.io editor.

Download built binaries from the releases section.

Can I use this app for free? Yes, under the apache 2.0 license. If you don't change the code and accept it is provided "as-is", you can use it for any purpose.

Security
--------

draw.io Desktop is designed to be completely isolated from the Internet, apart from the update process. This checks github.com at startup for a newer version and downloads it from an AWS S3 bucket owned by Github. All JavaScript files are self-contained, the Content Security Policy forbids running remotely loaded JavaScript.

No diagram data is ever sent externally, nor do we send any analytics about app usage externally. There is a Content Security Policy in place on the web part of the interface to ensure external transmission cannot happen, even by accident.

Security and isolating the app are the primarily objectives of draw.io desktop. If you ask for anything that involves external connections enabled in the app by default, the answer will be no.

Support
-------

Support is provided on a reasonable business constraints basis, but without anything contractually binding. All support is provided via this repo. There is no private ticketing support for non-paying users.

Purchasing draw.io for Confluence or Jira does not entitle you to commercial support for draw.io desktop.

Developing
----------

draw.io is a git submodule of drawio-desktop. To get both you need to clone recursively:

git clone --recursive https://github.com/jgraph/drawio-desktop.git

To run this:
1. npm install (in the root directory of this repo)
2. [internal use only] export DRAWIO_ENV=dev if you want to develop/debug in dev mode.
3. npm start _in the root directory of this repo_ runs the app. For debugging, use npm start --enable-logging.

Note: If a symlink is used to refer to drawio repo (instead of the submodule), then symlink the node_modules directory inside drawio/src/main/webapp also.

To release:
1. Update the draw.io sub-module and push the change. Add version tag before pushing to origin.
2. Wait for the builds to complete (https://travis-ci.org/jgraph/drawio-desktop and https://ci.appveyor.com/project/davidjgraph/drawio-desktop)
3. Go to https://github.com/jgraph/drawio-desktop/releases, edit the preview release.
4. Download the windows exe and windows portable, sign them using signtool sign /a /tr http://rfc3161timestamp.globalsign.com/advanced /td SHA256 c:/path/to/your/file.exe
5. Re-upload signed file as draw.io-windows-installer-x.y.z.exe and draw.io-windows-no-installer-x.y.z.exe
6. Add release notes
7. Publish release

Note: In Windows release, when using both x64 and is32 as arch, the result is one big file with both archs. This is why we split them.

Local Storage and Session Storage is stored in the AppData folder:

- macOS: ~/Library/Application Support/draw.io
- Windows: C:\Users\<USER-NAME>\AppData\Roaming\draw.io\

Not open-contribution
---------------------

draw.io is closed to contributions (unless a maintainer permits it, which is extremely rare).

The level of complexity of this project means that even simple changes
can break a _lot_ of other moving parts. The amount of testing required
is far more than it first seems. If we were to receive a PR, we'd have
to basically throw it away and write it how we want it to be implemented.

We are grateful for community involvement, bug reports, & feature requests. We do
not wish to come off as anything but welcoming, however, we've
made the decision to keep this project closed to contributions for
the long term viability of the project.