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."
Main process
[I]s responsible for creating and managing BrowserWindow instances and various application events. It can also register global shortcuts, creative native menus and dialogs, respond to auto-update events, and more. Your app's entry point will point to a JavaScript file that will be executed in the main process. A subset of Electron APIs are available in the main process, as well as all Node.js modules. The docs state: “The basic rule is: if a module is GUI or low-level system related, then it should be only available in the main process.” (Note that GUI here means native GUI, not HTML based UI rendered by Chromium). This is to avoid potential memory leak problems.
Renderer process
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
postMessage
between 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
Menu
as 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);