Jesse A. Green / notebook

drawio-desktop User Guide

Generated April 2026 from jgraph/drawio-desktop at 5986014

AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it.

drawio-desktop is the official offline desktop edition of the popular draw.io (also known as diagrams.net) diagram editor. It is an Electron application (Electron 40 on Node 20) that wraps the upstream jgraph/drawio web app and runs it locally with full file-system access, native OS menus, file associations for .drawio and .vsdx, and a powerful command-line export pipeline. The desktop edition publishes signed installers for Windows (NSIS, MSI, AppX, 32-bit and ARM64), macOS (DMG, ZIP, universal), and Linux (AppImage, .deb, .rpm, snap).

This guide documents the desktop wrapper itself — installation, the desktop-specific menu and file-handling surface, the command-line export interface, and the configuration flags honored by the Electron main process. The actual diagram editor (shapes, libraries, layers, the canvas, plugins, keyboard shortcuts inside a diagram) is implemented in the upstream jgraph/drawio web project — see diagrams.net documentation and the upstream repo for editor-side reference.


1. Quick Start

The fastest way to get drawio-desktop running is to download a prebuilt installer from the project's GitHub Releases page — there is no compilation required and updates are signed and delivered automatically.

Prerequisite: a 64-bit Windows 10+, macOS 11+, or Linux desktop. Disk: under 300 MB. RAM: 1 GB minimum.

  1. Open github.com/jgraph/drawio-desktop/releases.
  2. Pick the asset for your platform from the table below.
  3. Run the installer (Windows/macOS) or extract/install the package (Linux).
  4. Launch draw.io from your Start menu / Applications folder / app launcher.
Platform Recommended Asset Notes
Windows 10/11 (x64) drawio-<version>-windows-installer.exe NSIS installer, per-machine, lets you choose install dir
Windows 10/11 (x64, IT) drawio-<version>.msi MSI for Group Policy / Intune deployment
Windows ARM64 drawio-arm64-<version>-windows-arm64-installer.exe NSIS installer for Surface / Snapdragon devices
Windows 32-bit drawio-ia32-<version>-windows-32bit-installer.exe Legacy 32-bit only
macOS Intel/Apple Silicon drawio-<arch>-<version>.dmg arch = x64, arm64, or universal; signed and notarized
Linux x64 / ARM64 drawio-<arch>-<version>.AppImage Portable, no install required
Debian / Ubuntu drawio-<arch>-<version>.deb sudo apt install ./drawio-amd64-<version>.deb
Fedora / RHEL / openSUSE drawio-<arch>-<version>.rpm sudo rpm -i drawio-x86_64-<version>.rpm
Snap (Ubuntu) drawio_<version>_amd64.snap sudo snap install --dangerous ./drawio_*.snap
Microsoft Store AppX bundle Auto-managed via Store, no manual update

The artifact name templates come from the project's electron-builder configs (electron-builder-win.json, electron-builder-linux-mac.json, electron-builder-win-arm64.json, electron-builder-win32.json, electron-builder-snap.json, and electron-builder-appx.json), so substitute your version (e.g. 29.6.6) and architecture (x64, arm64, ia32, universal).

Once installed, double-click any .drawio file in your file manager — drawio-desktop registers itself as the default application for that extension and will open it directly.

Tip

You can also pass a file straight to the binary on launch: drawio path/to/diagram.drawio. The main process opens the file in the first window via the args-obj IPC payload that the renderer listens for, and subsequent file-open requests from the OS spawn additional windows.


2. Installation

drawio-desktop ships as platform-specific signed binaries for every common desktop OS. The recommended path is always the prebuilt installer from the GitHub Releases page; build-from-source is reserved for contributors.

2.1 System requirements

Resource Minimum Notes
OS Windows 10 (1809+), macOS 11 Big Sur, modern Linux (glibc 2.31+) Bundled Electron 40 sets the floor
CPU 64-bit x86 or ARM64 32-bit Windows still produced via release-win32
RAM 1 GB 4 GB+ recommended for large multi-page diagrams
Disk 300 MB Includes bundled Chromium runtime
Display 1024x768 Application starts at 1200x800 and remembers lastWinSize
Node (build only) >=20 Per package.json engines field

2.2 Windows

NSIS installer (most users)

Download drawio-<version>-windows-installer.exe and run it. The installer is per-machine (perMachine: true), prompts for an install directory (allowToChangeInstallationDirectory: true), and does not automatically create a desktop shortcut (createDesktopShortcut: false) or run the app after install (runAfterFinish: false). Confirm those defaults match your environment before clicking Install.

