IPC Communication Between Processes
Use ipcMain and ipcRenderer to send messages between the main process and React renderer securely.
IPC Communication Between Processes is a free React Academy lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the React Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
ipcMain.handle: Request-Response Pattern
ipcMain.handle registers a named channel in the main process that responds to requests from the renderer. It accepts an async handler function and its return value becomes the resolved value of the Promise in the renderer, making it ideal for operations like reading files or querying a database.
ipcRenderer.invoke: Calling the Main Process
ipcRenderer.invoke sends a message on a named channel and returns a Promise that resolves with the main process handler's return value. This creates a clean async request-response pattern that works naturally with async/await in both the preload script and React components.
Exposing invoke via contextBridge
The preload script wraps ipcRenderer.invoke calls and exposes them through contextBridge. For example: api.readFile = (filePath) => ipcRenderer.invoke('read-file', filePath). The renderer calls window.api.readFile(path) and gets a Promise back — clean and sandboxed.
Why the Renderer Never Imports ipcRenderer
With contextIsolation enabled, the renderer process cannot require('electron') or import ipcRenderer directly — the module is simply unavailable. All IPC must go through the preload script's contextBridge exposure. This is intentional: it prevents XSS attacks from gaining IPC access.
ipcMain.on: Fire-and-Forget Messages
ipcMain.on listens for one-way messages sent with ipcRenderer.send (not invoke). There is no automatic response channel — this pattern suits notifications or commands where the renderer doesn't need a reply, such as logging events or triggering a native notification.
Pushing Data from Main to Renderer
The main process can push data to the renderer using webContents.send('channel-name', data). This is the primary way the main process initiates communication — for example, forwarding file system watch events or native menu actions to the React UI.
ipcRenderer.on: Listening in the Preload
In the preload script, ipcRenderer.on('update', callback) registers a listener for push messages from the main process. The callback receives the event and any data the main process sent, which you then pass through to the renderer via the contextBridge-exposed function.
Exposing Event Listeners via contextBridge
A clean pattern for push events is: api.onUpdate = (callback) => ipcRenderer.on('update', (_event, data) => callback(data)). React components subscribe by calling window.api.onUpdate(setData), and the callback updates state when the main process pushes new data.
Cleanup: Removing Event Listeners
Every ipcRenderer.on listener must be removed when no longer needed to prevent memory leaks and duplicate callbacks. The preload function should return a cleanup function (e.g., () => ipcRenderer.removeListener('update', callback)) that React calls from the useEffect cleanup return.
Security: Validating IPC Inputs
IPC inputs from the renderer should be treated as untrusted data in the main process handler. Always validate file paths (prevent path traversal attacks), sanitize query parameters, and check that the sender's origin is expected. Never expose a generic eval or exec IPC channel.
Structuring IPC Channels
As your app grows, organize IPC channels with namespacing conventions: 'fs:read-file', 'db:query', 'window:minimize'. Keep channel names in a shared constants file imported by both main.js and the preload script to prevent typos and make refactoring safer.
ipcMain.handle Return Value
What happens to the value returned by an ipcMain.handle handler?
Lesson Recap
IPC is the backbone of Electron communication. ipcMain.handle and ipcRenderer.invoke form a Promise-based request-response pair for renderer-initiated operations. For main-initiated pushes, webContents.send and ipcRenderer.on work together. All IPC in the renderer must be routed through the preload's contextBridge, and listeners should always be cleaned up to prevent memory leaks.
Frequently asked questions
Is the “IPC Communication Between Processes” lesson free?
Yes — the full text of “IPC Communication Between Processes” is free to read here on the web, and the React Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the React Academy course, upgrade to CoddyKit PRO.
What will I learn in “IPC Communication Between Processes”?
Use ipcMain and ipcRenderer to send messages between the main process and React renderer securely. You practise React Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start React Academy?
No prior experience is required. React Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “IPC Communication Between Processes” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this React Academy lesson?
Yes. Every React Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Electron Architecture: Main and Renderer Processes
- Setting Up React with Electron
- IPC Communication Between Processes
- Packaging and Distribution for Desktop Platforms