Agent skill

Electron Dev

by jamditis in jamditis/claude-skills-journalism

Electron desktop apps with React, TypeScript, and Vite. An agent skill from jamditis/claude-skills-journalism.

MITAuto-check passed

Install Electron Dev

skills CLI
$ npx skills add jamditis/claude-skills-journalism --skill electron-dev -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install jamditis/claude-skills-journalism electron-dev --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/jamditis/claude-skills-journalism.git skills-src && mkdir -p .claude/skills && cp -r skills-src/dev-toolkit/skills/electron-dev .claude/skills/electron-dev && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
electron-dev
GitHub stars
416
Token cost
~2.9k tokens
SKILL.md length
523 words
Files
2
Skills in repo
53
Repo updated
First seen
Licence
MIT

At a glance

Electron desktop apps with React, TypeScript, and Vite. An agent skill from jamditis/claude-skills-journalism.

  • SKILL.md covers Security baseline (Electron 30+), Architecture patterns, System tray integration and Global shortcuts, plus 6 more sections
  • Calls npm and npx; needs APPLE_APP_SPECIFIC_PASSWORD and CSC_KEY_PASSWORD

What it does

Electron Dev is an agent skill from jamditis/claude-skills-journalism. Electron desktop apps with React, TypeScript, and Vite. Use for IPC, window/tray, PTY terminals, WebRTC, and packaging.

Its SKILL.md is about 2.9k tokens, which your agent loads only when the skill is triggered. The skill folder holds 2 other files (for example `agents/openai.yaml`).

It works with React, TypeScript and Vite. The repository describes itself as: Claude Code skills for journalism, media, and academia - verification, FOIA, data journalism, academic writing, and more. The licence is MIT.

Example prompts

  • “/electron-dev”

Requirements

  • Node.js

What it can do on your machine

Read from SKILL.md and the folder at commit e3e2172. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • npm
    • npx

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    Links to these hosts (documentation or services it may open):

    • electronjs.org

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names these keys or tokens, usually read from environment variables:

    • APPLE_APP_SPECIFIC_PASSWORD
    • CSC_KEY_PASSWORD

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Electron Dev loads about 2.9k tokens when it runs. Until then it costs about 33 tokens; SKILL.md has 523 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~33
When it runs · the whole SKILL.md, loaded when a task matches
~2.9k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from jamditis/claude-skills-journalism at commit e3e2172, republished under its MIT licence (© jamditis). 523 words, ~2,936 tokens.