MSI (Intune / Group Policy)

Download drawio-<version>.msi and deploy via Microsoft Endpoint Manager, Group Policy software installation, PDQ Deploy, or msiexec:

msiexec /i drawio-29.6.6.msi /qn /norestart

The MSI shares the NSIS post-install behavior — no shortcut, no auto-run.

Microsoft Store (AppX)

Search "draw.io Diagrams" in the Microsoft Store. The AppX is published under publisher CN=9E628CCB-BE04-4557-A5A8-81EC34B09733 and identity draw.io.draw.ioDiagrams. Updates are managed by the Store — disable in-app update checks if you use this channel (see DRAWIO_DISABLE_UPDATE in Section 3).

Windows ARM64

Use drawio-arm64-<version>-windows-arm64-installer.exe (NSIS) or the corresponding portable EXE if you cannot install. The portable build runs the application without writing to Program Files.

Windows 32-bit

Use drawio-ia32-<version>-windows-32bit-installer.exe. Only build separately maintained for legacy systems.

Important

Windows installers are not Authenticode-signed by every distributor — verify the GitHub Releases SHA against the published latest.yml from the same release tag. The electron-updater integration uses the GitHub provider (provider: "github", owner: jgraph, repo: drawio-desktop) for in-app updates, but the first install must be trusted manually.

2.3 macOS

Download the .dmg matching your CPU. Three variants exist:

Variant When to use
drawio-x64-<version>.dmg Intel Macs only
drawio-arm64-<version>.dmg Apple Silicon (M1/M2/M3/M4)
drawio-universal-<version>.dmg Single binary that runs natively on both architectures

Open the DMG, drag draw.io into /Applications, eject the volume. The app is signed with the Hardened Runtime enabled (hardenedRuntime: true) and Apple-notarized via the project's build/notarize.mjs pipeline, so Gatekeeper allows it without xattr workarounds. Entitlements are inherited from build/entitlements.mac.plist for both the parent process (entitlements) and child Electron helpers (entitlementsInherit).

Note

The macOS bundle declares LSItemContentTypes: ["com.jgraph.drawio"] with LSHandlerRank: "Owner", meaning Finder treats drawio-desktop as the owning application for .drawio files (UTI com.jgraph.drawio, conforms to public.xml and public.data) and assigns it as default opener on first run. .vsdx is registered as LSHandlerRank: "Default" — drawio-desktop accepts opens but does not claim exclusive ownership.

2.4 Linux

AppImage

Most portable. Single file, runs anywhere:

chmod +x drawio-amd64-29.6.6.AppImage
./drawio-amd64-29.6.6.AppImage

.deb (Debian / Ubuntu)

sudo apt install ./drawio-amd64-29.6.6.deb
drawio

The Debian package installs the binary as drawio (per executableName: "drawio") and registers .drawio and .vsdx MIME handlers.

.rpm (Fedora / RHEL / openSUSE)

sudo dnf install drawio-x86_64-29.6.6.rpm
drawio

The RPM is built with --rpm-rpmbuild-define=_build_id_links none and --rpm-digest=sha256 for maximum compatibility across RPM distros.

Snap

sudo snap install drawio

The snap package uses base: core20 and requests the default and removable-media plugs. The first plug grants standard desktop access; removable-media allows opening diagrams from USB sticks and external drives. Ubuntu users on 22.04+ may see GitHub issue #2219 (snap depends on a very old GNOME package) — prefer the .deb or AppImage on those systems.

Flatpak

drawio-desktop is not published as a first-party Flatpak by jgraph, but a community Flathub build exists. The main process detects flatpak sandboxing via the presence of /.flatpak-info and automatically disables the in-app updater in that case (since flatpak handles its own updates).

Warning

The Linux .desktop entry sets StartupWMClass: "draw.io". Some tiling window managers (i3, Sway, Hyprland) match against this exact class name — if your config rules use lowercase drawio, taskbar icons or window-grouping rules may not match.

2.5 Build from source (contributors)

Only required if you intend to patch the desktop wrapper. The diagram editor itself lives in the jgraph/drawio submodule.

git clone --recurse-submodules https://github.com/jgraph/drawio-desktop.git
cd drawio-desktop
nvm use            # uses the version pinned in .nvmrc
npm install
npm run sync       # node ./sync.cjs (syncs upstream drawio assets)
npm start          # electron .

