Install
$ agentstack add skill-ohvignas-claude-electron-skills-performance ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ● Filesystem access Used
- ● Shell / process execution Used
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Electron Performance
Overview
Electron ships a full Chromium + Node.js runtime, so performance problems are almost always self-inflicted: heavy work runs on the main process (the UI thread) or at startup before the user needs it. The mental model: measure first, defer everything you can, and never block the process that paints the window.
When to use
- Cold start is slow; the splash/window takes seconds to appear.
- The window freezes, beach-balls, or stops responding to clicks while a task runs.
- High memory or CPU at idle; a
require()of one module spikes startup. - You want to offload CPU-heavy work (parsing, crypto, image/PDF processing) off the main process.
- You're auditing bundle/
node_modulessize or considering V8 startup snapshots.
When NOT to use: for rendering jank caused by layout/paint, profile in the renderer's DevTools Performance tab first; for crashes/OOM kills see crash-diagnostics.
Quick reference
| Symptom / goal | Fix | |---|---| | Don't know what's slow | Profile first: node --cpu-prof --heap-prof -e "require('module')", then DevTools | | Heavy module loaded but rarely used | Move require() out of top level into the function that uses it (lazy require) | | Main process frozen | Offload CPU work to utilityProcess.fork(), worker_threads, or a BrowserWindow | | Sync I/O on main | Use async (fs.promises.readFile not fs.readFileSync); avoid sync IPC & @electron/remote | | Renderer jank | requestIdleCallback() for low-priority work; Web Worker for CPU loops | | Slow polyfills | Target latest ES; drop jQuery/polyfills Chromium already ships | | Network on startup | Bundle static fonts/icons/data; audit with DevTools Network tab | | Many require() calls | Bundle with Webpack/Parcel/rollup so the cost is paid once | | Default menu overhead | Menu.setApplicationMenu(null) before app is ready if you use a custom/frameless menu | | Shrink startup heap | V8 startup snapshot (v8_context_snapshot.bin via electron-mksnapshot) |
Example
Before/after: a parse-heavy module loaded eagerly on the main process froze the window. After, it's lazily required inside a utilityProcess so the main thread stays free.
// main.js — AFTER
const { app, BrowserWindow, utilityProcess } = require('electron')
const path = require('node:path')
function createWindow () {
const win = new BrowserWindow({ width: 900, height: 600 })
win.loadFile('index.html')
return win
}
app.whenReady().then(() => {
const win = createWindow()
// CPU-heavy parsing is forked into a Node child process backed by
// Chromium's Services API — it runs OFF the main process, so the
// window never freezes. modulePath is resolved relative to main.
const child = utilityProcess.fork(path.join(__dirname, 'parser.js'))
child.on('message', (result) => {
// Result arrives async; UI stayed responsive the whole time.
win.webContents.send('parsed', result)
})
child.postMessage({ file: '/path/to/huge.csv' })
})
// parser.js (the utility process) — heavy require() lives HERE, not on main.
process.parentPort.on('message', (e) => {
// Lazy require: the 100k-line dependency is only loaded when work arrives,
// and inside the child process — never blocking app startup.
const { parse } = require('some-heavy-parser')
const rows = parse(require('node:fs').readFileSync(e.data.file, 'utf8'))
process.parentPort.postMessage(rows.length)
})
Common mistakes
- Profiling by guessing. The docs are explicit: measure before optimizing. A "fast" module can pull a 100k-line JSON on
require(). require()at the top ofmain.jsfor everything. Top-level requires run at startup whether or not the feature is used. Defer them.- Doing CPU work on the main process (or via sync IPC /
@electron/remote). It blocks the UI thread for every window. UseutilityProcess/worker_threads. - Synchronous Node APIs (
fs.readFileSync,child_process.execSync) on the main process — always prefer thefs.promises/ async variant. - Shipping
devDependencies& unusednode_modulesinto the package — they bloat install size andrequire()graphs. Bundle and prune.
Reference
Full API tables: [reference.md](reference.md)
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: ohvignas
- Source: ohvignas/claude-electron-skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.