Electron
About Electron
A desktop application traditionally meant learning the native toolkit of each platform you wanted to support, which is three different languages, three interface systems and three sets of conventions. Electron replaced that with one answer, which is to write the interface as a web page and ship a browser to display it.
Electron contains two things. A browser engine that renders the interface, and a server-side JavaScript runtime that reaches the parts of the system a web page cannot touch. Between them, HTML and CSS become a window on the desktop with genuine access to the machine.
That approach produced a large share of the desktop software people now use daily, and it produced the loudest criticism in modern software development. Both deserve stating properly.
Its origin explains the design, since Atom was the editor this framework was built to make possible before the framework became the more significant of the two.
Two kinds of process, and why the split exists
An Electron application runs one main process and one or more renderer processes. The main process owns the application lifecycle, creates windows and holds the privileges. Each renderer draws one window and runs the interface code.
The separation is deliberate rather than architectural tidiness. Interface code is the code most likely to end up handling content from somewhere else, and giving that code direct access to the file system would be an obvious mistake. Renderers therefore ask the main process to do privileged things through a defined channel rather than doing them directly.
Getting that boundary right is most of building a sound application on this framework, and getting it wrong is how the security problems in this ecosystem have historically happened.
What it reaches that a web page cannot
The Electron list is what turns a page into an application. The file system, native menus in the correct place for each platform, a tray icon, system notifications, native file dialogs, global keyboard shortcuts that work when the window is not focused, registration as the handler for a protocol or a file type, automatic updating and crash reporting.
None of those are available to a website, and all of them are what users expect from something installed on their machine. An application without native menus and file dialogs feels wrong immediately even when nobody can articulate why.
Discord is a familiar example, using exactly that set to behave like a desktop application rather than a browser tab, including the global shortcuts and the tray presence.
The memory criticism, stated fairly
Every Electron application ships its own copy of the browser engine. Run four of them and four browser engines are running, each holding its own memory, which is why a chat application can occupy several hundred megabytes doing very little.
That criticism is correct and it is not the whole picture. The alternative is not a lighter application, it is three separate native applications written by teams who each know a different platform, maintained separately, diverging in features and shipping at different speeds. For most organisations that is not a trade they can afford to make.
Somebody comparing a text editor built this way against a native editor that starts instantly and uses a fraction of the memory is comparing correctly, and also comparing a program written for one platform against one running on all of them from a single codebase.
The honest position is that the criticism is about resource use and the counter-argument is about economics, and both are true simultaneously.
The security model
Because Electron renderers execute web content, an application can end up running code it did not write. That risk is real and the framework has responded to it structurally.
Context isolation separates the interface code from the internals it might otherwise reach, sandboxing restricts what a renderer may do, and the communication channel between processes is explicit rather than ambient. Those protections are now enabled by default, which was not always the case and is the reason older applications built this way carry more risk than current ones.
None of it protects an application whose author deliberately disabled the protections, which happens, usually because a shortcut was easier than the correct approach. That is a property of the application rather than the framework, and the framework’s defaults are now the correct ones.
Shipping the result
Electron packaging turns the application into something installable, producing the appropriate installer format for each platform along with signing so the operating system does not warn users away from it.
Automatic updating is built into the framework rather than being somebody’s afterthought, which matters more than it sounds. An application that updates itself quietly is an application whose security fixes actually reach the people running it.
Crash reporting collects what happened when something failed, which is the difference between a bug report saying it stopped working and one containing the information needed to fix it. Slack is among the applications built this way, and the update and reporting machinery is a large part of why an application that size can be maintained across platforms at all.
Conclusion
Electron made a specific trade that a great deal of the software industry decided was worth it. One codebase across every desktop platform, written by people who already knew the technologies, shipping quickly and updating itself, in exchange for each application carrying its own browser engine.
Judge it by that trade rather than by the memory figure alone. The criticism is accurate and the alternative costs considerably more, which is why the applications built this way are the ones that exist rather than the lighter native versions that were never written. For anybody building on it, the boundary between the main process and the interface is where the real work of doing it properly lies.
Pros & Cons
- One codebase produces applications for every major desktop platform
- Interfaces are built with the technologies an enormous number of programmers already know
- Reaches the file system, native menus, tray, notifications and global shortcuts
- Process separation keeps interface code away from system privileges by design
- Context isolation and sandboxing are enabled by default rather than optional
- Packaging, signing, automatic updating and crash reporting all included
- The ecosystem is large, so most problems have been solved by somebody already
- Every application bundles its own browser engine, so several running means several copies
- Memory use and disk footprint are far larger than a native equivalent
- Startup is slower than a native application of the same complexity
- An author who disables the protections produces a measurably riskier application
- Interfaces can feel subtly unlike the platform they are running on
Frequently asked questions
A framework bundling a browser engine and a JavaScript runtime, so an application interface is written as a web page while still reaching the file system, native menus and everything else a desktop program needs.
Because each one carries its own copy of the browser engine rather than sharing one. Four such applications mean four engines running, which is the standard and accurate criticism of the approach.
The main process owns the application lifecycle and the privileges, while renderers draw windows and run interface code. Renderers ask the main process to perform privileged operations rather than performing them directly, which keeps interface code away from system access.
Through context isolation and sandboxing, enabled by default, which separate interface code from the internals it might otherwise reach. Applications that switch those off are where the real problems occur.
A considerable number of the desktop applications people use daily, including messaging clients and code editors. The approach is common enough that recognising it by the memory usage has become a running joke among technical users.