To produce installers locally, run one of the published release-* scripts (each uses a dedicated electron-builder-*.json config):

Script Purpose
npm run release-win NSIS + MSI x64
npm run release-win32 NSIS ia32
npm run release-win-arm64 NSIS + portable arm64
npm run release-appx Microsoft Store AppX x64
npm run release-linux AppImage / deb / rpm + macOS dmg/zip
npm run release-snap snap (publishes never by default)

Caution

The release-win, release-win32, release-win-arm64, release-appx, and release-linux scripts pass --publish always to electron-builder, which uploads artifacts to GitHub Releases using the credentials in your environment (GH_TOKEN). Only run these if you are an official maintainer with publish rights. For local-only builds, change always to never in your invocation: npx electron-builder --config electron-builder-win.json --publish never.


3. Configuration

drawio-desktop configuration is split across environment variables, command-line flags, and an electron-store JSON file persisted under the OS-standard app-data directory. There is no config.yaml or ~/.drawiorc — all desktop preferences live in one of these three places.

3.1 Environment variables

Variable Effect Source
DRAWIO_DISABLE_UPDATE Set to true to suppress all auto-update checks (combine with packaging that handles updates externally — Microsoft Store, snap, flatpak) electron.js:33
DRAWIO_SILENT_UPDATE Set to true to download and install updates in the background without prompting; only honored when updates are not already disabled electron.js:36
DRAWIO_ENV Set to dev to enable developer mode: opens DevTools on launch, logs window-lifecycle events, exposes upstream draw.io test/dev URL parameters electron.js:74

Important

DRAWIO_DISABLE_UPDATE is also implicitly enabled when the app detects flatpak sandboxing (/.flatpak-info present) or when the --disable-update command-line flag is passed. Snap and AppX channels manage their own updates; explicitly setting this variable in those packages is harmless but redundant.

3.2 Command-line flags (Electron main process)

These flags are honored by the desktop wrapper itself, not the upstream Electron framework. Pass them as the first argument when launching the binary directly.

Flag Effect
--disable-update Same as DRAWIO_DISABLE_UPDATE=true
--silent-update Same as DRAWIO_SILENT_UPDATE=true
--disable-acceleration Calls app.disableHardwareAcceleration() before window creation. Use on systems where GPU compositing causes rendering glitches
--enable-plugins Allows loading plugins from the per-user plugins directory (see Section 4.6). Plugins are blocked by default for security
--no-sandbox Stripped from input-file path lists during CLI export. Pass it for compatibility on container/CI environments where the chrome sandbox is unavailable

The full export-mode CLI surface is described in Section 4.4; those flags are only active when -x/--export is passed.

3.3 Persistent store (electron-store)

User preferences are saved automatically through the electron-store package, which writes a JSON file under the OS standard:

Platform Path
Windows %APPDATA%\draw.io\config.json
macOS ~/Library/Application Support/draw.io/config.json
Linux ~/.config/draw.io/config.json

Recognized keys written by drawio-desktop:

Key Type Default Purpose
lastWinSize string 1200,800,0,0,false,false width,height,x,y,maximized,fullscreen — restored on next launch
enableSpellCheck bool true on macOS, false elsewhere Toggles Chromium spellchecker in the renderer
enableStoreBkp bool true Keeps .bkp backup of every saved file
isGoogleFontsEnabled bool false Allows fetching fonts.googleapis.com and fonts.gstatic.com (relaxes CSP)
dontCheckUpdates bool false Set to true to suppress the periodic autoUpdater.checkForUpdates() call on launch

Tip

Delete config.json while the app is closed to fully reset window position, spell-check, backup, and Google-Fonts state to defaults. The next launch regenerates the file with built-in defaults.

3.4 urlParams.json overlay

If a file named urlParams.json exists in the process's current working directory at launch, every key inside is merged into the URL query passed to the bundled draw.io web app. This is an undocumented but supported escape hatch for forcing upstream draw.io URL parameters (for example, enabling experimental modes) without modifying the bundle.

{
  "ui": "atlas",
  "tr": 0,
  "math": 1
}

Caution

Only place a urlParams.json you trust in the working directory — values are merged unconditionally into the URL the renderer loads. A malicious overlay could enable upstream features that bypass the desktop wrapper's defaults.

3.5 Logging

