- 👤 Andrés Cruz

🇪🇸 En español

Ver Listado »

The Ultimate Guide to Electron.js: Create Cross-Platform Desktop Applications with Web Technologies

Electron.js has revolutionized the way we think about desktop applications. By allowing developers to build native programs for Windows, macOS, and Linux using only web technologies (HTML, CSS, and JavaScript), it has democratized cross-platform software creation.

This SUPER post is your definitive resource for getting started, designed to take you from the first steps in Electron to building production-ready applications, covering its fundamental concepts and advanced techniques.

Throughout this document, we will distill the knowledge from our most detailed publications on Electron.js. We will cover installation, window creation, inter-process communication, menu management, debugging, and preparation for distribution. 

Our goal is to provide you with a complete roadmap, filled with code snippets, technical explanations, and practical advice, all with the direct and professional tone that characterizes DesarrolloLibre. Get ready to master Electron.js and expand your web development skills to the world of desktop software.

What is Electron?

Electron is an open-source framework for creating cross-platform desktop applications with web technology; that is: HTML, CSS, and JavaScript. Being integrated as a Node module, we can use all of Node's power for our application; components like databases, Rest APIs, CSS frameworks like Bootstrap or Tailwind, and much more, can be integrated into an Electron application.

It is developed and maintained by GitHub and is the graphical framework behind many major open-source projects today such as Atom, Visual Studio Code, Discord, and Whatsapp.

About Electron

Electron's secret is a combination of two processes: the main process and the renderer process.

  1. The first process, which is the main process, is a Node.js process; this process has access to several Electron.js APIs with which we can communicate with the Operating System.
  2. The second process is the renderer process which uses Chromium; this process has an included Node.js and, with it, access to all of its modules.

Chromium, an open-source project behind the Google Chrome browser, and Node.js, a JavaScript runtime based on Chrome's V8 JavaScript engine.

Electron uses Chromium for the frontend and Node.js for the backend. It provides an extensive set of interfaces or APIs with which to access the operating system, allowing us developers to create cross-platform applications that share the same HTML, CSS, and JavaScript code.

Ultimately, you can view the main process as the server, where we have database connections and operating system access, and the renderer process as the client side, where we build the screen for the end-user to interact with; it's important to note that we can communicate both processes directly.

Electron.js is a web framework with which we can create cross-platform desktop applications (non-native) that run on Windows, macOS, and Linux, with a web wrapper using JavaScript, HTML, and CSS and without needing experience in native development.

Electron.js works through two processes:

  1. The main process, which is a Node process, the application itself, in which we have access to some modules provided by the Electron.js API (some that serve to communicate with the Operating System, for example, creating cross-platform menus).
  2. The renderer process, which is a Chromium process that additionally has an embedded Node.js and access to all of its modules; from this process, we can develop the application's UI.

Chapter 1: First Steps and Initial Configuration in Electron.js

Electron.js is a web framework that allows us to create cross-platform desktop applications (non-native) that run on Windows, macOS, and Linux, with a web wrapper using JavaScript, HTML, and CSS and without needing experience in native development. It is a formidable solution for building a GUI around applications that would otherwise be limited to a command-line interface (CLI). Its value lies in uniting the browser environment (Chromium) with Node.js, allowing access to operating system resources in a way that traditional web applications cannot.

1.1. What is Electron.js and its Potential?

Electron is not a complicated framework; it is a simple runtime. Similar to how you use Node from the command line, you can run Electron applications using the Electron command line tool. You don't need to learn complex conventions to get started and you have complete freedom to structure your application however you see fit. This framework allows us to create web applications and then give them native desktop application functionality such as the use of menus, exporting and installing on Windows, Linux, and Mac Operating Systems, keyboard shortcuts, creation of windows and dialogs, and drag and drop of files.

The introductory material for this course is part of our complete course on Electron.js, where we address the core of Electron.js starting from the installation of basic components (Node and Visual Studio Code) to the creation of applications with native JavaScript and integration with Vue CLI. It is important to mention that no prior knowledge in Node is necessary, only basic knowledge of programming and HTML, CSS, and JavaScript. This course is aimed at anyone who wants to learn about the framework and create their first desktop applications, improve their skills, and grow as a developer.

1.2. Creating Your First Window: The "Hello World" in Electron

To create your first application with Electron.js, the process is simple. First, create a folder for your project and initialize it with NPM:

$ mkdir my-electron-app
$ cd my-electron-app
$ npm init -y

Then, install Electron as a development dependency:

$ npm i -D electron@latest

In the index.js file (your main process), you define the window creation:

const { app, BrowserWindow } = require('electron')

function createWindow() {
    let win = new BrowserWindow({
        width: 800,
        height: 600,
        webPreferences: {
            nodeIntegration: true, // Esto es crucial para este capítulo
            contextIsolation: false // Revisa las implicaciones de seguridad
        }
    })
    win.loadFile("index.html")
}

app.whenReady().then(createWindow)

And your index.html (your renderer process) will be a simple web page:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Mi primera App Electron</title>
</head>
<body>
    <h1>Hello Electron</h1>
</body>
</html>

Finally, add a start script in your package.json and run npm run start:

"scripts": { "start": "electron ." }

This process is the foundation of any Electron application and is explored in depth in "Creating Your First Application with Electron" and "First steps with Electron.js" which is a paid resource.

1.3. Enabling Node.js Integration

Node.js integration in Electron allows your renderer process (the web page) to access Node.js resources, and therefore, the Electron API. This is fundamental to giving your web application desktop functionalities. By default, this integration is disabled for security reasons in the latest versions of Electron. To enable it, you must configure it in webPreferences when creating your window:

let win = new BrowserWindow({
   // ...
   webPreferences:{
       nodeIntegration: true,
       contextIsolation: false 
   }
})

It is important to note that nodeIntegration allows full access to Node.js APIs in the renderer process, which is very powerful but can be a security risk if you load content from untrusted sources. contextIsolation helps mitigate this, but disabling it (false) gives you greater flexibility for older scripts. For more details, consult "Enable Node integration in Electron.js".

Chapter 2: Interaction and User Experience in Electron.js

Desktop applications not only display content; they interact with the user and the operating system in complex ways. Electron.js provides robust mechanisms for managing events, communicating processes, and creating rich, tailored user interfaces.

2.1. Introduction to Events in Electron.js

In Electron, events are notifications that are triggered at different times in the application's lifecycle, either in the Main Process or in the Renderer Processes. Understanding and controlling these events is fundamental for the dynamic behavior of your application.

  • Events of the app Module (Main Process): Control the overall application lifecycle, such as ready (when Electron has finished starting up), window-all-closed (when all windows have been closed), or activate (especially useful on macOS to reactivate the application without creating a new window if one already exists).
  • Events of webContents (Renderer Process): Related to the content of a window, such as did-finish-load (when the web page is fully loaded) or dom-ready (when the DOM is ready).

Events are like "sensors" that allow you to react to what happens. For example, you can use:

app.on('window-all-closed', () => { app.quit() }) 

To close the application when all windows are closed. Event management is key to a reactive application and is explained in depth in "Introduction to Events in Electron.js".

2.2. Inter-Process Communication (IPC): Main and Renderer

A distinctive feature of Electron is its dual-process architecture: the Main Process, which executes Node.js code and manages the windows, and the Renderer Processes, which are Chromium instances and display the web pages. Communication between these two types of processes is essential and is done through the ipcMain and ipcRenderer modules.

  • From Renderer to Main: From a web page, you can send a message to the main process using ipcRenderer.send('channel', data). The main process will listen for it with ipcMain.on('channel', (event, data) => { ... }).
  • From Main to Renderer: To send a message from the main process to a web window, you use window.webContents.send('channel', data). The renderer process will listen for this message with ipcRenderer.on('channel', (event, data) => { ... }).

This communication is vital for tasks such as opening new windows (action from the renderer, executed by the main) or passing data from the main to the web interface. You can even initialize lists or complete data from the main process and send them to the renderer when the page is ready. All details about IPC communication can be found in "Inter-Process Communication in Electron.js".

2.3. Building Cross-Platform Menus

Menus are a fundamental component of any desktop application. Electron.js allows you to create custom menus that integrate with the operating system and adapt to the conventions of Windows, macOS, and Linux. A menu in Electron is simply an array of objects with a predefined structure that is processed with electron.Menu.buildFromTemplate(). You can define two types of options:

  • Custom Options: With a click() property that executes a JavaScript function (e.g., open an external URL with shell.openExternal() or send an IPC event to the renderer).
  • Predefined Roles: Electron offers native roles such as reload, toggleDevTools, zoomIn, zoomOut, which perform common system actions without you needing to implement the logic.

The ability to combine custom options with predefined roles, and to adapt the menu according to the platform (process.platform), is very powerful. For a complete guide on how to create complex and cross-platform menus, including IPC communication so that menu actions affect the window content, consult "How to create a cross-platform menu in Electron.js".

2.4. Keyboard Shortcuts for Greater Efficiency

Keyboard shortcuts are crucial for the efficiency of a desktop application. Electron.js allows you to register two types of shortcuts:

  • Local Shortcuts (accelerator): Defined within the menu options and only work when the application window is active. They are perfect for actions like save, open, or reload.
  • Global Shortcuts (globalShortcut): Registered with the operating system and work even if the application is minimized or in the background. They are ideal for triggering quick actions or auxiliary tools.

Electron automatically translates key combinations to be cross-platform (e.g., CommandOrControl+S will be Cmd+S on macOS and Ctrl+S on Windows/Linux). 

It is essential to register global shortcuts after app.whenReady() and unregister them when closing the application to avoid conflicts. 

You can also capture keyboard events directly in the renderer process (keyup/keydown) or intercept keys in the main process with before-input-event for more granular control. Learn how to implement all these mechanisms in "Keyboard Shortcuts in Electron.js".

Chapter 3: Development, Debugging, and Optimization in Electron.js

Efficient development requires appropriate tools to debug and optimize our applications. Furthermore, keeping Electron updated is vital for security and performance.

3.1. Debugging with Chrome Tools (DevTools)

Since Electron windows are essentially Chromium browsers, you can debug your renderer process using the familiar Chrome DevTools. This allows you to inspect the DOM, debug JavaScript, view network requests, and analyze performance, just as you would in a web application. To activate the DevTools in a window, you simply use win.webContents.openDevTools() in your main process when creating the window:

function createWindow(){ let win = new BrowserWindow({ /* ... */ }) win.loadFile("index.html") win.webContents.openDevTools() // Activates DevTools }

This will open the developer console, allowing you to diagnose any problems that occur on the frontend side of your Electron application. Consult our article on "Debug (devTools) of the application in Chrome Electron.js" for more details.

3.2. Updating Electron.js to the Latest Version

The Electron team updates the framework frequently, introducing new features, performance improvements, and security patches. Keeping your project updated is crucial. To update your Electron version to the latest, you simply need to run the following command in your project's terminal:

$ npm install electron@latest

It is important to check Electron's release notes for possible changes that may require refactoring in your code due to compatibility issues. This process ensures that your application benefits from the latest innovations. More information in "Update to the latest version of Electron js using Node".

Chapter 4: Preparing Your Application for Production

Once your Electron application is developed, the final step is to package it into a distributable format that users can install on their operating systems.

4.1. Generating the Final Package for Production (Build)

To generate an executable for your Electron application, a tool like electron-builder is used. This package allows you to create native installers for Windows (EXE), macOS (DMG), and Linux (deb, rpm, AppImage). First, you must install electron-builder as a development dependency in your project:

$ npm install electron-builder -D

Then, configure scripts in your package.json to facilitate package generation for each platform. For example, for macOS:

"scripts": { "dev:macos": "electron-builder --macos --dir", // Generates a folder with the app for testing "pro:macos": "electron-builder --macos" // Packages into a distributable format (DMG) }

By running npm run pro:macos (or its equivalents for Windows and Linux), electron-builder will create the distributed executables in your project's dist/ folder. It is essential to make additional modifications to your code if your application accesses external resources or if file paths differ between the development and production environments. Consult "Generate an application for production in Electron.js" for a detailed guide.

Course and Book to Master Electron.js

In this book and course, we will learn how the framework is formed, its API and what it provides, the basic features that allow us to develop with this technology along with other web technologies to have scalable applications using all the power of Node together with Electron.

These guides aim to take the first steps with Electron.js; with this, we will state two things:

  1. It is not the objective to know 100% of Electron.js, or from zero to expert, since that would be too large a goal for the scope of this guide, but rather to know its ecosystem, what it offers us, and how it works based on several examples and/or small applications with limited scope.
  2. It is assumed that the reader has at least basic knowledge of the JavaScript programming language, as well as web technologies like HTML and CSS and of course Node.js. These are only some of the available posts and you can see all the posts in the complete list.

Conclusion: The Future of Desktop Development with Web Technologies

Electron.js has democratized desktop application development, allowing millions of web developers to leverage their existing skills to build cross-platform software. Its dual architecture (Main and Renderer Process), powerful operating system APIs, and flexibility to integrate any web library make it an indispensable tool in the arsenal of any modern developer.

From window creation and inter-process communication to menu management, keyboard shortcuts, debugging, and production packaging, Electron.js offers you total control.

This ultimate guide has covered the most important aspects of the framework, providing you with the foundations to build your own robust and functional desktop applications. We encourage you to explore each of the linked articles to deepen your understanding of the topics of interest and continue taking your ideas to new platforms.

Ver Listado »