Expert in building cross-platform desktop applications using web technologies (HTML/CSS/JS) with the Electron framework.
60
68%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
Fix and improve this skill with Tessl
tessl review fix ./.agents/skills/electron-pro/SKILL.mdProvides cross-platform desktop application development expertise specializing in Electron, IPC architecture, and OS-level integration. Builds secure, performant desktop applications using web technologies with native capabilities for Windows, macOS, and Linux.
How to structure the app?
│
├─ **Security First (Recommended)**
│ ├─ Context Isolation? → **Yes** (Standard since v12)
│ ├─ Node Integration? → **No** (Never in Renderer)
│ └─ Preload Scripts? → **Yes** (Bridge API)
│
├─ **Data Persistence**
│ ├─ Simple Settings? → **electron-store** (JSON)
│ ├─ Large Datasets? → **SQLite** (`better-sqlite3` in Main process)
│ └─ User Files? → **Native File System API**
│
└─ **UI Framework**
├─ React/Vue/Svelte? → **Yes** (Standard SPA approach)
├─ Multiple Windows? → **Window Manager Pattern**
└─ System Tray App? → **Hidden Window Pattern**| Pattern | Method | Use Case |
|---|---|---|
| One-Way (Renderer → Main) | ipcRenderer.send | logging, analytics, minimizing window |
| Two-Way (Request/Response) | ipcRenderer.invoke | DB queries, file reads, heavy computations |
| Main → Renderer | webContents.send | Menu actions, system events, push notifications |
Red Flags → Escalate to security-auditor:
nodeIntegration: true in productioncontextIsolationhttps://) without strict CSPremote module (Deprecated & insecure)Goal: Reduce launch time to < 2s.
Steps:
V8 Snapshot
electron-link or v8-compile-cache to pre-compile JS.Lazy Loading Modules
require() everything at top of main.ts.// Bad
import { heavyLib } from "heavy-lib";
// Good
ipcMain.handle("do-work", () => {
const heavyLib = require("heavy-lib");
heavyLib.process();
});Bundle Main Process
esbuild or webpack for Main process (not just Renderer) to tree-shake unused code and minify.Use case: Image processing or parsing large files without freezing the UI.
// main.ts
import { Worker } from "worker_threads";
ipcMain.handle("process-image", (event, data) => {
return new Promise((resolve, reject) => {
const worker = new Worker("./worker.js", { workerData: data });
worker.on("message", resolve);
worker.on("error", reject);
});
});Use case: Opening app from browser (myapp://open?id=123).
// main.ts
if (process.defaultApp) {
if (process.argv.length >= 2) {
app.setAsDefaultProtocolClient("myapp", process.execPath, [
path.resolve(process.argv[1]),
]);
}
} else {
app.setAsDefaultProtocolClient("myapp");
}
app.on("open-url", (event, url) => {
event.preventDefault();
// Parse url 'myapp://...' and navigate renderer
mainWindow.webContents.send("navigate", url);
});app-region: drag.9bae718
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.