The desktop wrapper uses electron-log for auto-updater diagnostics. Default file-level threshold is error; pass --enable-logging (a standard Electron flag) to forward Chromium console output to the controlling terminal for renderer-side debugging.

Log file Location
Windows %USERPROFILE%\AppData\Roaming\draw.io\logs\main.log
macOS ~/Library/Logs/draw.io/main.log
Linux ~/.config/draw.io/logs/main.log

4. Core Usage

This section covers the desktop-specific surface — file association behavior, native menus, multi-window management, the auto-update flow, and the command-line export pipeline. Everything that happens inside the diagram canvas (drawing, editing, libraries, search) lives in the upstream jgraph/drawio web app and is identical across desktop, web, and Confluence/Jira embeds.

4.1 Opening files

drawio-desktop accepts diagram files in three ways:

  1. Double-click in your file manager — the OS dispatches an open-file event (macOS) or relaunches the binary with the path appended to argv (Windows/Linux). The first window opens the file directly; if a window is already loaded, a second window is created for the new file.
  2. Drag a file onto the dock/taskbar icon — same path as #1.
  3. Pass on the command line — drawio diagram.drawio. Multiple files can be passed; each opens in a new window.

The desktop wrapper enforces a single-instance lock via app.requestSingleInstanceLock(). Launching drawio while another instance is running forwards the file path to the existing process via the second-instance event, and the existing process opens it in a new window.

Note

When you save a .drawio file, the wrapper writes through O_SYNC | O_CREAT | O_WRONLY | O_TRUNC and reads the file back to verify content integrity. If verification fails it retries up to 3 times before reporting Error: all saving trials failed. A .bkp sibling file is also created when enableStoreBkp is true.

4.2 File associations

The installer registers the application as a handler for these extensions on every supported platform:

Extension Role MIME type Default opener?
.drawio Editor application/vnd.jgraph.mxfile Yes (claimed exclusively)
.vsdx Editor application/vnd.visio No (registers without claiming)

The .dio extension (sometimes seen on legacy diagrams) is not in the registered list — files with that extension must be renamed or opened via File → Open inside the application.

Warning

Per GitHub issue #2338, .drawio.pdf files (PDFs with embedded diagram XML) sometimes do not open via double-click on Windows because the OS routes them to the system PDF handler. Open these from the application's File → Open menu instead, or rename the file to .drawio if you want to edit the diagram content.

4.3 Native menus and windows

On macOS, drawio-desktop installs an application menu with these items:

