Preload and IPC
Why the renderer is isolated
Understand why Node.js stays out of the page and why a preload bridge exposes only deliberate desktop capabilities.
8 minute lesson
Browser JavaScript normally cannot read arbitrary files or launch local programs. That limit contains the damage from an injected script or dependency bug.
Electron adds desktop power, but page code should not receive all of it. Keep three protections in place:
nodeIntegration: falseremoves direct Node.js access from the pagecontextIsolation: truegives preload and page code separate globalssandbox: truerestricts the renderer process
The preload script is more privileged than the page, even in a sandboxed renderer. Treat every value it exposes as a permanent public API.
This bridge is too powerful:
contextBridge.exposeInMainWorld('electron', {
send: (channel, value) => ipcRenderer.send(channel, value)
})
Any renderer code can choose any channel. Future main-process handlers can accidentally become reachable without changing the bridge.
Expose one method per intention instead:
contextBridge.exposeInMainWorld('notesAPI', {
saveNotes: notes => ipcRenderer.invoke('notes:save', notes)
})
This still does not make notes trusted. The main process must validate the sender and value before writing.
Imagine an injected script running in the renderer. List everything it could do through window.notesAPI. That list should be short, understandable, and no more powerful than the interface needs.
Lesson completed