Electron - Hello World
Electron - Modern Hello World
Section titled “Electron - Modern Hello World”Let’s create your first modern Electron desktop application. This ‘Hello World’ example will demonstrate the basic structure, including the main process, a renderer process, and a preload script for secure communication, which is a key aspect of modern Electron development.
First, ensure you have a package.json file. If not, run npm init -y. Then install Electron: npm install --save-dev electron.
Create a file named main.js. This is the entry point of your Electron application and runs in the Main Process:
const { app, BrowserWindow } = require('electron');const path = require('path');
function createWindow() { // Create the browser window. const mainWindow = new BrowserWindow({ width: 800, height: 600, webPreferences: { preload: path.join(__dirname, 'preload.js'), contextIsolation: true, // Protect against prototype pollution nodeIntegration: false // Enforce separation of concerns } });
// Load the index.html of the app. mainWindow.loadFile('index.html');
// Open the DevTools (optional) // mainWindow.webContents.openDevTools();}
// This method will be called when Electron has finished initialization// and is ready to create browser windows.app.whenReady().then(() => { createWindow();
app.on('activate', function () { // On macOS it's common to re-create a window in the app when the // dock icon is clicked and there are no other windows open. if (BrowserWindow.getAllWindows().length === 0) createWindow(); });});
// Quit when all windows are closed, except on macOS.app.on('window-all-closed', function () { if (process.platform !== 'darwin') app.quit();});Next, create preload.js. This script runs in a privileged environment before the renderer’s web page is loaded. It has access to Node.js APIs and can securely expose specific functionalities to the renderer process via the contextBridge.
const { contextBridge } = require('electron');
contextBridge.exposeInMainWorld('electronVersions', { node: () => process.versions.node, chrome: () => process.versions.chrome, electron: () => process.versions.electron // We can also expose variables, not just functions});Now, create your index.html file. This is the web page that will be displayed in your application’s window (Renderer Process):
<!DOCTYPE html><html><head> <meta charset="UTF-8"> <title>Hello World!</title> <link rel="stylesheet" href="styles.css"></head><body> <h1>Hello World!</h1> <p> We are using Node.js <span id="node-version"></span>, Chromium <span id="chrome-version"></span>, and Electron <span id="electron-version"></span>. </p>
<script src="renderer.js"></script></body></html>Create a simple styles.css (optional):
body { font-family: Arial, sans-serif; padding: 20px; background-color: #f4f4f4; color: #333;}
h1 { color: #0056b3;}
span { font-weight: bold; color: #28a745;}Finally, create renderer.js. This script runs in the renderer process and interacts with the DOM. It will use the APIs exposed by preload.js:
document.addEventListener('DOMContentLoaded', () => { const nodeVersionElement = document.getElementById('node-version'); const chromeVersionElement = document.getElementById('chrome-version'); const electronVersionElement = document.getElementById('electron-version');
if (window.electronVersions) { nodeVersionElement.textContent = window.electronVersions.node(); chromeVersionElement.textContent = window.electronVersions.chrome(); electronVersionElement.textContent = window.electronVersions.electron(); } else { console.error('electronVersions API not found. Check preload script.'); }});To run your app, first add a start script to your package.json:
"scripts": { "start": "electron ."}Then, run the app from your terminal:
npm startA window will appear displaying ‘Hello World!’ and the versions of Node.js, Chromium, and Electron being used. This text is dynamically inserted by renderer.js using information securely provided by preload.js.
How This Modern App Works
Section titled “How This Modern App Works”-
main.js(Main Process): Manages the application lifecycle and creates browser windows (BrowserWindow). It configureswebPreferencesto use apreload.jsscript, enablecontextIsolation, and disablenodeIntegrationfor security. -
preload.js: Acts as a bridge between the Node.js environment (accessible here) and the renderer’s isolated JavaScript context. It usescontextBridge.exposeInMainWorldto selectively expose specific Node.js functionalities (likeprocess.versions) to the renderer under a chosen API namespace (e.g.,window.electronVersions). -
index.html&renderer.js(Renderer Process):index.htmldefines the UI structure.renderer.jsruns in this sandboxed environment. It cannot directly access Node.js APIs. Instead, it uses the functions exposed bypreload.js(e.g.,window.electronVersions.node()) to get the required information and update the DOM.
This structure enhances security by limiting the renderer process’s access to powerful Node.js APIs, reducing the attack surface if your application loads remote or untrusted content.