Here are my highlights of Deep dive into Electron’s main and renderer processes by Cameron Nokes.
[Each of these processes is] an operative system level process, or as Wikipedia puts it "an instance of a computer program that is being execute."
[…] Each of these processes run concurrently to each other. […] [M]emory and resources are isolated from each other. […] The two processes don't share memory or state.
Why multiple processes?
Chromium runs each tab in a separate process so that if one tab runs into a fatal error, it doesn't bring down the entire application. […] "Chromium is built like an operative system, using multiple OS processes to isolate web sites from each other and from the browser itself."
The render process is responsible for running the user-interface of your app, or in other words, a web page which is an instance of webContents. All DOM APIs, Node.js APIs, and a subset of Electron APIs are available in the renderer. […] [O]ne or more webContents can live in a single window […] because a single window can host multiple webviews and each webview is its own webContents instance and renderer process.
See this Venn diagram of Electron (provided by the source).
How do I communicate between processes?
Electron uses interprocess communication (IPC) to communicate between processes—same as Chromium. IPC is sort of like using
postMessagebetween a web page and an iframe or webWorker […] you send a message with a channel name and some arbitrary information. IPC can work between renderers and the main process in both directions. IPC is asynchronous by default but also has synchronous APIs (like fs in Node.js).
Electron also gives you the remote module, which allows you to, for example, use a main process module like
Menuas if it were available in the renderer. No manual IPC calls [are] necessary, but what's really going on behind the scenes is that you are issuing commands to the main process via synchronous IPC calls. (These can be debugged with devtron.)
Can I make something work in both the main and renderer?
Yes, because main process APIs can be accessed through remote, you can do something like this:
const electron = require('electron'); const Menu = electron.Menu || electron.remote.Menu; //now you can use it seamlessly in either main or renderer console.log(Menu);