Download SKILL.mdSave it as .claude/skills/electron-dev/SKILL.md (or your agent's skills folder). This skill also uses 1 other file; get the full folder from GitHub.
name
electron-dev
description
Electron desktop apps with React, TypeScript, and Vite. Use for IPC, window/tray, PTY terminals, WebRTC, and packaging.

Electron desktop development

Patterns and practices for building production-quality Electron applications with React and TypeScript.

Security baseline (Electron 30+)

Electron's defaults have hardened over the past several releases. As of Electron 28+, contextIsolation: true and sandbox: true are the defaults for new BrowserWindow instances, most security advice from older guides assumed you had to opt in. You don't anymore; you have to opt OUT, and you should not.

Set explicitly anyway, so a config drift never weakens the security model:

javascript
const win = new BrowserWindow({
  webPreferences: {
    contextIsolation: true,        // default since 12, mandatory for any prod app
    sandbox: true,                  // default since 28; renderer runs sandboxed
    nodeIntegration: false,         // never enable in renderer
    webSecurity: true,              // never disable
    preload: path.join(__dirname, 'preload.cjs')
  }
});

Validate every IPC message in main. Don't trust the renderer.

Electron Fuses + ASAR integrity

Electron Fuses are package-time toggles baked into the binary. The two relevant for security distribution:

  • EnableEmbeddedAsarIntegrityValidation, verifies the app.asar hash at runtime against a hash embedded in the binary. Defends against attackers swapping the asar contents post-install.
  • OnlyLoadAppFromAsar, refuses to load app code from anywhere except the validated asar.

These are opt-in, not default. Enable both for production. Requires @electron/asar 3.1.0+ to generate the asar with embeddable integrity. electron-builder configures this via electronFuses in the build config; @electron/fuses does it programmatically.

CVE-2023-44402 (ASAR integrity bypass via filetype confusion) was the canonical motivation here, without integrity + only-load-from-asar, an attacker who can modify app files can swap behavior silently.

Common renderer-side risks
  • Preload script confusion, only expose narrow, typed surfaces via contextBridge.exposeInMainWorld. Never re-export ipcRenderer itself; expose specific methods that map to specific channels.
  • file:// IPC and navigation, restrict navigation with webContents.on('will-navigate', e => e.preventDefault()) for windows that shouldn't change URL. Deny setWindowOpenHandler requests by default; allow-list specific origins.
  • shell.openExternal with user input, validate the URL scheme before opening. An attacker-controlled file:// or javascript: URL hands them code execution.

Architecture patterns

Project structure
app/
├── electron/
│   ├── main.cjs              # Main process (CommonJS required)
│   ├── preload.cjs           # Context bridge for secure IPC
│   └── server.cjs            # Optional: WebSocket/HTTP server
├── src/
│   ├── components/           # React components
│   ├── services/             # Business logic (API clients, Firebase)
│   ├── utils/                # Utilities (audio, formatting)
│   ├── types.ts              # TypeScript interfaces
│   ├── App.tsx               # Root component
│   └── index.tsx             # React entry
├── assets/                   # Icons, sounds, images
├── package.json
├── vite.config.ts
└── electron-builder.yml      # Build configuration
IPC communication pattern

Main process (main.cjs):

javascript
const { ipcMain } = require('electron');

// Handle async requests from renderer
ipcMain.handle('action-name', async (event, args) => {
  try {
    const result = await someAsyncOperation(args);
    return { success: true, data: result };
  } catch (error) {
    return { success: false, error: error.message };
  }
});

// Send data to renderer
mainWindow.webContents.send('event-name', data);

Preload script (preload.cjs):

javascript
const { contextBridge, ipcRenderer } = require('electron');

contextBridge.exposeInMainWorld('electron', {
  actionName: (args) => ipcRenderer.invoke('action-name', args),
  onEventName: (callback) => {
    const handler = (event, data) => callback(data);
    ipcRenderer.on('event-name', handler);
    return () => ipcRenderer.removeListener('event-name', handler);
  }
});

Renderer (React):

typescript
const result = await window.electron.actionName(args);

useEffect(() => {
  return window.electron.onEventName((data) => {
    setState(data);
  });
}, []);

System tray integration

javascript
const { Tray, Menu, nativeImage } = require('electron');

let tray = null;

function createTray() {
  const icon = nativeImage.createFromPath(path.join(__dirname, '../assets/tray-icon.png'));
  tray = new Tray(icon.resize({ width: 16, height: 16 }));

  tray.setToolTip('App Name');
  tray.setContextMenu(Menu.buildFromTemplate([
    { label: 'Show', click: () => mainWindow.show() },
    { label: 'Quit', click: () => app.quit() }
  ]));

  tray.on('click', () => {
    mainWindow.isVisible() ? mainWindow.hide() : mainWindow.show();
  });
}

// Hide to tray instead of closing
mainWindow.on('close', (event) => {
  if (!app.isQuitting) {
    event.preventDefault();
    mainWindow.hide();
  }
});

Global shortcuts

javascript
const { globalShortcut } = require('electron');

app.whenReady().then(() => {
  // Register with conflict detection
  const registered = globalShortcut.register('Alt+S', () => {
    mainWindow.webContents.send('shortcut-triggered', 'toggle-recording');
  });

  if (!registered) {
    console.error('Shortcut registration failed - conflict detected');
  }
});

app.on('will-quit', () => {
  globalShortcut.unregisterAll();
});

PTY terminal integration (node-pty)

javascript
const pty = require('node-pty');

const shell = process.platform === 'win32' ? 'powershell.exe' : process.env.SHELL || '/bin/bash';

const ptyProcess = pty.spawn(shell, [], {
  name: 'xterm-256color',
  cols: 80,
  rows: 24,
  cwd: process.env.HOME,
  env: process.env
});

ptyProcess.onData((data) => {
  mainWindow.webContents.send('terminal-data', { tabId, data });
});

ipcMain.on('terminal-write', (event, { tabId, data }) => {
  ptyProcess.write(data);
});

ipcMain.on('terminal-resize', (event, { tabId, cols, rows }) => {
  ptyProcess.resize(cols, rows);
});

Audio recording workflow

typescript
// Request microphone access
const stream = await navigator.mediaDevices.getUserMedia({
  audio: {
    echoCancellation: true,
    noiseSuppression: true,
    autoGainControl: true
  }
});

// Record audio
const mediaRecorder = new MediaRecorder(stream, { mimeType: 'audio/webm' });
const chunks: Blob[] = [];

mediaRecorder.ondataavailable = (e) => chunks.push(e.data);
mediaRecorder.onstop = async () => {
  const blob = new Blob(chunks, { type: 'audio/webm' });
  const base64 = await blobToBase64(blob);
  // Send to transcription API
};

mediaRecorder.start();
// Later: mediaRecorder.stop();

WebRTC patterns (PeerJS)

typescript
import Peer from 'peerjs';

const peer = new Peer(userId, {
  host: 'peerjs-server.com',
  port: 443,
  secure: true
});

// Answer incoming calls
peer.on('call', (call) => {
  call.answer(localStream);
  call.on('stream', (remoteStream) => {
    audioElement.srcObject = remoteStream;
  });
});

// Make outgoing calls
const call = peer.call(remoteUserId, localStream);
call.on('stream', (remoteStream) => {
  audioElement.srcObject = remoteStream;
});

// Screen sharing via replaceTrack (no renegotiation)
const screenStream = await navigator.mediaDevices.getDisplayMedia({ video: true });
const videoTrack = screenStream.getVideoTracks()[0];
const sender = peerConnection.getSenders().find(s => s.track?.kind === 'video');
await sender.replaceTrack(videoTrack);
Show full SKILL.md (223 more words)Show less

Build configuration (electron-builder.yml)

yaml
appId: com.yourname.appname
productName: AppName
directories:
  output: release

win:
  target:
    - target: nsis
      arch: [x64]
  icon: assets/icon.ico

nsis:
  oneClick: false
  allowToChangeInstallationDirectory: true
  installerIcon: assets/icon.ico
  uninstallerIcon: assets/icon.ico

mac:
  target:
    - target: dmg
      arch: [x64, arm64]
  icon: assets/icon.icns
  hardenedRuntime: true
  gatekeeperAssess: false
  entitlements: build/entitlements.mac.plist
  entitlementsInherit: build/entitlements.mac.plist
  notarize:
    teamId: YOUR_APPLE_TEAM_ID

linux:
  target:
    - target: AppImage
      arch: [x64]
  icon: assets/icon.png

publish:
  provider: github
  owner: username
  repo: repo-name

extraResources:
  - from: "node_modules/node-pty/build/Release/"
    to: "node-pty/"
    filter: ["*.node"]

macOS notarization is required for distribution outside the App Store; Gatekeeper blocks unnotarized apps on first launch. Set the env vars APPLE_ID, APPLE_APP_SPECIFIC_PASSWORD, and APPLE_TEAM_ID (or use an App Store Connect API key) before running npm run package. electron-builder ≥ 24.13 handles notarization natively via the mac.notarize field; older versions require the electron-notarize afterSign hook.

For Windows, code signing with an EV cert is increasingly necessary to avoid SmartScreen warnings. electron-builder reads CSC_LINK (PFX) and CSC_KEY_PASSWORD env vars.

Common pitfalls

Stale closures in callbacks:

typescript
// Problem: State is stale in async callbacks
const [state, setState] = useState(initialValue);
peer.on('call', () => {
  console.log(state); // Always shows initialValue
});

// Solution: Use refs for async callback access
const stateRef = useRef(state);
useEffect(() => { stateRef.current = state; }, [state]);
peer.on('call', () => {
  console.log(stateRef.current); // Current value
});

Context isolation security:

  • Never expose ipcRenderer directly to renderer
  • Always use contextBridge.exposeInMainWorld()
  • Validate all IPC arguments in main process
  • Use TypeScript interfaces for IPC contracts

BrowserView is deprecated, use WebContentsView:

BrowserView was deprecated in Electron 30 (April 2024) and the underlying implementation has been replaced. BrowserView still works as a compatibility shim over WebContentsView, but new code should target WebContentsView directly. The constructors take the same webPreferences shape, so the migration is mostly mechanical. The differences worth knowing:

  • WebContentsView is added via win.contentView.addChildView(view) instead of win.addBrowserView(view)
  • Sizing is via view.setBounds({x, y, width, height}), no setAutoResize. You wire your own resize handlers if you want auto-resize.
  • Z-order is the order of addChildView calls; removeChildView then re-addChildView to bring forward.
javascript
const { WebContentsView } = require('electron');

const view = new WebContentsView({
  webPreferences: { contextIsolation: true, sandbox: true }
});
view.webContents.loadURL('https://example.com');
mainWindow.contentView.addChildView(view);
view.setBounds({ x: 0, y: 80, width: 800, height: 520 });

See the official BrowserView → WebContentsView migration guide for edge cases (popups, devtools, focus management).

Cross-platform shell detection:

javascript
const shell = process.platform === 'win32'
  ? 'powershell.exe'
  : process.env.SHELL || '/bin/bash';

const shellArgs = process.platform === 'win32'
  ? ['-NoLogo']
  : [];

Development workflow

bash
# Development (hot reload)
npm run electron:dev

# Production build
npm run electron:build

# Run built app locally
npx electron dist/

# Package for distribution
npm run package

© jamditis, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 1 other file in dev-toolkit/skills/electron-dev of jamditis/claude-skills-journalism.

  • SKILL.md
  • agents/openai.yaml

Open the folder on GitHubat commit e3e2172

Compare with similar skills

Electron Dev next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Electron Dev compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Electron Dev this skilljamditis/claude-skills-journalism416—~2.9kAutomated safety check: PassMIT
Web Artifacts Builderanthropics/skills180k40 repos~769Automated safety check: PassApache-2.0
Design To CodeMigoXLab/coderio1142 repos~1.2kAutomated safety check: PassApache-2.0
South Admin CRUD Generatorsouthliu/south-admin-react580—~1.7kAutomated safety check: PassMIT
Beautiful ArticleConardLi/garden-skills13k—~4.7kAutomated safety check: PassMIT
Local Testinglobehub/lobe-ui2.2k—~2.1kAutomated safety check: PassMIT

Similar skills

  • Web Artifacts Builder

    anthropics/skills

    Official

    Builds multi-component claude.ai HTML artifacts as a small React, TypeScript and Tailwind project, then bundles it into one shareable HTML file.

    180k GitHub starsUsed in 40 repos~769 tokens
    Frontend & DesignAuto-check passed
  • Design To Code

    MigoXLab/coderio

    Pixel-perfect Figma to React conversion using coderio. An agent skill from MigoXLab/coderio.

    114 GitHub starsUsed in 2 repos~1.2k tokens
    Frontend & DesignAuto-check passed
  • South Admin CRUD Generator

    southliu/south-admin-react

    Generates a full CRUD page - page component, data model and API client - from the south-admin-react project's own VS Code snippet templates.

    580 GitHub stars~1.7k tokensUpdated 17 days ago
    Frontend & DesignAuto-check passed
  • Beautiful Article

    ConardLi/garden-skills

    Turns a URL, PDF, DOCX, Markdown file, text or screenshots into a designed, shareable single-file HTML article through a staged review workflow.

    13k GitHub stars~4.7k tokensUpdated 2 mo ago
    Documents & OfficeAuto-check passed
  • Local Testing

    lobehub/lobe-ui

    Local browser verification for the lobe-ui component library and documentation site.

    2.2k GitHub stars~2.1k tokensUpdated today
    Frontend & DesignAuto-check passed
  • Wayfinder Development

    slimani-dev/muraqib

    A skill your agent uses for Laravel Wayfinder which auto-generates typed functions for Laravel controllers and routes.

    128 GitHub starsUsed in 1 repo~622 tokens
    Backend & APIsAuto-check passed

More from jamditis/claude-skills-journalism

All 53 skills in this repo
  • Web Design Picker

    jamditis/claude-skills-journalism

    A skill your agent uses when creating distinct website directions, a client review picker, asset catalog, previews, and Cloudflare-ready handoffs.

    416 GitHub stars~3.1k tokensUpdated 3 days ago
    Auto-check passed
  • Okf Wiki

    jamditis/claude-skills-journalism

    Builds an Open Knowledge Format (OKF) knowledge base from existing docs, notes, or a repo.

    416 GitHub stars~4.7k tokensUpdated 3 days ago
    Auto-check passed
  • Private Secret Scanning

    jamditis/claude-skills-journalism

    Local Gitleaks scans for staged changes, push ranges, and full history in private repos, with redacted reports.

    416 GitHub stars~1.8k tokensUpdated 3 days ago
    Auto-check passed
  • Data Journalism

    jamditis/claude-skills-journalism

    Acquire, clean, analyze, verify, visualize, and explain data for journalism.

    416 GitHub stars~1.6k tokensUpdated 3 days ago
    Auto-check passed
  • Document Design

    jamditis/claude-skills-journalism

    Creates print-ready HTML that exports to PDF. An agent skill from jamditis/claude-skills-journalism.

    416 GitHub stars~1.9k tokensUpdated 3 days ago
    Auto-check passed
  • Using Superjawn

    jamditis/claude-skills-journalism

    Establishes how to find and use skills, requiring Skill tool invocation before any response.

    416 GitHub stars~1.5k tokensUpdated 3 days ago
    Auto-check passed

Questions about Electron Dev

What does Electron Dev do?

Electron desktop apps with React, TypeScript, and Vite. An agent skill from jamditis/claude-skills-journalism. Electron Dev is an agent skill from jamditis/claude-skills-journalism. Electron desktop apps with React, TypeScript, and Vite.

How do I install Electron Dev in Claude Code?

Run `npx skills add jamditis/claude-skills-journalism --skill electron-dev -a claude-code`. Or copy the skill folder (dev-toolkit/skills/electron-dev in jamditis/claude-skills-journalism) into .claude/skills/electron-dev in your project. Claude Code loads it when a task matches its description.

How do I install Electron Dev in Codex?

Run `npx skills add jamditis/claude-skills-journalism --skill electron-dev -a codex`. Or copy the skill folder (dev-toolkit/skills/electron-dev in jamditis/claude-skills-journalism) into .agents/skills/electron-dev in your project. Codex loads it when a task matches its description.

Can I use Electron Dev in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add jamditis/claude-skills-journalism --skill electron-dev -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/electron-dev, .gemini/skills/electron-dev, .github/skills/electron-dev and .opencode/skills/electron-dev in your project.

What does Electron Dev need to run?

Going by SKILL.md and its folder, Electron Dev needs the command-line tools its instructions call (npm and npx) and credentials named APPLE_APP_SPECIFIC_PASSWORD and CSC_KEY_PASSWORD. Our summary lists: Node.js.

Does Electron Dev access the network?

SKILL.md names 1 domain. As links in the text: electronjs.org. This is read from the text; nothing was executed.

Is Electron Dev safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Electron Dev use?

Electron Dev is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Electron Dev use?

About 2.9k tokens (SKILL.md is roughly 12k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Electron Dev?

Skills that share tags, products or a category with Electron Dev: Web Artifacts Builder (anthropics/skills, 180k stars), Design To Code (MigoXLab/coderio, 114 stars), South Admin CRUD Generator (southliu/south-admin-react, 580 stars) and Beautiful Article (ConardLi/garden-skills, 13k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Electron Dev?

jamditis (a GitHub user) maintains it in jamditis/claude-skills-journalism, which has 416 GitHub stars. The repository holds 53 skills in this directory. The repository was last updated on October 4, 2026.

Source: jamditis/claude-skills-journalism on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.