IPC Channels Between Electron Renderer and Main Process in Modly: Complete Reference
Modly implements a typed preload bridge where domain-specific API objects exposed to the React renderer route method calls to specific IPC channels handled in the main process via ipcMain.handle and ipcMain.on.
Modly is an Electron-based 3D content creation platform that relies on structured inter-process communication to coordinate between its React frontend and Node.js backend capabilities. Understanding the IPC channels between the Electron renderer and main process in Modly reveals how the application manages window controls, file system operations, model downloads, and Python backend integration. The implementation centers on a strongly-typed preload bridge defined in electron/preload/electron-api.ts that maps high-level JavaScript methods to low-level Electron IPC calls, with corresponding handlers registered in electron/main/ipc-handlers.ts.
The Preload Bridge Architecture
Modly follows Electron's best practices for context isolation by using a preload script to safely expose main process capabilities to the renderer. The architecture consists of three core files:
electron/preload/index.ts– UsescontextBridge.exposeInMainWorldto inject the API intowindow.electronelectron/preload/electron-api.ts– Defines typed methods that wrapipcRenderer.invoke,ipcRenderer.send, andipcRenderer.onelectron/main/ipc-handlers.ts– Registers main process handlers usingipcMain.handle(for request-response) andipcMain.on(for fire-and-forget)
Each domain-specific namespace (window, filesystem, models, extensions) maps to a set of explicit channel strings following the pattern domain:action.
Window Control IPC Channels
Window management uses a mix of fire-and-forget events and state queries:
| Channel | Direction | Handler Type | Source Location |
|---|---|---|---|
window:minimize |
Renderer → Main | ipcMain.on |
electron/main/ipc-handlers.ts |
window:maximize |
Renderer → Main | ipcMain.on |
electron/main/ipc-handlers.ts |
window:close |
Renderer → Main | ipcMain.on |
electron/main/ipc-handlers.ts |
window:isMaximized |
Renderer → Main | ipcMain.handle |
electron/main/ipc-handlers.ts |
window:maximizeChanged |
Main → Renderer | ipcRenderer.on |
electron/preload/electron-api.ts |
The window:isMaximized channel uses invoke to return a boolean promise, while window:maximizeChanged is a main-to-renderer event for state synchronization.
File System and Dialog IPC Channels
The filesystem API provides comprehensive file and directory operations:
fs:selectImage– Opens image picker dialogfs:selectMeshFile– Opens 3D mesh file pickerfs:selectDirectory– Opens directory picker with default pathfs:selectTextFile– Opens text file pickerfs:saveModel– Saves model with dialogfs:savePath– Gets save path dialogfs:readFileBase64– Reads file as base64fs:readScreenshotDataUrl– Reads screenshot datafs:listDir– Lists directory contentsfs:listFiles– Lists files in directoryfs:moveDirectory– Moves directories between locationsfs:deleteDirectory– Removes directories recursively
All filesystem channels use ipcMain.handle for request-response patterns, returning promises that resolve to file paths or data.
Model Management IPC Channels
Model operations handle downloads, exports, and lifecycle management:
| Channel | Pattern | Purpose |
|---|---|---|
model:listDownloaded |
Invoke | List cached models |
model:isDownloaded |
Invoke | Check if specific model exists |
model:download |
Invoke | Start model download |
model:pauseDownload |
Invoke | Pause active download |
model:cancelDownload |
Invoke | Cancel download job |
model:delete |
Invoke | Remove downloaded model |
model:unloadAll |
Invoke | Clear all loaded models |
model:showInFolder |
Invoke | Open model location in system file manager |
model:export |
Invoke | Export model to format |
model:downloadProgress |
Event | Push updates from main to renderer |
The model:downloadProgress channel uses event.sender.send from the main process to stream progress updates to the renderer, which listens via ipcRenderer.on in the preload bridge.
Extension System IPC Channels
Extensions support installation, management, and process execution:
extensions:list– List installed extensionsextensions:installFromGitHub– Install from GitHub URLextensions:installFromLocal– Install from local pathextensions:uninstall– Remove extensionextensions:repair– Repair corrupted extensionextensions:reload– Reload extension without restartextensions:runProcess– Execute extension subprocessextensions:installProgress– Event channel for installation feedback
The extensions:installProgress event provides real-time feedback during GitHub installations, streaming progress from the main process handler to the React UI.
Python Backend Bridge Channels
Modly integrates a Python FastAPI backend using dedicated IPC channels:
| Channel | Direction | Purpose |
|---|---|---|
python:start |
Invoke | Spawn Python process |
python:status |
Invoke | Check if Python backend is running |
python:crashed |
Main → Renderer | Notify of Python process crash |
python:log |
Main → Renderer | Stream Python stdout/stderr logs |
The python:start handler in electron/main/ipc-handlers.ts manages the Python subprocess lifecycle, while python:crashed and python:log push events from main to renderer for monitoring backend health.
System, Settings, and Utility Channels
System Information
system:memory– Returns total, used, and available memory viaipcMain.handle
Application Settings
settings:get– Retrieve configuration valuesettings:set– Persist configuration change
Cache Management
cache:clear– Clear application cache directories
Auto-updater
updater:check– Check for application updatesupdater:quitAndInstall– Apply update and restartupdater:applying– Event indicating update in progressupdater:major-minor-available– Event for version availability
Logging
log:error– Send error logs from renderer to mainlog:getPath– Get log file locationlog:readAll– Read complete log contentslog:listSessions– List available log sessions
First-Run Setup
setup:check– Verify first-run statussetup:saveDataDir– Persist data directory selectionsetup:run– Execute setup workflowsetup:progress– Event for setup step updatessetup:complete– Event signaling setup finishedsetup:error– Event for setup failures
Workspace Management
workspace:listCollections– List project collectionsworkspace:createCollection– Create new collectionworkspace:renameCollection– Rename existing collectionworkspace:deleteCollection– Remove collectionworkspace:listJobs– List processing jobsworkspace:saveJobMeta– Persist job metadataworkspace:deleteJob– Remove job recordworkspace:library:list– List asset libraryworkspace:library:read– Read asset dataworkspace:library:open– Open asset location
Workspace library handlers are registered via registerWorkspaceAssetLibraryIpcHandlers in electron/main/artifact-registry-service.ts.
IPC Communication Patterns
Modly uses three distinct communication patterns:
ipcRenderer.invoke / ipcMain.handle – Used for request-response operations where the renderer needs data or confirmation. Returns a Promise that resolves with the handler's return value. Used by fs:selectImage, model:download, and system:memory.
ipcRenderer.send / ipcMain.on – Used for fire-and-forget messages where no response is needed. Common for window controls like window:minimize and logging via log:error.
ipcRenderer.on / event.sender.send – Used for main-to-renderer events. The main process pushes data to the renderer using event.sender.send(channel, data), while the preload bridge sets up listeners via ipcRenderer.on. Used for progress updates (model:downloadProgress, extensions:installProgress) and backend notifications (python:log).
Practical Usage Examples
Controlling Window State
// Minimize the application window
window.electron.window.minimize();
// Check if window is maximized
const isMaximized = await window.electron.window.isMaximized();
// Listen for maximize state changes
window.electron.window.onMaximizeChange((isMax) => {
console.log(`Window maximized: ${isMax}`);
});
Selecting Files and Directories
// Open image picker dialog
const imagePath = await window.electron.fs.selectImage();
// Select directory with default path
const dirPath = await window.electron.fs.selectDirectory('/home/user/projects');
// Read file as base64 for preview
const base64Data = await window.electron.fs.readFileBase64('/path/to/model.obj');
Managing Model Downloads with Progress
// Start downloading a model
await window.electron.model.download('stable-diffusion-xl');
// Listen for progress updates
window.electron.model.onProgress((data) => {
console.log(`Downloaded ${data.percent}% of ${data.modelId}`);
});
// Pause an active download
await window.electron.model.pauseDownload('stable-diffusion-xl');
Installing Extensions
// List installed extensions
const extensions = await window.electron.extensions.list();
// Install from GitHub with progress tracking
const result = await window.electron.extensions.installFromGitHub(
'https://github.com/username/extension-repo'
);
// Listen to installation progress
window.electron.extensions.onInstallProgress((progress) => {
console.log(`Installation: ${progress.stage} - ${progress.percent}%`);
});
Querying System Resources
// Get memory statistics
const mem = await window.electron.system.memory();
console.log(`Available: ${mem.available}MB / Total: ${mem.total}MB`);
Summary
- Modly uses a typed preload bridge defined in
electron/preload/electron-api.tsthat exposeswindow.electronto the React renderer, providing type-safe access to main process capabilities. - IPC channels follow a
domain:actionnaming convention, with domains includingwindow,fs,model,extensions,python,system, andworkspace. - Three communication patterns are implemented:
invoke/handlefor request-response,send/onfor fire-and-forget, andevent.sender.send/ipcRenderer.onfor main-to-renderer events. - File system operations use
invokeexclusively to return paths and file contents asynchronously. - Progress tracking relies on main-to-renderer events for real-time updates during long-running operations like model downloads and extension installations.
- Python backend integration uses bidirectional IPC to manage subprocess lifecycle and stream logs to the UI.
Frequently Asked Questions
How does Modly secure IPC communications between renderer and main process?
Modly implements context isolation by using a preload script (electron/preload/index.ts) that explicitly exposes only necessary APIs via contextBridge.exposeInMainWorld. The electron-api.ts file defines a typed interface that restricts renderer access to specific whitelisted channels, preventing arbitrary IPC calls and following Electron security best practices.
Can I add custom IPC channels to Modly?
Yes. To add a new channel, define the method in electron/preload/electron-api.ts using ipcRenderer.invoke, send, or on, then register the corresponding handler in electron/main/ipc-handlers.ts using ipcMain.handle or ipcMain.on. Ensure channel names follow the existing domain:action convention and update the TypeScript interfaces to maintain type safety across the bridge.
Why do some channels use invoke while others use send?
invoke is used when the renderer requires a response or confirmation from the main process, such as retrieving file paths (fs:selectImage) or checking system memory (system:memory). send is used for fire-and-forget operations where no return value is needed, such as window minimization (window:minimize) or logging errors (log:error). Event channels like model:downloadProgress use ipcRenderer.on to receive push notifications from the main process.
Where are the IPC handlers for workspace library operations defined?
While most IPC handlers reside in electron/main/ipc-handlers.ts, the workspace library-specific channels (workspace:library:list, workspace:library:read, workspace:library:open) are registered through the registerWorkspaceAssetLibraryIpcHandlers function in electron/main/artifact-registry-service.ts, demonstrating how Modly modularizes IPC registration across different service files.
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 →