ππ Recently I read a blog where electron.js was mentioned so I got curious to see what that framework or library is, so I started exploring more on that.
Electron.js is a super cool framework if you are working on a product where you are mainly focusing on deep OS integration
, file handling
, or system monitoring
.
It has full Node.js access.
Let me explain the use cases if you want to choose between ReactJS and ElectronJS (Assuming most of the devs are using Reactjs π)
Electron:
- Directly Access the File System (Read, modify and delete local files.)
- Work with different extensions like .txt, .json, .csv and even images & videos.
VS
React (Web) is sandboxed and canβt interact with the file system beyond limited browser storage (IndexedDB, LocalStorage).
Electron:
- Execute Shell Commands & Automate Tasks: Run terminal commands like ls, mkdir, git, or even npm install.
- Automate repetitive tasks like downloading files, executing scripts, or launching apps.
VS
React apps canβt execute shell commands due to browser security restrictions.
Electron:
- System Monitoring & Hardware Control
- Get real-time CPU, RAM, and Disk usage.
- Monitor battery status, network activity, and system processes.
VS
React (Web) canβt access system-level data without a backend service.
But but but, that doesn't mean you need to use this, understand your requirements and then only choose.
I wanted to explore Electron using a cute theme, so I used a pixel-based image (of a living room) as a background. (You can use yours)
Sharing folder structure and my code how I did it. Try it out and let me know how it goes ππ
Features:
1) Write & save notes to a local file
2) Encrypt & decrypt notes for privacy
3) Fun UI with a "lock/unlock" effect
Install Electron
npm init -y
npm install electron
Run the app
npm electron .
Electron doesnβt hot-reload CSS like a browser.
You can use multiple ways to handle hot-reloading (electron-reloader/electron-reload), I am skipping going into detail in this blog for now.
Let's see the folder structure
index.html (handles frontend UI)
Fun UI with a Lock/Unlock Button
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Secret Notes ππ</title>
<style>
body {
text-align: center;
font-family: Arial, sans-serif;
background-color: #222;
color: white;
margin-top: 50px;
background: url("background.png") center center/cover;
}
textarea {
width: 80%;
height: 200px;
padding: 10px;
font-size: 16px;
}
button {
margin-top: 10px;
padding: 10px;
font-size: 16px;
cursor: pointer;
}
</style>
</head>
<body>
<h1>π Secret Notes</h1>
<textarea id="note" placeholder="Write your secret here..."></textarea><br>
<button id="saveBtn" style="border-radius: 25px; color:orange; border: 1px solid orange;">Save & Lock π</button>
<button id="loadBtn" style="border-radius: 25px; color:orange;border: 1px solid orange;">Unlock & Load π</button>
<script>
document.getElementById("saveBtn")?.addEventListener("click", async () => {
const noteText = document.getElementById("note").value;
await window?.electronAPI?.saveNote(noteText);
alert("Note saved & encrypted!");
document.getElementById("note").value = "";
});
document.getElementById("loadBtn")?.addEventListener("click", async () => {
const decryptedText = await window?.electronAPI?.loadNote();
if (decryptedText) {
document.getElementById("note").value = decryptedText;
alert("Note unlocked!");
} else {
alert("No saved note found!");
}
});
</script>
</body>
</html>
main.js (Electron Main Process)
- Handle File Read/Write with Encryption
- Create a main.js file to handle file operations securely.
const { app, BrowserWindow, ipcMain } = require("electron");
const fs = require("fs");
const path = require("path");
const CryptoJS = require("crypto-js");
let mainWindow;
app.whenReady().then(() => {
mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: false,
contextIsolation: true,
preload: path.join(__dirname, "preload.js"),
},
});
mainWindow.loadFile("index.html");
mainWindow.webContents.openDevTools();
});
// Secret key for encryption
const SECRET_KEY = "***"; // use your secret key
// Handle writing encrypted notes
ipcMain.handle("save-note", (_, text) => {
const encryptedText = CryptoJS.AES.encrypt(text, SECRET_KEY).toString();
fs.writeFileSync("secret-note.txt", encryptedText, "utf-8");
});
// Handle reading and decrypting notes
ipcMain.handle("load-note", () => {
if (fs.existsSync("secret-note.txt")) {
const encryptedText = fs.readFileSync("secret-note.txt", "utf-8");
const bytes = CryptoJS.AES.decrypt(encryptedText, SECRET_KEY);
return bytes.toString(CryptoJS.enc.Utf8);
}
return "";
});
package.json
{
"name": "fun-app",
"version": "1.0.0",
"description": "",
"main": "main.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"crypto-js": "^4.2.0",
"electron": "^35.1.2",
"fs": "^0.0.1-security",
"path": "^0.12.7"
},
"devDependencies": {
"nodemon": "^3.1.9"
}
}
preload.js (Securely Expose Functions)
const { contextBridge, ipcRenderer } = require("electron");
contextBridge.exposeInMainWorld("electronAPI", {
selectFile: () => ipcRenderer.invoke("select-file"),
saveNote: (text) => ipcRenderer.invoke("save-note", text),
loadNote: () => ipcRenderer.invoke("load-note"),
});
renderer.js (Handles frontend logic)
document.getElementById("selectFile").addEventListener("click", async () => {
try {
const filePath = await window.electron.selectFile(); // Use the exposed function
if (filePath) {
const audioPlayer = document.getElementById("audioPlayer");
audioPlayer.src = `file://${filePath}`;
audioPlayer.play();
}
} catch (error) {
console.error("Error selecting file:", error);
}
});
Finished product π€©
How to use this app?
Follow these steps
- Type any secret key of yours (Maybe your favourite song, dish, favourite series/movies, anything you like).
- Hit on Save & Lock (It will gets disappeared)
- Click on Unload & Load (It will reappear and you can play with it, change it if you want and then hit Save & Lock)
I hope you find the reason whether to try this framework or not as per the use case π―
Top comments (0)