How to Configure Persistent Settings Using electron-store in draw.io Desktop
draw.io Desktop persists user preferences—including window geometry, spell-check toggles, and update flags—using electron-store, which automatically manages a JSON configuration file in the application's user data directory.
The jgraph/drawio-desktop repository implements a robust configuration layer built on electron-store to maintain state across application sessions. According to the source code in src/main/electron.js, the implementation wraps the store API with defensive programming patterns to ensure the diagramming application remains stable even when file system permissions prevent configuration access.
Initializing electron-store in the Main Process
The store is instantiated once during application startup inside the main process. The initialization uses a try-catch block to prevent startup failures if the configuration directory is inaccessible.
In src/main/electron.js at line 14, the store is created as follows:
import Store from 'electron-store';
// ...
let store;
try {
store = new Store();
} catch (e) {
console.error('Failed to initialize electron-store:', e);
store = null;
}
This pattern ensures that the store variable is either a functional electron-store instance or null, allowing subsequent code to fail gracefully rather than crashing the application.
Reading Persistent Settings with Default Fallbacks
Throughout the codebase, settings are retrieved using a null-safe pattern that supplies sensible defaults when keys are missing or the store is unavailable. The standard idiom checks store != null before calling store.get('key').
Spell-check configuration (lines 82-84) demonstrates reading a boolean with platform-specific defaults:
let enableSpellCheck = store != null ? store.get('enableSpellCheck') : false;
enableSpellCheck = enableSpellCheck != null ? enableSpellCheck : isMac;
Window geometry restoration (line 161) uses string parsing with comma-separated fallback values:
let lastWinSizeStr = (store && store.get('lastWinSize')) || '1200,800,0,0,false,false';
Other flags like enableStoreBkp and isGoogleFontsEnabled follow this same defensive retrieval pattern, ensuring the application launches with functional defaults even on first run or when the store is uninitialized.
Persisting Changes with store.set()
When users modify preferences or when the application state changes, values are written using store.set(key, value). This synchronous API immediately updates the JSON file in the user's application data directory (~/Library/Application Support/draw.io on macOS or %APPDATA%\draw.io on Windows).
Window size preservation (lines 251-257) serializes geometry state into a comma-delimited string:
store.set('lastWinSize',
size[0] + ',' + size[1] + ',' + pos[0] + ',' + pos[1] + ',' +
win.isMaximized() + ',' + win.isFullScreen());
User preference toggles are persisted at specific interaction points:
- Line 992:
store.set('enableSpellCheck', enableSpellCheck); - Line 1005:
store.set('enableStoreBkp', enableStoreBkp); - Line 1018:
store.set('isGoogleFontsEnabled', isGoogleFontsEnabled);
Auto-update control uses the dontCheckUpdates key, written when users disable update prompts (line 1433) and cleared when re-enabled (line 1049):
store.set('dontCheckUpdates', true); // Disabling updates
store.set('dontCheckUpdates', false); // Re-enabling updates
Accessing Settings from the Renderer Process
While electron-store operates in the main process, draw.io Desktop exposes configuration APIs to the renderer via IPC bridges defined in src/main/electron-preload.js. This allows the frontend to trigger persistent changes without direct store access.
Main process handler (in electron.js):
ipcMain.on('set-preference', (e, { key, value }) => {
if (store) store.set(key, value);
});
Preload script exposure (electron-preload.js):
const { ipcRenderer, contextBridge } = require('electron');
contextBridge.exposeInMainWorld('electronAPI', {
setPreference: (key, value) => ipcRenderer.send('set-preference', { key, value })
});
Renderer usage:
window.electronAPI.setPreference('enableSpellCheck', true);
This architecture maintains security boundaries while allowing the React-based frontend to persist user choices.
Summary
- Initialization: Create the store in
src/main/electron.jswith try-catch error handling to setstoreto either an instance ornull. - Defensive Reading: Always check
store != nullbefore callingstore.get(), providing explicit default values for missing keys. - Synchronous Writing: Use
store.set(key, value)to immediately persist changes to the JSON configuration file in the user's application data directory. - Cross-Process Access: Expose configuration methods to the renderer via
contextBridgeandipcMainrather than accessing electron-store directly from the frontend. - Storage Location: Configuration is automatically managed in platform-specific paths—macOS uses
~/Library/Application Support/draw.iowhile Windows uses%APPDATA%\draw.io.
Frequently Asked Questions
Where does draw.io Desktop store the electron-store configuration file?
electron-store automatically writes to the application's user data directory. On macOS, this is ~/Library/Application Support/draw.io/config.json, while on Windows it resides in %APPDATA%\draw.io\config.json. The library handles path resolution and file creation automatically without requiring explicit filesystem code.
What happens if electron-store fails to initialize?
If initialization fails due to permissions or corruption, the catch block in src/main/electron.js sets store = null. The application continues running using hardcoded defaults for all settings. Every subsequent read and write operation checks store != null before accessing the API, ensuring the diagram editor remains functional even when persistence is unavailable.
How do I add a new persistent setting to draw.io Desktop?
First, define a default value using the null-safe retrieval pattern: const mySetting = store != null ? store.get('myKey') : defaultValue;. Then persist changes using store.set('myKey', newValue) when the user modifies the setting. If the setting must be controlled from the renderer, add an IPC handler in the main process and expose the method through the preload script as shown in the cross-process access pattern.
Can I access electron-store directly from the renderer process?
No, direct access is blocked by Electron's context isolation for security reasons. draw.io Desktop uses the preload script (src/main/electron-preload.js) to expose specific, controlled methods via contextBridge. The renderer calls these exposed methods, which use ipcRenderer to send messages to the main process where electron-store actually executes the read or write operations.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →