Andrés Cruz

La Guía Definitiva de Electron.js: Crea Aplicaciones de Escritorio Multiplataforma con Tecnologías Web

Electron.js ha revolucionado la forma en que pensamos sobre las aplicaciones de escritorio. Al permitir a los desarrolladores construir programas nativos para Windows, macOS y Linux utilizando únicamente tecnologías web (HTML, CSS y JavaScript), ha democratizado la creación de software multiplataforma.

Este SUPER post es tu recurso definitivo para dar los primeros pasos, diseñado para llevarte desde los primeros pasos en Electron hasta la creación de aplicaciones listas para producción, pasando por sus conceptos fundamentales y técnicas avanzadas.

A lo largo de este documento, destilaremos el conocimiento de nuestras publicaciones más detalladas sobre Electron.js. Abordaremos la instalación, la creación de ventanas, la comunicación entre procesos, la gestión de menús, la depuración y la preparación para la distribución. 

Nuestro objetivo es proporcionarte un mapa de ruta completo, lleno de fragmentos de código, explicaciones técnicas y consejos prácticos, todo con el tono directo y profesional que caracteriza a DesarrolloLibre. Prepárate para dominar Electron.js y expandir tus habilidades de desarrollo web al mundo del software de escritorio.

¿Qué es el Electron?

Electron es un framework de código abierto para crear aplicaciones de escritorio multiplataforma con tecnología web; es decir: HTML, CSS y JavaScript; al estar integrada como un módulo de Node, podemos usar todo el poderío de Node para nuestra aplicación; componentes como base de datos, Api Rest, frameworks CSS como Bootstrap o Tailwind y un largo etc, lo podemos integrar en una aplicación en Electron.

Está desarrollado y mantenido por GitHub y es el framework gráfico detrás de muchos proyectos de código abierto muy importantes de la actualidad como Atom, Visual Studio Code, Discord y Whatsapp.

Sobre Electron

El secreto de Electron es una combinación de dos procesos; el proceso main o principal y el proceso renderer.

  1. El primer proceso, que es el main o principal es un proceso de Node.js; este proceso tiene acceso a varias APIs de Electron.js con el cual, podemos comunicarnos con el Sistema Operativo.
  2. El segundo proceso, es el de renderer el cual usa Chromium; este proceso tiene un Node.js incluido y con esto, acceso a todos sus módulos.

Chromium, un proyecto de código abierto detrás del navegador Google Chrome y Node.js, un tiempo de ejecución de JavaScript basado en el motor de JavaScript V8 de Chrome.

Electron usa Chromium para el frontend y Node.js para el backend. Proporciona un amplio conjunto de interfaces o APIs con las cuales poder acceder al sistema operativo y con las cuales, permiten a nosotros, los desarrolladores crear aplicaciones multiplataforma que comparten un mismo código HTML, CSS y JavaScript.

En definitiva, puedes ver el proceso principal como el servidor, en el cual tenemos las conexiones a la base de datos y los accesos al sistema operativo, y el proceso de renderer, el lado del cliente, en el cual, armamos la pantalla para que el usuario final pueda interactuar; es importante señalar que podemos comunicar ambos procesos de manera directa.

Electron.js es un framework web con el cual, podemos crear aplicaciones de escritorio multiplataforma (no nativas) que funcionan en Windows, MacOS y Linux, con una envoltura web empleando JavaScript, HTML y CSS y sin necesidad de tener experiencia en desarrollo nativo.

Electron.js funciona mediante dos procesos:

  1. El de main, que es un proceso de Node, la aplicación en sí misma, en la cual tenemos acceso a algunos módulos provistos por la API de Electron.js (algunos que sirven para comunicarnos con el Sistema Operativo, por ejemplo, crear menús multiplataformas.
  2. El de renderer, que es un proceso de Chromium que adicionalmente, tiene un Node.js incorporado y acceso a todos sus módulos, desde este proceso, podemos desarrollar la UI de la aplicación.

Capítulo 1: Primeros Pasos y Configuración Inicial en Electron.js

Electron.js es un framework web que nos permite crear aplicaciones de escritorio multiplataforma (no nativas) que funcionan en Windows, MacOS y Linux, con una envoltura web empleando JavaScript, HTML y CSS y sin necesidad de tener experiencia en desarrollo nativo. Es una solución formidable para construir una GUI alrededor de aplicaciones que, de otro modo, estarían limitadas a una interfaz de línea de comandos (CLI). Su valor radica en unir el entorno del navegador (Chromium) con Node.js, permitiendo acceder a recursos del sistema operativo de una manera que las aplicaciones web tradicionales no pueden.

1.1. ¿Qué es Electron.js y su Potencial?

Electron no es un framework complicado; es un tiempo de ejecución (runtime) simple. De manera similar a cómo usas Node desde la línea de comandos, puedes ejecutar aplicaciones de Electron utilizando la herramienta de línea de comando de Electron. No necesitas aprender convenciones complejas para comenzar y tienes total libertad para estructurar tu aplicación como mejor te parezca. Este framework nos permite crear aplicaciones web para luego darle funcionamiento de aplicaciones de escritorio nativas como el uso de menús, exportar e instalar en Sistemas Operativos Windows, Linux y Mac, atajos de teclado, creación de ventanas y diálogos, y drag and drop de archivos.

El material introductorio a este curso forma parte de nuestro curso completo sobre Electron.js, donde abordamos el núcleo de Electron.js comenzando desde la instalación de los componentes básicos (Node y Visual Studio Code) hasta la creación de aplicaciones con JavaScript nativo e integración con Vue CLI. Es importante mencionar que no es necesario conocimiento previo en Node, solo conocimientos básicos de programación y de HTML, CSS y JavaScript. Este curso está dirigido a cualquiera que quiera conocer el framework y crear sus primeras aplicaciones de escritorio, mejorar sus habilidades y crecer como desarrollador.

1.2. Creando tu Primera Ventana: El "Hola Mundo" en Electron

Para crear tu primera aplicación con Electron.js, el proceso es sencillo. Primero, crea una carpeta para tu proyecto e inicialízala con NPM:

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

Luego, instala Electron como una dependencia de desarrollo:

$ npm i -D electron@latest

En el archivo index.js (tu proceso principal), defines la creación de la ventana:

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)

Y tu index.html (tu proceso de renderizado) será una simple página web:

<!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>

Finalmente, añade un script start en tu package.json y ejecuta npm run start:

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

Este proceso es la base de cualquier aplicación Electron y se explora en profundidad en "Creando tu Primera Aplicación con Electron" y "Primeros pasos con Electron.js" que es un recurso de pago.

1.3. Habilitando la Integración con Node.js

La integración con Node.js en Electron permite que tu proceso de renderizado (la página web) acceda a los recursos de Node.js, y por ende, a la API de Electron. Esto es fundamental para dotar a tu aplicación web de funcionalidades de escritorio. Por defecto, esta integración está deshabilitada por motivos de seguridad en las últimas versiones de Electron. Para habilitarla, debes configurarla en webPreferences al crear tu ventana:

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

Es importante notar que nodeIntegration permite el acceso completo a las APIs de Node.js en el proceso de renderizado, lo cual es muy potente pero puede ser un riesgo de seguridad si cargas contenido de fuentes no confiables. contextIsolation ayuda a mitigar esto, pero desactivarlo (false) te da mayor flexibilidad para scripts antiguos. Para más detalles, consulta "Habilitar la integración con Node en Electron.js".

Capítulo 2: Interacción y Experiencia de Usuario en Electron.js

Las aplicaciones de escritorio no solo muestran contenido; interactúan con el usuario y con el sistema operativo de maneras complejas. Electron.js proporciona mecanismos robustos para gestionar eventos, comunicar procesos y crear interfaces de usuario ricas y adaptadas.

2.1. Introducción a los Eventos en Electron.js

En Electron, los eventos son notificaciones que se disparan en diferentes momentos del ciclo de vida de la aplicación, ya sea en el proceso principal (Main Process) o en los procesos de renderizado (Renderer Processes). Entender y controlar estos eventos es fundamental para el comportamiento dinámico de tu aplicación.

  • Eventos del Módulo app (Proceso Principal): Controlan el ciclo de vida general de la aplicación, como ready (cuando Electron ha terminado de iniciar), window-all-closed (cuando todas las ventanas se han cerrado) o activate (especialmente útil en macOS para reactivar la aplicación sin crear una nueva ventana si ya hay una).
  • Eventos de webContents (Proceso de Renderizado): Relacionados con el contenido de una ventana, como did-finish-load (cuando la página web está completamente cargada) o dom-ready (cuando el DOM está listo).

Los eventos son como "sensores" que te permiten reaccionar a lo que ocurre. Por ejemplo, puedes usarÑ

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

Para cerrar la aplicación cuando todas las ventanas se cierran. La gestión de eventos es la clave para una aplicación reactiva y se explica a fondo en "Introducción a los eventos en Electron.js".

2.2. Comunicación entre Procesos (IPC): Main y Renderer

Una característica distintiva de Electron es su arquitectura de dos procesos: el Proceso Principal (Main Process), que ejecuta el código Node.js y gestiona las ventanas, y los Procesos de Renderizado (Renderer Processes), que son instancias de Chromium y muestran las páginas web. La comunicación entre estos dos tipos de procesos es esencial y se realiza a través de los módulos ipcMain e ipcRenderer.

  • De Renderer a Main: Desde una página web, puedes enviar un mensaje al proceso principal utilizando ipcRenderer.send('canal', datos). El proceso principal lo escuchará con ipcMain.on('canal', (event, datos) => { ... }).
  • De Main a Renderer: Para enviar un mensaje del proceso principal a una ventana web, usas window.webContents.send('canal', datos). El proceso de renderizado escuchará este mensaje con ipcRenderer.on('canal', (event, datos) => { ... }).

Esta comunicación es vital para tareas como abrir nuevas ventanas (acción desde el render, ejecutada por el main) o pasar datos desde el main a la interfaz web. Incluso puedes inicializar listados o datos completos desde el proceso principal y enviarlos al renderizado cuando la página esté lista. Todos los detalles sobre la comunicación IPC se encuentran en "Comunicación entre procesos en Electron.js".

2.3. Construyendo Menús Multiplataforma

Los menús son un componente fundamental de cualquier aplicación de escritorio. Electron.js te permite crear menús personalizados que se integran con el sistema operativo y se adaptan a las convenciones de Windows, macOS y Linux. Un menú en Electron no es más que un array de objetos con una estructura predefinida que se procesa con electron.Menu.buildFromTemplate(). Puedes definir dos tipos de opciones:

  • Opciones Personalizadas: Con una propiedad click() que ejecuta una función JavaScript (ej. abrir una URL externa con shell.openExternal() o enviar un evento IPC al renderer).
  • Roles Predefinidos: Electron ofrece roles nativos como reload, toggleDevTools, zoomIn, zoomOut, que realizan acciones comunes del sistema sin que necesites implementar la lógica.

La capacidad de combinar opciones personalizadas con roles predefinidos, y de adaptar el menú según la plataforma (process.platform), es muy potente. Para una guía completa sobre cómo crear menús complejos y multiplataforma, incluyendo la comunicación IPC para que las acciones del menú afecten al contenido de la ventana, consulta "Cómo crear un menú multiplataforma en Electron.js".

2.4. Atajos de Teclado (Shortcuts) para una Mayor Eficiencia

Los atajos de teclado, o "shortcuts", son cruciales para la eficiencia de una aplicación de escritorio. Electron.js te permite registrar atajos de dos tipos:

  • Atajos Locales (accelerator): Se definen dentro de las opciones de menú y solo funcionan cuando la ventana de la aplicación está activa. Son perfectos para acciones como guardar, abrir o recargar.
  • Atajos Globales (globalShortcut): Se registran con el sistema operativo y funcionan incluso si la aplicación está minimizada o en segundo plano. Son ideales para disparar acciones rápidas o herramientas auxiliares.

Electron traduce automáticamente las combinaciones de teclas para ser multiplataforma (ej. CommandOrControl+S será Cmd+S en macOS y Ctrl+S en Windows/Linux). 

Es fundamental registrar los atajos globales después de app.whenReady() y desregistrarlos al cerrar la aplicación para evitar conflictos. 

También puedes capturar eventos de teclado directamente en el proceso de renderizado (keyup/keydown) o interceptar teclas en el proceso principal con before-input-event para un control más granular. Aprende a implementar todos estos mecanismos en "Atajos de teclado: Shortcut en Electron.js".

Capítulo 3: Desarrollo, Depuración y Optimización en Electron.js

Un desarrollo eficiente requiere herramientas adecuadas para depurar y optimizar nuestras aplicaciones. Además, mantener Electron actualizado es vital para la seguridad y el rendimiento.

3.1. Depuración (Debugging) con Herramientas de Chrome (DevTools)

Dado que las ventanas de Electron son esencialmente navegadores Chromium, puedes depurar tu proceso de renderizado utilizando las familiares Chrome DevTools. Esto te permite inspeccionar el DOM, depurar JavaScript, ver peticiones de red y analizar el rendimiento, igual que harías en una aplicación web. Para activar las DevTools en una ventana, simplemente usas win.webContents.openDevTools() en tu proceso principal al crear la ventana:

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

