jgraph/drawio-desktop
Official electron build of draw.io
Healthy across all four use cases
weakest axisPermissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit today
- ✓6 active contributors
- ✓Apache-2.0 licensed
- ✓CI configured
- ⚠Concentrated ownership — top contributor handles 72% of recent commits
- ⚠No test directory detected
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the “Healthy” badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/jgraph/drawio-desktop)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/jgraph/drawio-desktop on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: jgraph/drawio-desktop
Generated by RepoPilot · 2026-05-06 · Source
Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/jgraph/drawio-desktop shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
Verdict
GO — Healthy across all four use cases
- Last commit today
- 6 active contributors
- Apache-2.0 licensed
- CI configured
- ⚠ Concentrated ownership — top contributor handles 72% of recent commits
- ⚠ No test directory detected
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live jgraph/drawio-desktop
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/jgraph/drawio-desktop.
What it runs against: a local clone of jgraph/drawio-desktop — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in jgraph/drawio-desktop | Confirms the artifact applies here, not a fork |
| 2 | License is still Apache-2.0 | Catches relicense before you depend on it |
| 3 | Default branch dev exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 30 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of jgraph/drawio-desktop. If you don't
# have one yet, run these first:
#
# git clone https://github.com/jgraph/drawio-desktop.git
# cd drawio-desktop
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of jgraph/drawio-desktop and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "jgraph/drawio-desktop(\\.git)?\\b" \\
&& ok "origin remote is jgraph/drawio-desktop" \\
|| miss "origin remote is not jgraph/drawio-desktop (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(Apache-2\\.0)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"Apache-2\\.0\"" package.json 2>/dev/null) \\
&& ok "license is Apache-2.0" \\
|| miss "license drift — was Apache-2.0 at generation time"
# 3. Default branch
git rev-parse --verify dev >/dev/null 2>&1 \\
&& ok "default branch dev exists" \\
|| miss "default branch dev no longer exists"
# 4. Critical files exist
test -f "src/main/electron.js" \\
&& ok "src/main/electron.js" \\
|| miss "missing critical file: src/main/electron.js"
test -f "package.json" \\
&& ok "package.json" \\
|| miss "missing critical file: package.json"
test -f "src/main/electron-preload.js" \\
&& ok "src/main/electron-preload.js" \\
|| miss "missing critical file: src/main/electron-preload.js"
test -f "electron-builder-win.json" \\
&& ok "electron-builder-win.json" \\
|| miss "missing critical file: electron-builder-win.json"
test -f ".github/workflows/electron-builder.yml" \\
&& ok ".github/workflows/electron-builder.yml" \\
|| miss "missing critical file: .github/workflows/electron-builder.yml"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 30 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~0d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/jgraph/drawio-desktop"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
TL;DR
drawio-desktop is an Electron-based desktop application that wraps the core draw.io editor (via git submodule), providing a standalone diagramming tool for Windows, macOS, and Linux. It delivers offline-first diagram creation with zero external data transmission, secured by Content Security Policy and self-contained JavaScript bundles, while maintaining feature parity with the web editor through the bundled drawio submodule. Single-entry-point Electron app: src/main/electron.js bootstraps the application, which loads the bundled drawio editor (via git submodule at ./drawio/src/main/webapp) as the core rendering engine. Build artifacts organize platform-specific resources in ./build/ (icons, Windows AppX assets, macOS entitlements, notarization config). Release process is orchestrated via npm scripts invoking electron-builder with platform-specific configs (electron-builder-*.json files).
Who it's for
Software architects, UML modelers, and technical teams who need to create flowcharts, diagrams, and network topologies offline without cloud dependency or analytics tracking. Also relevant for organizations with air-gapped or security-conscious deployment requirements who want a native desktop experience.
Maturity & risk
Production-ready and actively maintained. Current version is 29.7.9 with CI/CD pipelines for Windows (NSIS/MSI/portable), Linux, macOS, and APPX (Microsoft Store) via GitHub Actions workflows. Node >=20 requirement and modern Electron 40.8.4 indicate current development. The presence of established release processes (doc/RELEASE_PROCESS.md) and multiple distribution channels suggests stable, mature operations.
Low risk overall, but dependency on the drawio submodule means breaking changes upstream could affect this build. 91.9KB of JavaScript is substantial; security model relies entirely on Content Security Policy enforcement. Single team ownership (jgraph) creates maintenance concentration, though Apache 2.0 licensing enables community forks. No visible test suite in the file listing is a minor concern for a distribution package.
Active areas of work
Active release cycle with version 29.7.9 current. GitHub Actions workflows (electron-builder.yml, electron-builder-win.yml, prepare-release.yml) automate multi-platform builds and publishing. Hash verification (hash-gen.yml) and stale issue management indicate ongoing maintenance. Recent additions like build/fuses.cjs suggest adoption of Electron security hardening (fuses API).
Get running
Clone recursively to include the drawio submodule: git clone --recursive https://github.com/jgraph/drawio-desktop.git. Then run npm install in the repository root. Start the dev app with npm start (use npm start --enable-logging for debugging). Optionally set export DRAWIO_ENV=dev for development mode before running.
Daily commands:
For development: npm install, then npm start. For debugging: npm start --enable-logging. For releases to specific platforms: npm run release-win (Windows NSIS), npm run release-appx (Microsoft Store), npm run release-linux (Linux/AppImage), npm run release-snap (Snap package). All release scripts invoke electron-builder with platform-specific configuration files.
Map of the codebase
src/main/electron.js— Main Electron process entry point that initializes the application window, handles IPC communication, and manages the desktop app lifecycle.package.json— Defines all build targets (Windows/Mac/Linux), release scripts, and Node version requirements; essential for understanding supported platforms and build process.src/main/electron-preload.js— Preload script that bridges Electron's main process and renderer, exposing safe IPC APIs to the draw.io frontend.electron-builder-win.json— Windows build configuration that defines installer type, signing, and distribution strategy; critical for Windows release pipeline..github/workflows/electron-builder.yml— CI/CD pipeline for macOS and Linux builds; automates release artifact generation and publishing.build/notarize.mjs— Apple notarization handler for macOS code-signing compliance; required for modern macOS distribution..gitmodules— Declares the core draw.io editor as a git submodule dependency; defines how the desktop wrapper integrates with the web editor.
How to make changes
Add a new IPC handler for desktop-specific feature
- Add a new context bridge API in preload script to expose a safe channel to renderer (
src/main/electron-preload.js) - Implement the corresponding ipcMain handler in the main process that calls the OS API or accesses restricted resources (
src/main/electron.js) - Update entitlements for macOS if the feature requires sandbox exceptions (e.g., file system access) (
build/entitlements.mac.plist)
Build and release for a new Windows platform variant
- Create a new electron-builder config JSON file (e.g., electron-builder-win-custom.json) specifying target architecture, output directory, and signing certificate (
electron-builder-win.json) - Add a new GitHub Actions workflow file that triggers on release tags and calls electron-builder with your config (
.github/workflows/electron-builder-win.yml) - Update package.json scripts to include a release command for the new variant (e.g., release-win-custom) (
package.json)
Add support for a new Linux distribution or packaging format
- Update the linux target in the electron-builder config to include the new format (e.g., rpm, deb, freebsd) (
electron-builder-linux-mac.json) - If creating a snap, create or update electron-builder-snap.json with snap-specific metadata and confinement settings (
electron-builder-snap.json) - Add or update GitHub Actions workflow to build and publish the new format on release tags (
.github/workflows/electron-builder.yml)
Update the embedded draw.io editor to a new version
- Run git submodule update --remote to pull the latest version of the core draw.io repository (
.gitmodules) - Review and commit the submodule update; if changes to IPC or preload are needed for new features, update the preload script (
src/main/electron-preload.js) - Test the build locally with npm start, then bump the version in package.json and create a release (
package.json)
Why these technologies
- Electron — Enables a cross-platform desktop application using web technologies (Chromium + Node.js), allowing a single codebase to target Windows, macOS, and Linux.
- electron-builder — Simplifies building and publishing installers across multiple platforms with a single configuration; handles code signing, auto-update, and artifact distribution.
- Git submodule (drawio core) — Allows the desktop wrapper to stay in sync with the core draw.io web editor without duplicating code or maintaining a separate build pipeline.
- GitHub Actions — Provides free CI/CD for automated builds on each platform; integrates with GitHub Releases for distribution.
- Apple notarization (build/notarize.mjs) — Required for modern macOS distribution; verifies the app has not been tampered with and is safe to run.
Trade-offs already made
-
Single Electron process wrapping a web app vs. native implementation
- Why: Reuses the battle-tested draw.io web editor code; eliminates divergence between web and desktop versions.
- Consequence: Larger memory footprint and startup time compared to a native application; limited access to advanced OS-level features without explicit preload bridges.
-
Platform-specific build configs (separate .json files per OS/arch) vs. unified config
- Why: Allows fine-grained control over installer type, signing certificate, and distribution per platform (e.g., MSI for per-user Windows, DMG for macOS).
- Consequence: More configuration files to maintain; risk of divergence if one platform's config falls out of sync.
-
Git submodule for core editor vs. npm package dependency
- Why: Allows simultaneous development of desktop wrapper and core editor in the same CI/CD pipeline; easier to cherry-pick urgent fixes.
- Consequence: Submodule workflows are less familiar to some developers; requires explicit git submodule update commands.
-
Disable Electron's auto-update in favor of electron-builder's GitHub Releases distribution
- Why: Simplifies release process and avoids hosting an update server; leverages GitHub's CDN for downloads.
- Consequence: No delta updates; users must re-download the full installer each time.
Non-goals (don't propose these)
- Does not host a central update server; relies entirely on GitHub Releases for distribution.
- Does not support automatic delta updates; full application binaries are downloaded on each release.
- Does not enforce code signing or authentication within the app itself; relies on OS-level code signing (Apple notarization, Windows SmartScreen).
- Does not include a backend service or cloud synchronization; all file operations are local.
Traps & gotchas
Git submodule must be cloned recursively (git clone --recursive) or drawio source will be missing. If using a symlink for drawio instead of the submodule, you must also symlink node_modules inside drawio/src/main/webapp (non-obvious dependency resolution). DRAWIO_ENV=dev is undocumented in package.json but mentioned in README for development/debug mode. macOS notarization (build/notarize.mjs) requires Apple Developer credentials via environment variables not shown in the config files. Electron fuses (build/fuses.cjs) may be security-hardening code requiring specific Electron version compatibility. No visible npm test suite, so changes are validated only through manual testing and CI build success.
Architecture
Concepts to learn
- Content Security Policy (CSP) — draw.io Desktop enforces CSP to prevent remote code execution and data exfiltration; understanding CSP rules is critical for securing Electron apps bundling web content.
- Electron Multi-Process Architecture (Main + Renderer) — This repo wraps a web editor in Electron's main/renderer process model; understanding the boundary between them is essential for debugging crashes, IPC, and security.
- Code Signing and Notarization (macOS/Windows) — build/notarize.mjs and electron-builder configs implement Apple notarization and Windows code signing; these are non-negotiable for distribution on modern OS versions.
- Git Submodules — The drawio core is a git submodule; incorrect clone/update workflow will corrupt the build. Understanding
git submodule update --recursiveis essential. - Electron Auto-Update (electron-updater) — electron-updater in dependencies handles secure update checks to github.com and S3 downloads; the update mechanism is core to the security model (isolated from general internet).
- Platform-Specific Installer Formats (NSIS/MSI/AppX/AppImage/Snap) — This repo releases 7+ distribution formats (Windows NSIS/MSI/portable/AppX, Linux AppImage/Snap, macOS DMG); each has different signing, auto-update, and user experience implications.
- Electron Fuses (Security Hardening) — build/fuses.cjs suggests adoption of Electron's new fuses API to disable potentially dangerous features (Node integration, preload scripts); critical for modern security posture.
Related repos
jgraph/drawio— The core web-based draw.io editor bundled as a git submodule in this repo; all diagram functionality comes from here.electron/electron— The Electron framework that powers the desktop wrapper; critical for understanding the main process, build config, and security model.electron-userland/electron-builder— The packaging/distribution tool used via npm scripts (release-* commands); configures multi-platform installers and code signing.yabwe/online-draw— A Dockerized alternative for running draw.io in a container; relevant if you need headless or server-side diagram generation.jwilsson/drawio-cli— Command-line wrapper for draw.io; complements the desktop app for scripting and CI/CD diagram exports.
PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add GitHub Action workflow for automated code signing and notarization on macOS releases
The repo has build/notarize.mjs and build/entitlements.mac.plist files indicating macOS code signing infrastructure exists, but there's no dedicated GitHub Actions workflow for macOS builds like there is for Windows (electron-builder-win.yml, electron-builder-win32.yml). This gaps means macOS releases require manual local builds, increasing friction and inconsistency. Adding a .github/workflows/electron-builder-mac.yml would enable automated, signed macOS releases matching the Windows release automation.
- [ ] Create .github/workflows/electron-builder-mac.yml based on the pattern in .github/workflows/electron-builder.yml
- [ ] Configure the workflow to use build/notarize.mjs with required environment secrets (APPLE_TEAM_ID, APPLE_NOTARY_USER, APPLE_NOTARY_PASSWORD)
- [ ] Test the workflow with electron-builder-linux-mac.json config and verify code signing/notarization steps
- [ ] Document the required Apple credentials in DEVELOPMENT.md or doc/RELEASE_PROCESS.md
Implement Electron security hardening by adding fuses configuration validation in CI
The repo has build/fuses.cjs file for Electron security fuses, but there's no CI workflow to validate that fuses are properly applied to built binaries. This risks shipping unsigned/improperly configured security settings. Adding a validation step in the existing release workflows would ensure build/fuses.cjs settings are consistently applied across all platform builds and catch configuration regressions early.
- [ ] Review build/fuses.cjs to understand current security fuse configuration
- [ ] Add a validation step to .github/workflows/electron-builder.yml and .github/workflows/electron-builder-win.yml that verifies fuses are applied to built binaries using @electron/fuses
- [ ] Create a build/validate-fuses.mjs script to check binary integrity post-build
- [ ] Document the fuses configuration and validation process in DEVELOPMENT.md
Add integration tests for Electron IPC preload bridge in src/main/electron-preload.js
The preload.js and src/main/electron-preload.js files handle critical security boundaries between the main process and renderer, but there are no visible test files in the repo (no src/tests, tests, or .spec.js files). This is a high-risk area where IPC vulnerabilities could be introduced. Adding Jest/Vitest tests for the preload script would validate context isolation and IPC message handling without requiring full end-to-end testing.
- [ ] Set up Jest or Vitest in package.json with test configuration
- [ ] Create src/main/tests/electron-preload.test.js to test exposed IPC APIs and context isolation
- [ ] Add tests for the main process electron.js IPC listeners (e.g., 'menu-file-open', 'menu-file-saveas')
- [ ] Add pre-commit test runner to package.json scripts (e.g., 'test' and 'test:watch')
- [ ] Update DEVELOPMENT.md with testing instructions for new contributors
Good first issues
- Add integration tests for multi-platform file dialog interactions: No test files visible in the repo. Electron file dialogs behave differently across Windows/macOS/Linux; adding test coverage in src/main/ would catch cross-platform regressions early.
- Document platform-specific build prerequisites in DEVELOPMENT.md: DEVELOPMENT.md exists but file list suggests macOS notarization (Apple certs), Windows signing (code signing cert), and Linux dependencies are undocumented. New contributors hit friction here.
- Automate drawio submodule version pinning and update checks in CI: sync.cjs exists to sync drawio, but there's no visible automated PR or notification when upstream drawio has breaking changes. Adding a workflow (like GitHub's dependabot but for submodules) would catch incompatibilities.
Top contributors
- @davidjgraph — 72 commits
- @alderg — 14 commits
- @github-actions[bot] — 5 commits
- @dependabot[bot] — 5 commits
- @m-mohamedin — 2 commits
Recent commits
a4cdb82— Made silent update the default (with an option to disable that), added check for updates interval configuration, and dis (m-mohamedin)9bfa3bb— Merge pull request #2276 from murataslan1/fix/cache-autoupdate-check (m-mohamedin)5986014— Removes toolbar from macOS Quick Look preview (alderg)2bd3c2d— Documents Windows installer admin behaviour [jgraph/drawio-desktop#2404] (alderg)b26ef74— Merge pull request #2400 from jgraph/releases/v29.7.9 (davidjgraph)f1aeeca— Prepare release v29.7.9 (github-actions[bot])bd8e703— Adds option for pdf save to fix XML embedding [jgraph/drawio-desktop#2394] (davidjgraph)0030fff— Updates to 29.7.8 (davidjgraph)cb98889— Updates drawio submodule (davidjgraph)50c2fc7— ci: source release VERSION from drawio-dev in build workflows (davidjgraph)
Security observations
- High · Dependency on electron-updater with automatic updates —
package.json (electron-updater dependency), electron-builder-*.json files. The application uses electron-updater v6.8.3 with release scripts configured to publish with 'always' policy. This could potentially allow remote code execution if the update server is compromised or if there are vulnerabilities in the update mechanism. The configuration in multiple electron-builder JSON files suggests auto-update is enabled across platforms. Fix: Implement signature verification for all updates, use secure update channels with HTTPS pinning, consider implementing staged rollouts, and regularly audit the update infrastructure. Review electron-updater security advisories. - High · Insecure context-menu plugin —
package.json (electron-context-menu dependency), src/main/electron.js. The application uses electron-context-menu v4.1.1, which may expose dangerous functionality or allow context menu injection attacks if not properly configured. This could lead to XSS or command injection vulnerabilities. Fix: Review how electron-context-menu is initialized and configured. Ensure spellcheck features are properly sandboxed, disable dangerous options (like shell integration), and implement a Content Security Policy (CSP) to prevent context menu injection. - High · Preload script without proper isolation —
preload.js, src/main/electron-preload.js, src/main/electron.js. The presence of preload.js at the root suggests preload scripts may be used to expose Node.js APIs to the renderer process. Without proper context isolation and API validation, this could allow renderer-to-main privilege escalation. Fix: Ensure contextIsolation is enabled in BrowserWindow creation, use a whitelist of safe IPC methods, implement strict input validation on all IPC messages, and regularly audit the preload script for privilege escalation risks. - Medium · Outdated Electron version —
package.json (electron dev dependency). The application uses Electron v40.8.4. While relatively recent, Electron versions should be kept current with security patches. Verify that all known CVEs for this version have been addressed. Fix: Implement a policy to update Electron to the latest stable version within 30 days of release. Monitor Electron security advisories and apply patches immediately for critical vulnerabilities. - Medium · Use of commander CLI library with potential injection —
package.json (commander dependency), src/main/electron.js. The application uses commander v14.0.3 for CLI argument parsing. If user input is not properly sanitized before being passed to system commands, this could lead to command injection attacks. Fix: Validate and sanitize all command-line arguments before use. Avoid using shell=true when spawning child processes. Use parameterized APIs instead of string concatenation for system calls. - Medium · PDF processing with third-party library —
package.json (@cantoo/pdf-lib dependency). The application uses @cantoo/pdf-lib v2.6.1 for PDF manipulation. PDF processing is a known attack vector for exploits. Ensure this library and its dependencies are kept updated and that PDF files from untrusted sources are properly validated. Fix: Keep the PDF library updated with security patches. Implement file type validation before processing PDFs. Consider sandboxing PDF processing in a separate process. Monitor for CVEs in this library. - Medium · Electron Store for persistent data without encryption —
package.json (electron-store dependency), src/main/electron.js. The application uses electron-store v11.0.2 for persistent configuration storage. By default, electron-store does not encrypt sensitive data, making stored credentials or API keys potentially vulnerable if the user's file system is compromised. Fix: Enable encryption for sensitive data stored in electron-store using the cipherKey option. Never store API keys, tokens, or passwords in plaintext. Consider using OS-level keychains for sensitive credentials. - Medium · Missing Content Security Policy (CSP) —
src/main/electron.js, src/main/electron-preload.js. No CSP headers are visible in the codebase structure. Without a strict CSP, the application is vulnerable to XSS attacks, particularly since it wraps a web-based editor (draw.io core). Fix: Implement a strict Content Security
LLM-derived; treat as a starting point, not a security audit.
Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.