.agents/skills/electron/SKILL.md
Electron framework for building cross-platform desktop applications with JavaScript, HTML, and CSS. Covers architecture, IPC, security, packaging, auto-updates, and backend integration patterns. USE WHEN: user mentions "Electron", "desktop app", "cross-platform application", asks about "IPC", "main process", "renderer process", "Electron packaging", "auto-updates", "code signing", "Electron security" DO NOT USE FOR: Tauri applications - use `tauri` skill instead
npx skillsauth add d-subrahmanyam/deno-fresh-microservices electronInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Deep Knowledge: Use
mcp__documentation__fetch_docswith technology:electronfor comprehensive API documentation.
tauri skill for Rust-based desktop apps┌─────────────────────────────────────────────────────────────┐
│ Main Process │
│ - Node.js Runtime (full access) │
│ - Electron APIs (app, BrowserWindow, ipcMain, dialog) │
└──────────────────────────┬──────────────────────────────────┘
│ IPC Channel
┌──────────────────────────▼──────────────────────────────────┐
│ Preload Script │
│ - Executes before renderer │
│ - Uses contextBridge to expose safe APIs │
└──────────────────────────┬──────────────────────────────────┘
│ contextBridge.exposeInMainWorld()
┌──────────────────────────▼──────────────────────────────────┐
│ Renderer Process │
│ - Chromium Runtime (standard Web APIs) │
│ - No direct Node.js access (by default) │
│ - window.electronAPI (exposed via preload) │
└─────────────────────────────────────────────────────────────┘
electron-app/
├── src/
│ ├── main/ # Main process
│ │ ├── index.ts # Entry point
│ │ ├── window.ts # Window management
│ │ ├── ipc/ # IPC handlers
│ │ └── updater.ts # Auto-updates
│ ├── preload/
│ │ ├── index.ts # Main preload
│ │ └── types.d.ts # Type declarations
│ └── renderer/ # Frontend app
├── resources/ # App icons
├── electron-builder.yml # Packaging config
└── package.json
// src/preload/index.ts
import { contextBridge, ipcRenderer } from 'electron';
const electronAPI = {
openFile: () => ipcRenderer.invoke('dialog:openFile'),
saveFile: (content: string) => ipcRenderer.invoke('dialog:saveFile', content),
getVersion: () => ipcRenderer.invoke('app:getVersion'),
};
contextBridge.exposeInMainWorld('electronAPI', electronAPI);
// Event subscriptions
contextBridge.exposeInMainWorld('electronEvents', {
onMenuAction: (callback: (action: string) => void) => {
const handler = (_e: any, action: string) => callback(action);
ipcRenderer.on('menu:action', handler);
return () => ipcRenderer.removeListener('menu:action', handler);
},
});
// src/main/ipc/index.ts
import { ipcMain, dialog, app } from 'electron';
export function registerIpcHandlers() {
ipcMain.handle('dialog:openFile', async () => {
const result = await dialog.showOpenDialog({
properties: ['openFile'],
});
return result.canceled ? null : result.filePaths[0];
});
ipcMain.handle('app:getVersion', () => app.getVersion());
}
Full Reference: See ipc-security.md for complete IPC patterns and type-safe setup.
const win = new BrowserWindow({
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
contextIsolation: true, // REQUIRED
nodeIntegration: false, // REQUIRED
sandbox: true, // Recommended
webSecurity: true, // NEVER disable
},
});
// Content Security Policy
win.webContents.session.webRequest.onHeadersReceived((details, callback) => {
callback({
responseHeaders: {
...details.responseHeaders,
'Content-Security-Policy': [
"default-src 'self'",
"script-src 'self'",
"connect-src 'self' https://api.example.com",
].join('; '),
},
});
});
contextIsolation: true - Isolate preload from renderernodeIntegration: false - No Node.js APIs in renderersandbox: true - OS-level process sandboxingipcRenderer to rendereripcMain.handle() handlerssafeStorage API for credentialsFull Reference: See ipc-security.md for complete security configuration.
appId: com.company.app
productName: My Application
mac:
hardenedRuntime: true
target: [dmg, zip]
win:
target: [nsis, portable]
linux:
target: [AppImage, deb]
publish:
provider: github
owner: company
repo: app
import { autoUpdater } from 'electron-updater';
autoUpdater.on('update-available', (info) => {
dialog.showMessageBox({
message: `Version ${info.version} available`,
buttons: ['Download', 'Later'],
}).then(({ response }) => {
if (response === 0) autoUpdater.downloadUpdate();
});
});
autoUpdater.on('update-downloaded', () => {
autoUpdater.quitAndInstall();
});
// Check on startup
autoUpdater.checkForUpdates();
Full Reference: See packaging.md for complete Forge and Builder configuration.
import Database from 'better-sqlite3';
import { app } from 'electron';
const db = new Database(path.join(app.getPath('userData'), 'app.db'));
db.pragma('journal_mode = WAL');
export const itemsRepo = {
getAll: () => db.prepare('SELECT * FROM items').all(),
create: (data) => db.prepare('INSERT INTO items (name) VALUES (?)').run(data.name),
};
import { safeStorage } from 'electron';
import Store from 'electron-store';
const store = new Store({ name: 'auth' });
export const tokenStore = {
setToken(token: string): void {
if (safeStorage.isEncryptionAvailable()) {
const encrypted = safeStorage.encryptString(token);
store.set('accessToken', encrypted.toString('base64'));
}
},
getToken(): string | null {
const stored = store.get('accessToken') as string;
if (safeStorage.isEncryptionAvailable()) {
return safeStorage.decryptString(Buffer.from(stored, 'base64'));
}
return stored;
},
};
Full Reference: See backend.md for embedded servers, offline-first patterns, and WebSocket integration.
| Metric | Warning | Critical | |--------|---------|----------| | Startup time | > 3s | > 5s | | Memory usage | > 300MB | > 500MB | | Crash rate | > 0.1% | > 1% |
| Anti-Pattern | Problem | Solution |
|--------------|---------|----------|
| nodeIntegration: true | Major security risk | Use contextIsolation: true + preload |
| webSecurity: false | Enables XSS | Never disable |
| Exposing raw ipcRenderer | Security hole | Use contextBridge.exposeInMainWorld() |
| No input validation | Injection attacks | Validate in ipcMain.handle() |
| Hardcoded credentials | Exposed in ASAR | Use safeStorage API |
| ipcRenderer.sendSync | Blocks renderer | Use async invoke() |
| Issue | Solution |
|-------|----------|
| require is not defined | Use preload with contextBridge |
| IPC returns undefined | Verify channel names match |
| White screen on startup | Check DevTools console |
| Auto-updater not checking | Ensure app is code-signed |
| High memory usage | Check for unbounded caches |
| App won't start on macOS | Complete notarization |
| File | Content | |------|---------| | ipc-security.md | Type-safe IPC, Security configuration | | packaging.md | Electron Forge, Builder, Auto-updates | | backend.md | SQLite, Express, Offline-first, WebSocket |
development
Guidelines for building high-performance APIs with Fastify and TypeScript, covering validation, Prisma integration, and testing best practices
development
FastAPI modern Python web framework. Covers routing, Pydantic models, dependency injection, and async support. Use when building Python APIs. USE WHEN: user mentions "fastapi", "pydantic", "async python api", "python rest api", asks about "dependency injection python", "python openapi", "python swagger", "async endpoints", "python api validation", "fastapi middleware" DO NOT USE FOR: Django apps - use `django` instead, Flask apps - use `flask` instead, synchronous Python APIs without type hints, GraphQL-only APIs
tools
FastAPI integration testing specialist. Covers synchronous TestClient, async httpx AsyncClient, dependency injection overrides, auth testing (JWT, OAuth2, API keys), WebSocket testing, file uploads, background tasks, middleware testing, and HTTP mocking with respx, responses, and pytest-httpserver. USE WHEN: user mentions "FastAPI test", "TestClient", "httpx async test", "dependency override test", "respx mock", asks about testing FastAPI endpoints, authentication in tests, or HTTP client mocking. DO NOT USE FOR: Django - use `pytest-django`; pytest internals - use `pytest`; Container infrastructure - use `testcontainers-python`
development
Expert in FastAPI Python development with best practices for APIs and async operations