Tutorial for creating your first application with Electron
The Value of Electron: Uniting the Web and Native Desktop
Electron isn't just a great option for creating web applications that behave like native desktop applications; it's also a formidable solution for building a GUI around applications that would otherwise be limited to a command-line interface (CLI).
Breaking Browser Barriers
Suppose you want to create an application that lets you view and edit a folder of images directly on your computer.
Traditional Browser Applications: These applications cannot access the file system. They wouldn't be able to access the photo directory, load any of the images, or save the changes you make.
Node.js Only: With Node, you could implement all those system access and file handling functions. However, you wouldn't be able to provide a GUI, which would make your application extremely difficult for the average user to use.
By combining the browser environment (Chromium) with Node.js, you can use Electron to create an application where you can open and edit photos, as well as provide a visual and intuitive user interface to do so.
✨ Simplicity and Flexibility
Electron isn't a complicated framework; it's 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 as you see fit.
Creating an Electron.js Project
Now we are going to create a typical hello world application with Electron and run it to display it in an application window.
In your workspace, we are going to create a folder for the project we are going to carry out:
$ mkdir For example:
$ mkdir chat-app $ cd chat-appAt this point, you can drag the above folder to your VSC or preferred editor to start working on this project, a project that is completely empty for now; now, we need to initialize our new project with the NPM tool using the following command:
$ npm initThe previous command initializes a Node project and will generate the package.json file for us; which contains project metadata, as well as commands, version number, dependencies, among others:
package.json
{
"name": "electron-chat2",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
},
"author": "",
"license": "ISC",
}With this, we can now install our Electron.js with the following command:
$ npm i -D electron@latestWith the previous command, we install the latest version of the popular framework, ready to develop applications; remember that the previous material is part of my complete course on Electron.js
Rendering a Window
Content Index
We can now start working according to the project we created with Electron and Node; we will learn in detail and in practice the concepts of "main process" and "renderer process" (web page).
Now let's look at our package.json with the Electron dependency:
package.json
{
"name": "electron-chat2",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "electron ."
},
"author": "",
"license": "ISC",
"devDependencies": {
"electron": "^20.0.3"
}
}In the project root, we are going to create a JS file with the following content:
index.js
const { app, BrowserWindow } = require('electron')
function createWindow() {
let win = new BrowserWindow({
width: 800,
height: 600,
})
win.loadFile("index.html")
}
app.whenReady().then(createWindow)First, you must import the necessary objects and classes that we are going to use to work; since Electron uses Node, it is quite modular, and therefore, we import the necessary elements to work with it, in this case:
- A reference to a BrowserWindow type object that will be instantiated and shown to your users.
- With the app object, we control the application's lifecycle.
After that, we must wait for the application to be ready before we can create a small window of 800 x 600 size (the size specified using new BrowserWindow({ width: 800, height: 600, })).
Finally, the content of the index.html file, which contains the main content of the Electron application, is loaded and displayed:
win.loadFile("index.html")Although we have not yet defined the index.html file, as you can guess, this corresponds to the renderer process or web page; let's remember that web pages have the HTML extension.
The app.whenReady() function returns a promise when Electron is initialized (and therefore, is ready to make calls to the OS, in this case, to create a window).
This file, as you can guess, is the main process in which we maintain communication with the OS using the extensive API of functionalities that Electron provides us, in this case, the function that allows us to create a window.
Now, we need to show some Graphical Interface to the user, buttons, texts, images, etc. For this, we have to work in the renderer process or web page, which, as its name indicates, is an HTML page that can have any HTML content:
index.html
<!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>Document</title>
</head>
<body>
<h1>Hello Electron</h1>
</body>
</html>As you can see, in the previous web page, we can place any type of HTML content, in this case, a welcome message.
Now we need a mechanism with which to execute the application and be able to visualize the window with the greeting; we create the command to execute our application:
package.json
{
"name": "electron-chat2",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "electron ."
},
"author": "",
"license": "ISC",
"devDependencies": {
"electron": "^20.0.3"
}
}And by executing the command in the terminal:
$ npm run startRemember that the previous material is part of my complete course on Electron.js
HTML and a bit of CSS
A basic application in Electron.js is pure HTML just as we showed before. Of course, this HTML can be integrated with Electron to provide it with operating system functionalities such as menus, window management, etc., but everything starts with a simple HTML 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>Document</title>
<style>
body {
background-color: purple;
}
h1 {
text-align: center;
}
#customId{
display: block;
width: 100%;
}
section{
background-color: #FFF;
font-family: Georgia;
padding: 25px;
margin-top: 10px;
}
</style>
</head>
<body>
<main>
<h1>Page Detail</h1>
<img id="customId" src="https://cdn.pixabay.com/photo/2022/08/16/20/02/wallpaper-7391054__340.jpg" alt="">
<section>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Esse dicta nulla asperiores, similique iure quas
optio! Error quasi doloremque illo voluptatem, fugiat voluptate exercitationem, qui repudiandae officiis
ipsa corrupti animi.</p>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Esse dicta nulla asperiores, similique iure quas
optio! Error quasi doloremque illo voluptatem, fugiat voluptate exercitationem, qui repudiandae officiis
ipsa corrupti animi.</p>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Esse dicta nulla asperiores, similique iure quas
optio! Error quasi doloremque illo voluptatem, fugiat voluptate exercitationem, qui repudiandae officiis
ipsa corrupti animi.</p>
</section>
</main>
</body>
</html>In this example as you can see, we are placing HTML and CSS content, which are the fundamental pieces in any web development, and in Electron, it cannot be the exception. When running the application, we will have:
Remember that the code for main.js is the same as the one used in the first application. Remember that the previous material is part of my complete course on Electron.js
Importing Bootstrap 5 into Electron.js
Electron.js, being a web application at its core, allows us to use all kinds of libraries, tooltips, etc., as in this case, Bootstrap:
For this, we have the following command that we must execute on the previously generated Electron project:
$ npm install bootstrapAnd with the previous command, we already have Bootstrap ready in the project. To configure it, we have several ways. This time, we are going to load Bootstrap based on an import to it in a CSS file:
css/index.css
@import "../node_modules/bootstrap/dist/css/bootstrap.min.css";Which we will use from our html 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>Document</title>
<link rel="stylesheet" href="css/index.css">
</head>
<body>
<button class="btn btn-primary">Button</button>
</body>
</html>And that would be all, with this, we can use Bootstrap without problems. If you want to use another library like Tailwind or similar, you should follow the same steps:
- Install the package in Node
- Create a CSS file in which you place the library's dependencies
- Load the previous file in your HTML file.
The next thing we will see is how to activate the devtool in the browser with Electron.js
Remember that the previous material is part of my complete course on Electron.js
Text Box, Chat-type App
In this section, we are going to create a list of messages or chats, which will be a structure similar to the contact list built in the previous entry:
<div class="col-8" id="right">
<div class="d-flex chat">
<div class="w-25 d-flex align-items-end justify-content-end">
<img class="rounded-pill me-3 avatar" width="60"
src="https://randomuser.me/api/portraits/men/17.jpg">
</div>
<div class="w-75">
<div class="card">
<div class="card-body">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Doloribus reprehenderit
voluptatibus cumque, deserunt deleniti consequatur adipisci nisi consequuntur sunt itaque?
Sunt aspernatur, ratione labore ipsam enim unde itaque dolorum magni?
</div>
</div>
<p class="small text-muted">8:45 PM</p>
</div>
</div>
<div class="d-flex chat">
<div class="w-75 ">
<div class="card bg-dark">
<div class="card-body text-light">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Doloribus reprehenderit
voluptatibus cumque, deserunt deleniti consequatur adipisci nisi consequuntur sunt itaque?
Sunt aspernatur, ratione labore ipsam enim unde itaque dolorum magni?
</div>
</div>
<p class="small text-muted float-end">9:17 AM</p>
</div>
<div class="w-25 d-flex align-items-end">
<img class="rounded-pill ms-3 avatar" src="https://randomuser.me/api/portraits/men/19.jpg">
</div>
</div>
</div>And we will use the following CSS:
css/style.css
#right {
background-color: #333;
***
}
.chat {
margin-top: 8px;
}
.chat img.avatar {
width: 50px;
height: 50px;
}With this, it will look like this:
The next thing we are going to create is a list of chats.
Previously we created the message list for the application, now we are going to create the text box, which is where we will place the messages. It will be composed of two columns, one of them with automatic size so that it only occupies the necessary size; in the fixed-size one, we place the TEXTAREA with rounded corners:
<div class="col-8" id="right">
*** CHATS
<form action="" class="form-message">
<div class="row">
<div class="col">
<textarea class="form-control rounded-pill"></textarea>
</div>
<div class="col-auto">
<button class="btn btn-primary rounded-circle send-button">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="w-6 h-6">
<path strokeLinecap="round" strokeLinejoin="round" d="M12 20.25c4.97 0 9-3.694 9-8.25s-4.03-8.25-9-8.25S3 7.444 3 12c0 2.104.859 4.023 2.273 5.48.432.447.74 1.04.586 1.641a4.483 4.483 0 01-.923 1.785A5.969 5.969 0 006 21c1.282 0 2.47-.402 3.445-1.087.81.22 1.668.337 2.555.337z" />
</svg>
</button>
</div>
</div>
</form>
</div> </button> </div> </div> </form> </div>And we will use the following CSS:
css/style.css
form-message{
margin-top: 15px;
}
.form-message button.send-button svg {
width: 40px;
height: 40px;
}
.form-message textarea{
overflow: hidden;
resize: none;
}For the chat application we are carrying out and having already installed Bootstrap 5 in the Electron.js project, it consists of two sections, one for each column, one for the contact list and the other for the chat detail.
Contacts
For the contacts column, we will define an UL list with its LIs, in which, in the LI we will place a card; in short, each contact corresponds to a Bootstrap card; apart from this, we will place typical contact data such as image, name, last contact, and chat count that we align using flexes and their related properties. Finally, we will use the HTML flexes to align the content in rows for the image and the last contact content:
<div class="col-4" id="left">
<ul class="contact list-unstyled mb-0 mt-2">
<li class="p-2 card ">
<div class="card-body">
<div class="d-flex">
<div>
<img class="rounded-pill me-3" width="60" src="https://randomuser.me/api/portraits/women/56.jpg">
</div>
<div>
<p class="fw-bold mb-0 text-light">Alex Alexis</p>
<p class="small text-muted">Lorem ipsum dolor sit amet...</p>
</div>
</div>
</div>
</li>
<li class="p-2 card mt-2">
<div class="card-body">
<div class="d-flex">
<div>
<img class="rounded-pill me-3" width="60" src="https://randomuser.me/api/portraits/men/96.jpg">
</div>
<div>
<p class="fw-bold mb-0 text-light">Eli Barrett</p>
<p class="small text-muted">Lorem ipsum dolor sit amet...</p>
</div>
<div>
<p class="small text-muted">5 min ago</p>
<span class="badge bg-danger rounded-pill float-end">2</span>
</div>
</div>
</div>
</li>
<li class="p-2 card mt-2">
<div class="card-body">
<div class="d-flex">
<div>
<img class="rounded-pill me-3" width="60" src="https://randomuser.me/api/portraits/men/17.jpg">
</div>
<div>
<p class="fw-bold mb-0 text-light">Ramon Reed</p>
<p class="small text-muted">Lorem ipsum dolor sit amet...</p>
</div>
<div>
<p class="small text-muted">2 days ago</p>
<span class="badge bg-danger rounded-pill float-end">1</span>
</div>
</div>
</div>
</li>
<li class="p-2 card mt-2">
<div class="card-body">
<div class="d-flex">
<div>
<img class="rounded-pill me-3" width="60" src="https://randomuser.me/api/portraits/women/83.jpg">
</div>
<div>
<p class="fw-bold mb-0 text-light">Kylie Young</p>
<p class="small text-muted">Lorem ipsum dolor sit amet...</p>
</div>
<div>
<p class="small text-muted">1 week ago</p>
<span class="badge bg-danger rounded-pill float-end">4</span>
</div>
</div>
</div>
</li>
</ul>
</div>And a custom CSS:
#left {
background-color: #111;
***
}
.contact .card {
background-color: #333;
}The next step is to learn about the Main Process and the Rendering Process in Electron JS.
I agree to receive announcements of interest about this Blog.
We will create our first window using Electron.js