Skip to content

Electron - Building UIs

Electron - Building Modern User Interfaces

Section titled “Electron - Building Modern User Interfaces”

Electron applications build their User Interfaces (UIs) using standard web technologies: HTML, CSS, and JavaScript. This means you can leverage the vast ecosystem of front-end web development tools, libraries, and frameworks. Popular choices include React, Vue.js, Angular, Svelte, as well as CSS frameworks like Bootstrap or Tailwind CSS.

Package management is typically handled by npm (Node Package Manager) or yarn, which come bundled with Node.js. These tools allow you to easily install and manage front-end dependencies. The bower package manager, mentioned in older tutorials, is now largely deprecated.

For example, to install Bootstrap and jQuery (though modern applications often use vanilla JS or a UI framework instead of jQuery directly for DOM manipulation), you would use npm:

npm install bootstrap jquery

This command downloads the packages into a node_modules directory in your project. You can then reference their CSS and JS files in your HTML or import them into your JavaScript modules if you’re using a build tool like Webpack or Parcel.

Let’s set up a basic main.js file. Note the webPreferences for security and to enable a preload script:

const { app, BrowserWindow } = require('electron');
const path = require('path');
let mainWindow;
function createWindow() {
mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
contextIsolation: true,
nodeIntegration: false
}
});
mainWindow.loadFile(path.join(__dirname, 'index.html'));
}
app.whenReady().then(createWindow);
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});

Now, create preload.js. This script runs before your renderer’s web page loads and can selectively expose Node.js APIs or other functionalities to your renderer process in a secure way using contextBridge.

const { contextBridge } = require('electron');
const $ = require('jquery'); // jQuery is available in preload due to nodeIntegration by default in preload
contextBridge.exposeInMainWorld('electronAPI', {
// Expose jQuery to the renderer window, if needed for legacy or specific reasons
// Be cautious with exposing entire libraries like jQuery to the renderer.
// Often, it's better to expose specific functions that renderer needs.
getJQuery: () => $
});
// You could also expose specific functions that use jQuery internally
// contextBridge.exposeInMainWorld('domUtils', {
// setText: (selector, text) => $(selector).text(text),
// onClick: (selector, callback) => $(selector).on('click', callback)
// });

Next, your index.html file. We’ll link Bootstrap’s CSS from node_modules:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>UI Building Example</title>
<!-- Adjust path if your node_modules is elsewhere relative to index.html -->
<link rel="stylesheet" href="../node_modules/bootstrap/dist/css/bootstrap.min.css">
<style>
body { padding: 20px; }
</style>
</head>
<body>
<div class="container">
<h1>This page uses Bootstrap and jQuery (via Preload)</h1>
<h3 id="click-counter">Counter: 0</h3>
<button class="btn btn-success" id="countBtn">Click Me!</button>
</div>
<script src="./renderer.js"></script>
</body>
</html>

Finally, create renderer.js with the click counter logic. It will use the jQuery instance exposed by the preload script:

// renderer.js
document.addEventListener('DOMContentLoaded', () => {
// Access jQuery exposed by the preload script
// Note: Exposing full jQuery like this (window.electronAPI.getJQuery()) is one way,
// but for better security and modularity, consider exposing only necessary functions from preload.
const $ = window.electronAPI.getJQuery();
let count = 0;
const clickCounterDisplay = $('#click-counter');
const countButton = $('#countBtn');
clickCounterDisplay.text(`Counter: ${count}`);
countButton.on('click', () => {
count++;
clickCounterDisplay.text(`Counter: ${count}`);
});
});

Run the app using:

npx electron .

The application window will show a page styled with Bootstrap, featuring a title, a counter display initialized to ‘Counter: 0’, and a green ‘Click Me!’ button. Clicking the button will increment and update the counter display.

This setup demonstrates using external libraries like Bootstrap and jQuery in a modern Electron app with contextIsolation enabled. For complex applications, consider using a JavaScript framework (React, Vue, Angular) along with build tools like Webpack or Vite for a more structured development experience. These tools help manage dependencies, transpile code, and bundle assets efficiently.