Menu Items
draw.io About draw.io (opens https://www.drawio.com), Support (opens GitHub issues), Check for updates (hidden when updates disabled), Actual Size / Zoom In / Zoom Out, Hide / Hide Others / Show All, Quit
Edit Undo, Redo, Cut, Copy, Paste, Paste and Match Style, Select All

On Windows and Linux the application menubar is hidden (menu.setApplicationMenu(null)); all commands are reached through the in-canvas menus rendered by the upstream draw.io web app.

The wrapper intercepts Ctrl+Shift+V (Windows/Linux) and Cmd+Shift+V (macOS) at the before-input-event stage and routes it to webContents.pasteAndMatchStyle(). This is the desktop-only fix tracked in issue #2380.

Tip

A right-click in any text input field shows a custom context menu (via electron-context-menu) with Copy / Save Image / Save Image As / Select All plus Paste and Match Style when plain text is on the clipboard. Searching the web and dictionary lookups are deliberately disabled for offline-first behavior.

4.4 Command-line export

Pass -x / --export to put drawio-desktop into headless export mode. The application creates a hidden BrowserWindow, loads the diagram, renders it, writes the output, and quits. No editor UI appears.

Basic syntax

drawio --export [options] <input file or folder>

Format and output flags

Flag Default Description
-c, --create — Create a new empty file if no input is passed
-k, --check — Do not overwrite existing files; suffix with -1, -2 instead
-x, --export — Enables export mode
-r, --recursive — For folder input, recurse into subdirectories
-o, --output <path> input name + format ext Output file or folder
-f, --format <fmt> pdf One of pdf, svg, png, jpeg, jpg, xml, html

Image quality and layout

Flag Default Description
-q, --quality <n> 90 JPEG quality 0-100
-t, --transparent — Transparent PNG background
-b, --border <n> 0 Border around the diagram
-s, --scale <n> 1 Scale factor
--width <n> — Fit to width, preserve aspect ratio
--height <n> — Fit to height, preserve aspect ratio
--crop — Crop PDF to diagram size

Page selection

Flag Description
-a, --all-pages Export all pages (PDF and HTML only)
-p, --page-index <n> Select a specific 1-based page
-g, --page-range <from>..<to> 1-based inclusive range (PDF only)
-l, --layers <comma-list> Layer indexes to export (applies to all pages)

Embedding

Flag Default Description
-e, --embed-diagram — Embed source XML inside the output (PNG/SVG/PDF)
--embed-svg-images — Embed referenced raster images inside SVG
--embed-svg-fonts <true/false> true Embed fonts inside SVG
-u, --uncompressed — Uncompressed XML / SVG output

SVG-specific

Flag Default Description
--svg-theme <theme> auto dark, light, or auto
--svg-links-target <target> auto auto, new-win, or same-win

HTML-specific (interactive viewer)

Flag Default Description
--html-theme <theme> auto dark, light, auto
--html-zoom <true/false> true Show zoom controls
--html-lightbox <true/false> true Enable lightbox
--html-layers <true/false> true Show layers toolbar
--html-tags <true/false> true Show tags toolbar
--html-fit <true/false> true Responsive fit-to-container
--html-link-target <target> auto auto, blank, self
--html-link-color <color> #0000ff Highlight color for links
--html-edit-link <url> — URL for the Edit button in the viewer

Other

Flag Description
-z, --zoom <n> Scale the application interface itself (used in normal mode too)
--enable-plugins Allow plugin loading during export
-V, --version Print version and quit
-h, --help Print help and quit

Important

When the --output path's extension is one of the recognized format extensions (pdf, svg, png, jpeg, jpg, xml, html), it wins over --format. Use --format when piping output to a folder so each file inherits the chosen format.

4.5 Auto-update behavior

drawio-desktop ships with electron-updater configured against the GitHub provider:

autoUpdater.setFeedURL({
  provider: 'github',
  repo: 'drawio-desktop',
  owner: 'jgraph'
})

On launch, unless dontCheckUpdates is true or updates are disabled, autoUpdater.checkForUpdates() runs once. If a newer release is found:

  • Default mode: a dialog asks Ok / Cancel / Don't Ask Again before downloading.
  • Silent mode (DRAWIO_SILENT_UPDATE=true or --silent-update): downloads + installs on next quit with no prompt (autoDownload: true, autoInstallOnAppQuit: true).
  • Disabled (DRAWIO_DISABLE_UPDATE=true, --disable-update, or running in flatpak): no check at any time.

During the download a progress window from electron-progressbar shows real-time progress (Mac receives no download-progress events from electron-updater, so the bar runs indeterminate until completion). When ready to install, a final dialog offers Install / Later — choosing Later defers application until the next quit.

4.6 Plugin loading

Plugins are JavaScript files placed in the per-user plugins directory beneath the OS app-data folder. They are blocked unless one of these is true:

  • The user passes --enable-plugins on the command line.
  • An IPC installPlugin request from the renderer succeeded (the renderer surfaces this through draw.io's Extras → Plugins menu).

The desktop wrapper enforces that plugin scripts can only load files from the per-user plugins URL or the bundled application URL — anything else is blocked at the session.webRequest.onBeforeRequest layer. This is intentional defense-in-depth; even with plugins enabled, an installed plugin cannot pull in arbitrary file:// resources.

4.7 Relationship to the upstream draw.io web app

drawio-desktop does not implement the diagram editor itself. The drawio/ directory is a git submodule pointing at jgraph/drawio. At build time the submodule's src/main/webapp/ directory is packaged into the desktop app and loaded by the Electron main process via:

const codeDir = path.join(__dirname, '/../../drawio/src/main/webapp');
mainWindow.loadURL(`file://${codeDir}/index.html?...`)

For diagram-editor questions (how to add a shape, connect arrows, use the formula editor, work with libraries) consult the upstream documentation at www.drawio.com and the jgraph/drawio repository. The desktop wrapper only adds: file-system bridges, OS menus, file associations, the CLI export pipeline, the auto-updater, and platform-specific packaging.


5. Common Tasks

Every recipe below is grounded in actual drawio-desktop behavior — no invented flags, no upstream-only features.

5.1 Install and open your first diagram

Goal: verify the install end-to-end with one round trip.

  1. Download and install the appropriate package from Section 2.
  2. Launch the app from your Start menu / Applications / app launcher.
  3. Click + Create New Diagram, pick any template, choose Device as the storage backend, and save as ~/Documents/test.drawio.
  4. Close the app.
  5. Open your file manager and double-click test.drawio.

Verify: the application reopens with test.drawio already loaded and the title bar shows the file name.

5.2 Set drawio-desktop as the default for .drawio and .vsdx

The installer attempts this automatically, but OS preferences sometimes win.

Windows

  1. Right-click any .drawio file → Open with → Choose another app.
  2. Pick draw.io, check Always use this app, click OK.
  3. Repeat for .vsdx if desired.

macOS

  1. Right-click a .drawio file in Finder → Get Info.
  2. Under Open with, select draw.io, click Change All....

Linux (XDG)

xdg-mime default drawio.desktop application/vnd.jgraph.mxfile
xdg-mime default drawio.desktop application/vnd.visio

5.3 Export a diagram from the command line

Goal: generate a 2x-scaled PNG with no background, embedding the source XML so the file remains editable.

drawio --export --format png --scale 2 --transparent --embed-diagram \
       --output my-diagram.png my-diagram.drawio
my-diagram.drawio -> my-diagram.png

Goal: convert every .drawio in a folder tree to a single multi-page PDF each.

drawio --export --recursive --format pdf --all-pages \
       --output ./pdfs ./diagrams

Tip

Combine --check with --output pointing at a folder to avoid overwriting prior runs — the wrapper appends -1, -2, ... to the basename when targets exist.

5.4 Run multiple windows of the same app

drawio-desktop supports unlimited concurrent windows in a single process. Open a second window via:

  • macOS menu: File → New (rendered by the upstream web app).
  • Cross-platform: launch the binary again — the single-instance lock will route the request to the existing process, which spawns a new window.
drawio &
drawio another-diagram.drawio &

Note

Per-window state (zoom level, fullscreen) is not persisted; only the last closed window's size, position, maximized, and fullscreen flags are written to lastWinSize in the electron-store JSON.

5.5 Diagnose a startup or rendering problem with --enable-logging

When the app fails to start or produces blank windows, run from a terminal with --enable-logging and DRAWIO_ENV=dev:

DRAWIO_ENV=dev drawio --enable-logging
in preload C:\Program Files\draw.io\resources\app.asar\src\main
createWindow {}
Window on close 0 ...

The wrapper opens DevTools automatically when DRAWIO_ENV=dev, exposing the renderer console for upstream-app errors. Capture both the terminal output and the DevTools Console for any bug report.

5.6 Deploy via Group Policy on Windows

For enterprise rollouts, distribute the MSI rather than the NSIS exe.

  1. Build/download drawio-29.6.6.msi.
  2. Place the file on a UNC share readable by all target machines.
  3. In Group Policy Management Console → Computer Configuration → Software Settings → Software Installation → New → Package.
  4. Point at the UNC path and select Assigned.
  5. Optionally push DRAWIO_DISABLE_UPDATE=true as a system environment variable via Preferences → Environment so machines do not pull updates from GitHub directly.

Important

The MSI installs per-machine by default — confirm your GPO context (computer vs. user) matches that scope. Pushing via user-context GPO with a per-machine MSI fails silently on lockdown.

5.7 Customize the cache directory

The Electron userData directory holds the electron-store config, plugins, draft files, and Chromium cache. Move it by setting the standard Electron environment variable before launch:

Linux / macOS

export ELECTRON_USER_DATA=/data/drawio
drawio

Windows (PowerShell)

$env:ELECTRON_USER_DATA = "D:\drawio-data"
& "C:\Program Files\draw.io\draw.io.exe"

This is useful for shared workstation builds, encrypted-volume setups, and CI runners.

5.8 Build the desktop wrapper from source for a contribution

git clone --recurse-submodules https://github.com/jgraph/drawio-desktop.git
cd drawio-desktop
nvm install
nvm use
npm install
npm run sync
npm start

After validating your change locally:

# Linux test build (does not publish):
npx electron-builder --config electron-builder-linux-mac.json --publish never

Open a PR against master of jgraph/drawio-desktop. Editor-side fixes should target jgraph/drawio instead — see the upstream contributing guide for details.


6. Troubleshooting

Error: Failed to process page <n>. The file may be corrupt.

Cause: during multi-page PDF combination via @cantoo/pdf-lib, one of the per-page render outputs failed to load. Most often caused by a font missing from the system or a malformed shape on the offending page.

Solution:

  1. Re-run the export with a single page using --page-index <n> to isolate the broken page.
  2. Open the diagram in the GUI, navigate to that page, and look for shapes with broken text or missing image references.
  3. As a workaround, export each page individually with --page-index and merge externally.

Prevention: install all referenced custom fonts on the system (drawio-desktop reads them via fc-list on Linux/mac and PowerShell InstalledFontCollection on Windows).

Error: Invalid file data

Cause: the wrapper's checkFileContent() saw the destination path under the application's own asar/install directory or the file body did not match any recognized header (XML, JSON, PNG, JPEG, WebP, PDF, ZIP, mxfile).

Solution:

  1. Confirm the save target is outside Program Files\draw.io / /Applications/draw.io.app / the snap mountpoint.
  2. Confirm the file extension matches the actual content — saving an arbitrary binary as .drawio will trip the magic-byte check.

Prevention: save into your home directory, Documents folder, or any user-writable location. Never target the install directory; the asar archive is read-only by design.

Error: all saving trials failed

Cause: after writing the file with O_SYNC, the wrapper read it back and the bytes did not match the original. Retried 3 times; all failed. Caused by network drives, certain antivirus realtime scanners, or filesystems that reject O_SYNC.

Solution:

  1. Save to local disk first; copy to network share manually.
  2. Add an antivirus exclusion for the directory.
  3. Check disk health (fsck, chkdsk).

Prevention: keep working diagrams on local SSD. The .bkp companion file (when enableStoreBkp is true) holds the previous version even after this error.

Error: conflict

Cause: the file's modification timestamp on disk changed since drawio-desktop loaded it (someone else saved over it, or git rewrote it). The wrapper refuses to overwrite without explicit confirmation.

Solution: the in-app dialog offers Overwrite / Reload / Save As — pick Save As to preserve both versions or Overwrite if you are sure your version supersedes the other.

Prevention: close the file when stepping away for long periods; re-open after pulling git changes.

Cannot open .drawio.pdf files

Cause: GitHub issue #2338. The OS routes the file to the system PDF handler because .pdf wins over .drawio.pdf in MIME resolution.

Solution: open from inside drawio-desktop via File → Open and select the file manually. The wrapper detects the embedded XML via readPdfXml() and reconstructs the diagram.

Math rendering does not work in exports

Cause: issue #2354 (closed). MathJax is loaded by the upstream web app but the headless export path may finish before MathJax typesets if many equations are present.

Solution: add a --scale 2 or --width 2000 flag to slow the render path and give MathJax time to complete; in extreme cases pass --all-pages (which serializes per-page rendering) instead of single-page.

Linux: app does not start on Ubuntu 24.04+

Cause: issue #2263. Snap's core20 base ships an older glibc/GNOME stack that may conflict with newer Ubuntu kernels and AppArmor policies.

Solution: switch to the .deb or AppImage on Ubuntu 24.04+; both run against the host's libraries.

macOS: cannot print from desktop app

Cause: issue #2317. System print dialog interaction was broken in some Electron 40 builds on macOS Ventura+.

Solution: use File → Export As → PDF with the --all-pages equivalent, then open the PDF in Preview and print from there. Track the issue for an upstream fix.

Dark mode does not match website

Cause: issue #2346. The desktop wrapper does not propagate OS-level dark-mode preference to the upstream web app's theme picker on first launch.

Solution: open Extras → Theme inside the diagram editor and select Dark or Auto explicitly.

Snap Scratchpad errors on launch

Cause: issue #2341 (closed in 29.5.2). The snap's confined data directory was not writable for the Scratchpad initialization on some configurations.

Solution: upgrade to v29.5.2 or later. As a workaround on older versions, switch to .deb or AppImage.

%pagenumber% placeholder does not render in PDF export

Cause: issue #2376. The placeholder substitution is performed by the upstream web app before PDF rendering, and is not re-applied after the per-page combine step in the desktop wrapper's mergePdfs() flow.

Solution: track the upstream fix; as a workaround, hardcode page numbers in the diagram itself before export.

Light/Dark switch needs full app restart to take effect

Cause: issue #2366 (closed). The Electron nativeTheme change event was not wired through the IPC bridge in earlier 29.x versions.

Solution: upgrade to the latest release. As a workaround, File → Quit and relaunch after toggling the theme.

Caution

If the app refuses to launch at all and you suspect a corrupt store, exit fully (check Task Manager / Activity Monitor for stray processes), back up ~/.config/draw.io/config.json (or platform equivalent), then delete it. The next launch regenerates defaults. Note that this also resets your last window size and Google Fonts opt-in.


7. FAQ

Q: What is the difference between drawio-desktop and the website at draw.io?

The website (drawio.com / app.diagrams.net) and drawio-desktop run the same diagram editor — drawio-desktop bundles the upstream jgraph/drawio web app inside an Electron shell. The desktop edition adds full offline operation, OS file associations, native menus on macOS, the command-line export pipeline, and a built-in auto-updater. It removes Google Drive / OneDrive / GitHub cloud storage by default (gapi=0, od=0, gh=0, gl=0, tr=0 in the URL query); files always save to your local disk.

Q: Where is my diagram data stored?

Wherever you save it — drawio-desktop never sends diagram content to a server. The application's own preferences live in the OS standard app-data directory (%APPDATA%\draw.io\ on Windows, ~/Library/Application Support/draw.io/ on macOS, ~/.config/draw.io/ on Linux). Drafts of unsaved files are kept beside the original file as .$<filename>.dtmp and deleted once you save.

Q: Does drawio-desktop work fully offline?

Yes. The default URL query disables every cloud backend (mode: 'device', all storage flags off). The only outbound traffic is: (1) the GitHub auto-updater check on launch (suppressible — see Section 3), and (2) optionally fonts.googleapis.com if you toggle Google Fonts in settings (off by default).

Q: How do I update drawio-desktop?

When a new release lands on the GitHub Releases page, the electron-updater shows a dialog at next launch offering to download. Choose Ok to download in the background; once complete, accept the Install / Later prompt. To skip checks entirely, set DRAWIO_DISABLE_UPDATE=true. AppX (Microsoft Store), snap, and flatpak users get updates from their package manager — auto-update is automatically suppressed in flatpak via the /.flatpak-info detection.

Q: Can I open Visio (.vsdx) files?

Yes — drawio-desktop registers .vsdx as an editable file type and converts them transparently on open via the bundled vsdxImporter.html. CLI export of .vsdx is also supported: drawio --export --format png input.vsdx.

Q: Does it support .dio files (the legacy extension)?

The installer does not register .dio. Open such files via File → Open within the application, or rename them to .drawio.

Q: How do I disable the in-app updater for managed deployments?

Set the environment variable DRAWIO_DISABLE_UPDATE=true system-wide, or pass --disable-update on every launch (e.g. wrap the binary in a shell script). For Microsoft Store users, the AppX channel handles updates automatically; for flatpak users, detection of /.flatpak-info disables the updater automatically.

Q: Can I run drawio-desktop in a CI/headless container?

Yes — pass --export to enable headless mode and --no-sandbox if you cannot run with the chrome sandbox (the wrapper strips --no-sandbox from input file paths so it works as expected). Use xvfb-run drawio --export ... on Linux CI runners that lack a display.

Q: How do I install plugins and where do they go?

Inside the editor, open Extras → Plugins... → Add. The IPC installPlugin action stores the JS file under your userData/plugins/ directory. Plugins are blocked at runtime unless you launch with --enable-plugins. Plugins are not sandboxed beyond the file-protocol whitelist — only install plugins from sources you trust.

Q: My diagrams open at the wrong window size after restart.

Window size, position, maximize and fullscreen are persisted in lastWinSize (electron-store key, default 1200,800,0,0,false,false). If the saved coordinates are off-screen (external monitor disconnected), the wrapper's isWithinDisplayBounds() check resets position to default. To force a reset, edit or delete config.json in your app-data directory.

Q: Can I use drawio-desktop alongside the web app?

Yes — they are isolated. Diagrams created in one open identically in the other (same XML format, same file extensions). You can keep .drawio files in a synced folder (Dropbox, OneDrive, iCloud) and edit them from any device.

Q: How do I report a bug?

Open an issue at github.com/jgraph/drawio-desktop/issues. Include your OS, drawio-desktop version (visible in Help → About or drawio --version), and a minimal .drawio file that reproduces the problem. Diagram-editor bugs (canvas, shapes, formulas) should go to jgraph/drawio instead — they are fixed upstream and rolled into the next desktop release.

Q: Where can I see what changed between versions?

The GitHub Releases page lists each version with release notes. Underlying editor changes come from upstream jgraph/drawio — its CHANGELOG covers shape and feature additions.