Skip to content
Back to blog

Electron

An overview of Electron's multi-process architecture, the integration of the Chromium and Node.js event loops, inter-process communication, data sharing, and native capabilities.

Updated

Electron Architecture

Multi-Process Architecture Diagram

Electron's underlying architecture is based on Chromium; the complete Chromium architecture can be found in the official documentation.

A simplified version of the architecture diagram is as follows:

The Electron main process connects to two renderer processes via IPC; each process has different APIs and runtimes.

Event Loop

Electron is based on Chromium and NodeJS, but their event loops and lifecycles are different:

  • Chromium: message pump
  • NodeJS: libuv

The process of integrating Chromium with NodeJS is shown below:

Node event notifications reach the Electron main thread, where the Chromium MessageLoop handles libuv events.

The basic flow is:

  • Start a separate safe thread
  • The thread polls backend_fd to get the latest libuv events
  • Add the events to the Chromium event loop

Inter-Process Communication

render to main

There are two ways for render to notify main: the event-callback style and the Promise style; the Promise style is only supported in Electron 7 and above.

  • render uses ipcRenderer.send(channel, ...args) and main uses ipcMain.on(channel, handler); used when render does not need to wait for main to return
  • render uses ipcRenderer.invoke(channel, ...args) and main uses ipcMain.handle(channel, handler); render can wait for main's response to come back

main to render

For main to notify render, you first need to get the child process's window object, then send the message through window.webContents.send(channel, ...args).

render can receive the event through ipcRenderer.on(channel, ...args).

main does not provide an invoke-equivalent API when sending messages. Generally speaking, main should not continuously wait for render's result; if needed, it can also be implemented through simulation.

render-to-render communication

Electron 5 and above provide ipcRenderer.sendTo, which can send messages from render to render.

In Electron 27, ipcRenderer.sendTo was officially deprecated, replaced by render-to-render communication through MessageChannel.

Before that, messages needed to be forwarded through main.

Data Sharing

Since Electron is also based on Chromium, it also supports localStorage, sessionStorage, indexedDB, and similar capabilities, which can be used for data sharing.

In addition, Electron provides remote for data sharing; underneath it is a synchronous ipc communication, which can easily cause jank and similar issues.

In Electron 9 the remote feature was disabled by default, and it was officially removed in Electron 12, moving to maintenance as a separate plugin.

Native Capabilities

Because Electron runs on the desktop, it can provide capabilities unique to desktop applications, such as GUI and device access.

Meanwhile, because the underlying layer uses NodeJS, richer operations can be implemented through NodeJS's native APIs and addons, reusing existing NodeJS modules.

Desktop capabilities listed by Node.js, Electron Native API, and operating system.