Introduction to Electron: Building Cross‑Platform Desktop Applications with JavaScript
This tutorial introduces Electron, the Chromium‑Node.js framework for building cross‑platform desktop apps with HTML, CSS and JavaScript, walks through a simple “Hello World” project, explains its main and renderer processes, key modules such as IPC, remote and webview, and shows how to package the app for Windows and macOS.
After a previous version was revised, this article presents an updated tutorial on Electron, a framework that enables developers to create cross‑platform desktop applications using familiar web front‑end technologies. Electron combines Chromium and Node.js, providing APIs for native system interaction.
Overview
Electron (formerly Atom Shell) was originally created for the Atom editor. It allows developers to write desktop applications that run on Windows, Linux, and macOS using HTML, CSS, and JavaScript.
Popular applications built with Electron include Atom, Visual Studio Code, and Postman.
Hello World Example
Three simple steps are enough to build a minimal "Hello World" desktop program:
1. Clone the official example
$ git clone https://github.com/electron/electron-quick-start
2. Enter the project directory
$ cd electron-quick-start
3. Install dependencies and start the app
$ npm install && npm startThe resulting window displays a basic HTML page.
Project Structure
.
├── .gitignore
├── index.html
├── LICENSE.md
├── main.js
├── package.json
├── README.md
└── renderer.jsThe three core parts are:
package.json : defines dependencies and the entry point (main.js).
main.js : runs in the main process, creates application windows, and has full Node.js access.
index.html : rendered in the renderer process and shows the UI (e.g., the "Hello World" text).
Electron launches two processes: the main process and one or more renderer processes. Communication between them is handled via the IPC (Inter‑Process Communication) module.
Key Modules
IPC
The IPC module consists of ipcMain (used in the main process) and ipcRenderer (used in renderer processes). Example:
main.js:
// Import ipcMain
const ipcMain = require('electron').ipcMain;
// Listen on channel 'blabla'
ipcMain.on('blabla', function(event, arg) {
console.log(arg);
event.sender.send('blibli', 'hello client!');
});index.html (renderer):
// Import ipcRenderer
const ipcRenderer = require('electron').ipcRenderer;
// Send a message
ipcRenderer.send('blabla', 'hello server!');
// Listen for a reply
ipcRenderer.on('blibli', function(event, arg) {
console.log(arg);
});Running the code prints "hello server!" in the main process and "hello client!" in the renderer.
remote
The remote module allows renderer processes to access modules and globals defined in the main process.
main.js:
global.person = {
name: 'boxizen',
sex : 'male',
age : 24
};index.html:
// Import remote
const remote = require('electron').remote;
// Access the global object defined in main.js
console.log(remote.getGlobal('person').age);The output is 24.
webview
The webview tag embeds external web pages in a separate process, unlike iframe. Example embedding the web version of WeChat:
index.html:
<webview autosize="on" src="https://wx.qq.com/" style="display:inline-flex; width:1000px; height:764px"></webview>main.js (window creation):
mainWindow = new BrowserWindow({width: 1000, height: 764, resizable: false});The webview provides methods such as insertCSS() and executeJavaScript(). With the preload attribute, a script can be injected before the page loads, enabling features like displaying unread message badges.
Example badge script (badge.js) and IPC communication to update the dock badge:
// badge.js
const ipcRenderer = require('electron').ipcRenderer;
badge = {
get: function () {
$(".panel").bind('DOMSubtreeModified', function() {
var count = 0;
$(".icon.web_wechat_reddot_middle").each(function () {
count += parseInt(this.textContent);
});
if (count > 0) {
ipcRenderer.send('badge-changed', count.toString());
} else {
ipcRenderer.send('badge-changed', '');
}
});
}
}; // main.js (IPC handling)
const electron = require('electron');
const ipcMain = electron.ipcMain;
const app = electron.app;
ipcMain.on('badge-changed', function (event, num) {
app.dock.setBadge(num);
});Packaging
Electron applications can be packaged with tools such as electron-builder, electron-packager, or asar. This tutorial uses electron-packager:
# Install the packager
npm install electron-packager --save-dev
# Add scripts to package.json
"scripts": {
"start": "electron .",
"build-win": "electron-packager . myApp --platform=win32 --arch=x64 --version=1.2.6 --icon=./app.ico --overwrite",
"build-mac": "electron-packager . myApp --platform=darwin --arch=x64 --version=1.2.6 --icon=./app.icns --overwrite"
},
# Build for macOS
npm run build-macAfter the build completes, the packaged application can be distributed.
References
Electron official documentation: http://electron.atom.io/
From node‑webkit to Electron 1.0: http://cheng.guru/blog/2016/05/13/from-node-webkit-to-electron-1-0.html
Embedding Node.js in Atom editor: https://speakerdeck.com/zcbenz/practice-on-embedding-node-dot-js-into-atom-editor
Atom Shell vs node‑webkit: http://blog.iwege.com/posts/atom-shell-vs-node-webkit.html
Maintaining a large project experience: https://www.zhihu.com/question/36292298/answer/102418523
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Tencent Music Tech Team
Public account of Tencent Music's development team, focusing on technology sharing and communication.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
