How Modly's Settings Store Persists and Synchronizes Configuration
Modly persists configuration to a JSON file in Electron's user data directory and synchronizes state across processes using IPC handlers, ensuring all renderer windows reflect changes immediately.
The lightningpixel/modly repository implements a lightweight, file-backed configuration system that balances durability with real-time consistency. Unlike database-heavy solutions, Modly uses a simple JSON store combined with Electron's inter-process communication (IPC) to keep settings synchronized between the main process and multiple renderer windows.
JSON File Persistence Architecture
All user-specific configuration resides in a settings.json file located within the Electron userData path (retrieved via app.getPath('userData')). The settings store (electron/main/settings-store.ts) serves as the single source of truth for directory paths and authentication tokens.
Default Configuration with Migration
The getSettings(userData) function constructs default locations for models, workspaces, workflows, extensions, and dependencies. When settings.json exists, the function reads and merges it with these defaults, automatically migrating legacy keys such as the deprecated outputsDir property. This ensures backward compatibility while always returning a complete AppSettings object.
Atomic Write Operations
Updates occur through setSettings(userData, patch), which accepts a Partial<AppSettings> object. The function first retrieves the current configuration via getSettings, applies the patch, and writes the result back to disk using writeFileSync with two-space indentation. Because the write is synchronous and atomic, any subsequent read operation—whether from the same process or a newly launched instance—immediately sees the latest values.
Cross-Process Synchronization via IPC
Renderer processes never access the filesystem directly. Instead, they communicate with the main process through IPC handlers defined in electron/main/ipc-handlers.ts.
IPC Handler Implementation
The main process exposes two critical channels:
getSettings– Returns the currentAppSettingsobject by calling the store'sgetSettingsfunction.setSettings– Receives a partial settings object from the renderer, invokessetSettings(userData, patch)to persist the change, and returns the updated configuration.
Real-Time Broadcast Mechanism
When setSettings is invoked, the main process writes the JSON file and immediately broadcasts the new configuration back to the requesting renderer. This broadcast extends to all open windows, ensuring that path changes, token updates, and directory relocations remain consistent across the entire application without requiring manual refreshes.
Practical Usage Examples
Reading Configuration from the Renderer
To retrieve the current settings from a React component or other renderer context:
import { ipcRenderer } from 'electron'
async function loadSettings() {
const settings = await ipcRenderer.invoke('getSettings')
console.log('Current Modly settings:', settings)
}
loadSettings()
Updating Values (e.g., Hugging Face Token)
To modify a specific setting such as the Hugging Face authentication token:
import { ipcRenderer } from 'electron'
async function updateToken(newToken: string) {
const updated = await ipcRenderer.invoke('setSettings', { hfToken: newToken })
console.log('Settings after update:', updated)
}
updateToken('hf_XXXXXXXXXXXXXXXX')
Behind the Scenes: Main Process Handlers
The IPC implementation in electron/main/ipc-handlers.ts bridges renderer requests to the settings store:
import { ipcMain, app } from 'electron'
import { getSettings, setSettings } from './settings-store'
ipcMain.handle('getSettings', (event) => {
const userData = app.getPath('userData')
return getSettings(userData)
})
ipcMain.handle('setSettings', (event, patch) => {
const userData = app.getPath('userData')
return setSettings(userData, patch)
})
Summary
- File Location: Modly stores configuration in
settings.jsoninside Electron'suserDatadirectory, retrieved viaapp.getPath('userData'). - Store Implementation: The
electron/main/settings-store.tsfile providesgetSettingsandsetSettingsfunctions that handle defaults, legacy migrations, and atomic file writes. - Synchronization: IPC handlers in
electron/main/ipc-handlers.tsexpose these functions to renderers, broadcasting updates to all windows immediately after persistence. - Durability: Using
writeFileSyncensures data survives application restarts, while the merge-based approach preserves settings across version updates.
Frequently Asked Questions
Where is the Modly settings.json file located on disk?
The file resides in the Electron user data directory, which varies by operating system. On Windows, this is typically %APPDATA%/Modly/settings.json; on macOS, ~/Library/Application Support/Modly/settings.json; and on Linux, ~/.config/Modly/settings.json. The exact path is determined at runtime by app.getPath('userData').
How does Modly keep multiple windows synchronized when settings change?
When any renderer invokes setSettings via IPC, the main process writes the updated configuration to disk and immediately returns the new state to the caller. The architecture ensures that subsequent getSettings calls from other windows retrieve the latest values, maintaining consistency without requiring a separate state management library.
What happens if the settings.json file becomes corrupted?
The getSettings function in electron/main/settings-store.ts validates the existing file against default configuration objects. If parsing fails or keys are missing, the function merges the corrupted data with sensible defaults, effectively repairing the configuration on the next read operation without losing user data.
Can two processes write to the settings simultaneously?
Because Modly uses writeFileSync for atomic writes and follows a single-writer pattern (only the main process writes to disk), simultaneous write conflicts are prevented. Renderer processes always route updates through the main process's IPC handlers, serializing access to the configuration file and eliminating race conditions.
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 →