Windows and the renderer
Understand the process model
Separate main-process responsibilities from renderer work before adding application behavior.
An Electron app is not one JavaScript environment.
The main process is the application coordinator. It owns lifecycle, creates windows, calls native APIs, and has Node.js access. If it blocks or crashes, the whole application is affected.
Each BrowserWindow loads web content in a renderer process. The renderer owns DOM events, interface state, and drawing. Treat its input as you would treat input from a web page.
The preload script runs in the renderer process before page code. With context isolation, it has a separate JavaScript world and can expose a narrow API through contextBridge.
Desktop Notes will follow this ownership map:
flowchart LR
accTitle: Electron process ownership
accDescr: The renderer calls a narrow preload API, which sends validated actions to the main process. The main process returns note data and native menu events through the same bridge.
Renderer -->|"saveNotes(notes)<br/>exportNotes()"| Preload["Preload bridge"]
Preload -->|"Validated IPC"| Main["Main process"]
Main -->|"Read notes<br/>native menu event"| Preload
Preload -->|"loadNotes()<br/>onNewNote(callback)"| Renderer
The arrow is a trust boundary. Values are copied across IPC; the processes do not share ordinary objects or a call stack.
Keep CPU-heavy work out of the main process too. For this small app, file operations are asynchronous and short. Larger computation can move to a utility process or worker rather than freezing every window.
Before implementing a feature, write down which process owns it and why. If the answer is “the renderer because it was convenient,” inspect whether the feature touches the computer or private data.
Lesson completed