Esto abrirá la consola de desarrolladores, permitiéndote diagnosticar cualquier problema que ocurra en el lado del frontend de tu aplicación Electron. Consulta nuestro artículo sobre "Debug (devTools) de la aplicación en Chrome Electron.js" para más detalles.

3.2. Actualización de Electron.js a la Última Versión

El equipo de Electron actualiza el framework con frecuencia, introduciendo nuevas características, mejoras de rendimiento y parches de seguridad. Mantener tu proyecto actualizado es crucial. Para actualizar tu versión de Electron a la última, simplemente debes ejecutar el siguiente comando en la terminal de tu proyecto:

$ npm install electron@latest

Es importante revisar las notas de la versión de Electron por posibles cambios que puedan requerir refactorizaciones en tu código debido a problemas de compatibilidad. Este proceso garantiza que tu aplicación se beneficie de las últimas innovaciones. Más información en "Actualizar a la última versión de Electron js mediante Node".

Capítulo 4: Preparando tu Aplicación para Producción

Una vez que tu aplicación Electron está desarrollada, el último paso es empaquetarla en un formato distribuible que los usuarios puedan instalar en sus sistemas operativos.

4.1. Generando el Paquete Final para Producción (Build)

Para generar un ejecutable de tu aplicación Electron, se utiliza una herramienta como electron-builder. Este paquete te permite crear instaladores nativos para Windows (EXE), macOS (DMG) y Linux (deb, rpm, AppImage). Primero, debes instalar electron-builder como una dependencia de desarrollo en tu proyecto:

$ npm install electron-builder -D

Luego, configura scripts en tu package.json para facilitar la generación de los paquetes para cada plataforma. Por ejemplo, para macOS:

"scripts": {
    "dev:macos": "electron-builder --macos --dir", // Genera una carpeta con la app para pruebas
    "pro:macos": "electron-builder --macos" // Empaqueta en un formato distribuible (DMG)
}

Ejecutando npm run pro:macos (o sus equivalentes para Windows y Linux), electron-builder creará los ejecutables distribuidos en la carpeta dist/ de tu proyecto. Es fundamental realizar modificaciones adicionales en tu código si tu aplicación accede a recursos externos o si las rutas de archivos difieren entre el entorno de desarrollo y el de producción. Consulta "Generar una aplicación para producción en Electron.js" para una guía detallada.

Curso y Libro para dominar Electron.js

En este libro y curso, vamos a conocer cómo está formado el framework, su API y que nos provee, las características básicas que nos permiten desarrollar con esta tecnología junto con otras tecnologías web para tener aplicaciones escalables usando todo el poderío de Node junto con Electron.

Estas guías tienen la finalidad de dar los primeros pasos con Electron.js; con esto, vamos a plantear dos cosas:

  1. No tiene por objetivo conocer al 100% Electron.js, o de cero a experto, ya que, sería un objetivo demasiado grande para el alcance de esta guía, si no conocer su ecosistema, que nos ofrece y cómo funciona el mismo en base a varios ejemplos y/o aplicaciones pequeñas con alcances limitados.
  2. Se da por hecho de que el lector tiene conocimientos al menos básicos en el lenguaje de programación de JavaScript, al igual que en tecnologías web como HTML y CSS y por supuesto Node.js. Estos son solamente algunos posts que están disponibles y puedes ver todos los posts en el listado completo.

Conclusión: El Futuro del Desarrollo de Escritorio con Tecnologías Web

Electron.js ha democratizado el desarrollo de aplicaciones de escritorio, permitiendo a millones de desarrolladores web aprovechar sus habilidades existentes para construir software multiplataforma. Su arquitectura dual (Main y Renderer Process), sus potentes APIs de sistema operativo y su flexibilidad para integrar cualquier librería web lo convierten en una herramienta indispensable en el arsenal de cualquier desarrollador moderno.

Desde la creación de ventanas y la comunicación entre procesos hasta la gestión de menús, atajos de teclado, depuración y empaquetado para producción, Electron.js te ofrece un control total.

Esta guía definitiva ha cubierto los aspectos más importantes del framework, proporcionándote los cimientos para construir tus propias aplicaciones de escritorio robustas y funcionales. Te animamos a explorar cada uno de los artículos enlazados para profundizar en los temas de tu interés y seguir llevando tus ideas a nuevas plataformas.