Skip to content
Web apps

Electron desktop app rules

Electron rules for agents: sandboxed renderers, narrow contextBridge APIs, sender-checked IPC, deny-by-default windows, CSP and fuses, with a static security check.

Verified install Not agent-tested v1.0.0 MIT updated electrondesktoptypescriptnodejs
Equips
  • 1 1 Rules
  • 1 1 Skills
  • – 0 MCP

Agents build Electron apps that work and then turn off the protections to make a feature easier: nodeIntegration on, contextIsolation off, ipcRenderer handed straight to the page, shell.openExternal on whatever URL arrives. This loadout writes the Electron security checklist into rules your agent follows, and ships a skill for adding IPC channels the safe way: a named preload function, a fixed channel, an ipcMain.handle that checks event.senderFrame and validates every argument. A small static check catches the common regressions. The verifier type-checks the examples against Electron 44's types and runs the check on a good and an insecure app.

What's in it

  • contextIsolation, sandbox and nodeIntegration written out, never weakened
  • IPC through named preload functions; handlers check senderFrame and validate input
  • Custom app:// protocol instead of file://; deny-by-default window and navigation handlers
  • Fuses flipped at package time with @electron/fuses
  • Static check mapped to the numbered Electron security checklist

You'll need

  • Tools: node, npm
Level 1 · automated

Verification

Verified install

Checked at commit 021470d · 9 passed, 0 failed, 1 not applicable

CheckResultWhat we found
Listinglisting.yaml matches the schema and declares every file in the folder. Pass
Schema valid; 9 files declared, none missing or extra
  • tested.status: untested (agent tests are separate from Level 1)
Files parseJSON parses; SKILL.md and .mdc front matter is valid YAML with the fields each agent needs; code fences are closed. Pass All 9 files parse; front matter valid
AdaptersCLAUDE.md imports @AGENTS.md, GEMINI.md imports @./AGENTS.md, and both match the generator. Pass
CLAUDE.md and GEMINI.md import AGENTS.md and are up to date
  • CLAUDE.md: matches the generator
  • GEMINI.md: matches the generator
Install pathsEvery file lands where each agent documents it, with no collisions, and the laid-out project is re-discovered correctly. Pass
Correct paths for all 6 agents; layouts re-discovered
  • Claude Code: 8 files, 1 skill in .claude/skills/
  • Codex CLI: 7 files, 1 skill in .agents/skills/
  • Cursor: 7 files, 1 skill in .agents/skills/
  • Gemini CLI: 8 files, 1 skill in .agents/skills/
  • Antigravity CLI: 7 files, 1 skill in .agents/skills/
  • GitHub Copilot: 7 files, 1 skill in .agents/skills/
MCP configmcp.json is structurally valid, converts to each agent's format, declares no literal secrets, and referenced packages exist on npm/PyPI. Not applicable No MCP servers in this loadout
Safety scanThe intake scanner finds no credentials, risky shell, hidden Unicode or prompt-injection wording, and the listing's network flag is honest. Pass
Clean: no credentials, risky shell or hidden text
  • Scanner intake-precheck/1: verdict clean; network yes (listing says yes)
ReferencesLinks and file paths between the loadout's files resolve, including for each agent's installed layout. Pass 2 references between files resolve for every agent
Size limitsFile count and sizes are within the submission limits; SKILL.md bodies stay under 500 lines. Pass
9 files, 13.1 KB total; largest skills/electron-ipc-channel/scripts/check_electron_security.mjs 4.3 KB
  • Limits: 30 files, 32 KB per file, 128 KB total, 500 lines per skill or rule
LicenceA recognised SPDX licence, with the licence text available. Pass MIT, by Agent Loadout; text in the repository LICENSE
Starter buildA minimal fixture project with the loadout applied installs and builds or type-checks, and the loadout's own code examples compile. Pass
The electron-ipc-channel skill's main, preload and fuses examples type-check against Electron 44's own types, pass the security check, and the check reports all 11 problems in an insecure app
  • Applied 15 loadout files at every agent's paths
  • ✓ place the examples: bash -c mkdir -p src && cp .agents/skills/electron-ipc-channel/references/*.ts src/ && cp good-html/index.html src/ && echo placed
  • ✓ install (no Electron binary download): npm ci --no-audit --no-fund
  • ✓ tsc --noEmit (strict, Electron 44 types): npm run check
  • ✓ security check passes the examples: node .agents/skills/electron-ipc-channel/scripts/check_electron_security.mjs src
  • ✓ security check catches an insecure app: bash -c node .claude/skills/electron-ipc-channel/scripts/check_electron_security.mjs bad; test $? -eq 1 && echo caught
  • Covers: contextIsolation, sandbox and nodeIntegration written out; custom app:// protocol instead of file://
  • Covers: Narrow contextBridge API with fixed channel names; typed window API
  • Covers: ipcMain.handle with senderFrame origin check and argument validation
  • Covers: setWindowOpenHandler deny-by-default, https-only openExternal, will-navigate guard
  • Covers: @electron/fuses hardening typed against the real package

What this means: a script checked the files themselves: they parse, they install where each agent looks, any MCP config is sound, the safety scan is clean, references between files resolve, and, where a free and repeatable fixture exists, a small starter project builds with the loadout applied. No AI agent was run. Per-agent results ("tested with agent") are separate and stay untested until an agent actually runs.

Install

Choose your agent. Run the commands from your project root, or download a zip already laid out in the right folders.

Claude Code reads CLAUDE.md (imports AGENTS.md with @AGENTS.md) and skills from .claude/skills/.

Download zip
curl -fsSL --create-dirs -o AGENTS.md https://loadout.jnw-it.com/raw/electron-app/1.0.0/AGENTS.md
curl -fsSL --create-dirs -o CLAUDE.md https://loadout.jnw-it.com/raw/electron-app/1.0.0/CLAUDE.md
curl -fsSL --create-dirs -o .claude/skills/electron-ipc-channel/SKILL.md https://loadout.jnw-it.com/raw/electron-app/1.0.0/skills/electron-ipc-channel/SKILL.md
curl -fsSL --create-dirs -o .claude/skills/electron-ipc-channel/references/main.ts https://loadout.jnw-it.com/raw/electron-app/1.0.0/skills/electron-ipc-channel/references/main.ts
curl -fsSL --create-dirs -o .claude/skills/electron-ipc-channel/references/preload.ts https://loadout.jnw-it.com/raw/electron-app/1.0.0/skills/electron-ipc-channel/references/preload.ts
curl -fsSL --create-dirs -o .claude/skills/electron-ipc-channel/references/renderer-api.d.ts https://loadout.jnw-it.com/raw/electron-app/1.0.0/skills/electron-ipc-channel/references/renderer-api.d.ts
curl -fsSL --create-dirs -o .claude/skills/electron-ipc-channel/references/flip-fuses.ts https://loadout.jnw-it.com/raw/electron-app/1.0.0/skills/electron-ipc-channel/references/flip-fuses.ts
curl -fsSL --create-dirs -o .claude/skills/electron-ipc-channel/scripts/check_electron_security.mjs https://loadout.jnw-it.com/raw/electron-app/1.0.0/skills/electron-ipc-channel/scripts/check_electron_security.mjs
FileGoes to
AGENTS.mdAGENTS.md
CLAUDE.mdCLAUDE.md
skills/electron-ipc-channel/SKILL.md.claude/skills/electron-ipc-channel/SKILL.md
skills/electron-ipc-channel/references/main.ts.claude/skills/electron-ipc-channel/references/main.ts
skills/electron-ipc-channel/references/preload.ts.claude/skills/electron-ipc-channel/references/preload.ts
skills/electron-ipc-channel/references/renderer-api.d.ts.claude/skills/electron-ipc-channel/references/renderer-api.d.ts
skills/electron-ipc-channel/references/flip-fuses.ts.claude/skills/electron-ipc-channel/references/flip-fuses.ts
skills/electron-ipc-channel/scripts/check_electron_security.mjs.claude/skills/electron-ipc-channel/scripts/check_electron_security.mjs

Already have an AGENTS.md or CLAUDE.md? The commands above overwrite it — download the file instead and merge the sections you want.

Files

Rules AGENTS.md Electron rules for windows, preload, IPC, packaging and dependencies. 42 lines
Download Raw
# AGENTS.md: Electron desktop app

Electron app: a privileged main process (Node.js) and renderer processes that show web content. Treat every renderer
as untrusted web content, even when it only loads your own bundle. Follow the Electron security checklist.

## Commands
- Check the project's `package.json` scripts first. Typical: `npm start` (dev), `npm test`, `npm run make` or
  `npm run dist` (packaging).
- Type-check with `npx tsc --noEmit` if the project uses TypeScript.
- Before finishing, run the `electron-ipc-channel` skill's security check (`scripts/check_electron_security.mjs` in the
  skill folder) over `src/`. It must report no findings.

## Windows (BrowserWindow and webPreferences)
- Keep the secure defaults and write them out so reviews can see them: `contextIsolation: true`, `sandbox: true`,
  `nodeIntegration: false`. Never set `webSecurity: false`, `allowRunningInsecureContent: true`,
  `experimentalFeatures: true` or `enableBlinkFeatures`.
- Load local pages from a custom protocol (`protocol.handle`) or the packaged file, never remote code into a window
  with a preload.
- Set `webContents.setWindowOpenHandler` to deny by default and open allowed links with `shell.openExternal` only
  after checking the URL scheme is `https:` (or a small allow-list).
- Handle `will-navigate` and block navigation away from the app's origin.
- Define a Content Security Policy (meta tag or response header): `default-src 'self'`, no `unsafe-eval`.

## Preload and IPC
- The preload exposes small, named functions through `contextBridge.exposeInMainWorld`. Never expose `ipcRenderer`,
  `require`, `process` or a generic "send any channel" function.
- Main uses `ipcMain.handle` for request/response. Every handler checks `event.senderFrame` (origin allow-list) and
  validates its arguments before doing anything.
- Do privileged work (files, shell, network with credentials) in main, never in the renderer.
- New channels: use the `electron-ipc-channel` skill.

## Packaging and updates
- Flip fuses at package time with `@electron/fuses`: `RunAsNode` off, `EnableNodeOptionsEnvironmentVariable` off,
  `EnableNodeCliInspectArguments` off, `EnableEmbeddedAsarIntegrityValidation` on, `OnlyLoadAppFromAsar` on,
  `EnableCookieEncryption` on.
- Stay on a supported Electron major. Ask before upgrading a major version; read the breaking changes first.
- Do not sign, notarise, publish or upload builds unless the user asks. Never commit signing certificates or tokens.

## Dependencies
- Ask before adding a dependency. Pin exact versions for anything that runs in main.
- No `@electron/remote`. No native modules unless needed and rebuilt for the Electron version.
Adapter CLAUDE.md Imports AGENTS.md for Claude Code. 10 lines
Download Raw
# CLAUDE.md

@AGENTS.md

## Claude Code notes
- Skills from this loadout live in `.claude/skills/`: `electron-ipc-channel`. Use them when their description matches the task.
- Follow AGENTS.md above; where this file and AGENTS.md disagree, AGENTS.md wins.

<!-- From the Agent Loadout "Electron desktop app rules" v1.0.0 — https://loadout.jnw-it.com/loadouts/electron-app/ -->
Adapter GEMINI.md Imports AGENTS.md for Gemini CLI. 10 lines
Download Raw
# GEMINI.md

@./AGENTS.md

## Gemini CLI notes
- Skills from this loadout live in `.agents/skills/`: `electron-ipc-channel`. Use them when their description matches the task.
- Follow AGENTS.md above; where this file and AGENTS.md disagree, AGENTS.md wins.

<!-- From the Agent Loadout "Electron desktop app rules" v1.0.0 — https://loadout.jnw-it.com/loadouts/electron-app/ -->
Skill skills/electron-ipc-channel/SKILL.md Add a typed, sender-checked IPC channel. 21 lines
Download Raw
---
name: electron-ipc-channel
description: Add a typed IPC channel between an Electron renderer and the main process, with a narrow preload API, sender validation and argument checks, then run the security check.
---

# Add an IPC channel

The examples are in `references/`: `main.ts`, `preload.ts` and `renderer-api.d.ts`. Copy the pattern, not the
names.

1. Name the operation after what the user does (`notes:save`), not a generic verb (`send`, `invoke`).
2. Preload: add one function to the object passed to `contextBridge.exposeInMainWorld`. It calls
   `ipcRenderer.invoke` with a fixed channel name and passes only the arguments it needs. Never pass `ipcRenderer`
   itself, an event object, or a channel name chosen by the renderer.
3. Types: add the function to the `window` API declaration so the renderer gets type checking.
4. Main: register `ipcMain.handle(channel, handler)`. In the handler, first call `assertTrustedSender(event)`,
   which checks `event.senderFrame?.origin` against the app's own origin, then validate every argument (type, length,
   allowed values). Throw on bad input; Electron passes the error message to the renderer's promise.
5. Keep the work in main and return plain data (no class instances, functions or Electron objects).
6. Run `node scripts/check_electron_security.mjs src` and fix every finding. Run the type-check.
Skill file skills/electron-ipc-channel/references/main.ts Main process: window, protocol, IPC handlers. 83 lines
Download Raw
import { app, BrowserWindow, ipcMain, net, protocol, shell, type IpcMainInvokeEvent } from "electron";
import { join, normalize, sep } from "node:path";
import { pathToFileURL } from "node:url";

const APP_ORIGIN = "app://bundle";
const MAX_NOTE_CHARS = 10_000;
const RENDERER_DIR = join(__dirname, "renderer");
const notes = new Map<string, string>();

// Serve the bundle from app://bundle/ instead of file://, so only files under RENDERER_DIR are reachable.
protocol.registerSchemesAsPrivileged([{ scheme: "app", privileges: { standard: true, secure: true, supportFetchAPI: true } }]);

function serveBundle(request: Request): Promise<Response> | Response {
  const file = normalize(join(RENDERER_DIR, decodeURIComponent(new URL(request.url).pathname)));
  if (!file.startsWith(RENDERER_DIR + sep)) return new Response("not found", { status: 404 });
  return net.fetch(pathToFileURL(file).toString());
}

function assertTrustedSender(event: IpcMainInvokeEvent): void {
  const origin = event.senderFrame?.origin;
  if (origin !== APP_ORIGIN) throw new Error(`untrusted IPC sender: ${origin ?? "unknown"}`);
}

function parseNoteId(value: unknown): string {
  if (typeof value !== "string" || !/^[a-z0-9-]{1,64}$/.test(value)) throw new Error("invalid note id");
  return value;
}

ipcMain.handle("notes:save", (event, id: unknown, text: unknown) => {
  assertTrustedSender(event);
  const noteId = parseNoteId(id);
  if (typeof text !== "string" || text.length > MAX_NOTE_CHARS) throw new Error("invalid note text");
  notes.set(noteId, text);
  return { id: noteId, savedAt: new Date().toISOString() };
});

ipcMain.handle("notes:load", (event, id: unknown) => {
  assertTrustedSender(event);
  return notes.get(parseNoteId(id)) ?? null;
});

function isAllowedExternal(url: string): boolean {
  try {
    return new URL(url).protocol === "https:";
  } catch {
    return false;
  }
}

function createWindow(): BrowserWindow {
  const win = new BrowserWindow({
    width: 1000,
    height: 700,
    webPreferences: {
      preload: join(__dirname, "preload.js"),
      contextIsolation: true,
      sandbox: true,
      nodeIntegration: false,
    },
  });
  win.webContents.setWindowOpenHandler(({ url }) => {
    if (isAllowedExternal(url)) void shell.openExternal(url);
    return { action: "deny" };
  });
  win.webContents.on("will-navigate", (event, url) => {
    if (!url.startsWith(`${APP_ORIGIN}/`)) event.preventDefault();
  });
  void win.loadURL(`${APP_ORIGIN}/index.html`);
  return win;
}

void app.whenReady().then(() => {
  protocol.handle("app", serveBundle);
  createWindow();
  app.on("activate", () => {
    if (BrowserWindow.getAllWindows().length === 0) createWindow();
  });
});

app.on("window-all-closed", () => {
  if (process.platform !== "darwin") app.quit();
});
Skill file skills/electron-ipc-channel/references/preload.ts Narrow contextBridge API. 13 lines
Download Raw
import { contextBridge, ipcRenderer } from "electron";

// Small, named functions only. The renderer never sees ipcRenderer or picks a channel name.
const api = {
  saveNote: (id: string, text: string): Promise<{ id: string; savedAt: string }> =>
    ipcRenderer.invoke("notes:save", id, text),
  loadNote: (id: string): Promise<string | null> => ipcRenderer.invoke("notes:load", id),
};

export type NotesApi = typeof api;

contextBridge.exposeInMainWorld("notes", api);
Skill file skills/electron-ipc-channel/references/renderer-api.d.ts Window API types for the renderer. 10 lines
Download Raw
import type { NotesApi } from "./preload";

declare global {
  interface Window {
    notes: NotesApi;
  }
}

export {};
Skill file skills/electron-ipc-channel/references/flip-fuses.ts Fuses hardening for packaged builds. 18 lines
Download Raw
// Run after packaging and before code signing, e.g. from an electron-builder afterPack hook
// or an Electron Forge packageAfterCopy hook. Pass the path to the packaged Electron binary.
import { flipFuses, FuseV1Options, FuseVersion } from "@electron/fuses";

export async function hardenBinary(electronBinary: string, macArm64: boolean): Promise<void> {
  await flipFuses(electronBinary, {
    version: FuseVersion.V1,
    resetAdHocDarwinSignature: macArm64,
    [FuseV1Options.RunAsNode]: false,
    [FuseV1Options.EnableCookieEncryption]: true,
    [FuseV1Options.EnableNodeOptionsEnvironmentVariable]: false,
    [FuseV1Options.EnableNodeCliInspectArguments]: false,
    [FuseV1Options.EnableEmbeddedAsarIntegrityValidation]: true,
    [FuseV1Options.OnlyLoadAppFromAsar]: true,
    [FuseV1Options.GrantFileProtocolExtraPrivileges]: false,
  });
}
Skill file skills/electron-ipc-channel/scripts/check_electron_security.mjs Static check against the Electron security checklist. 81 lines
Download Raw
#!/usr/bin/env node
// Static checks from the Electron security checklist. Pattern-based: it reads files, it runs nothing.
// Usage: node check_electron_security.mjs <dir> [more dirs]
// Exit 1 if anything is found. Checks .js/.mjs/.cjs/.ts/.tsx and .html files, skipping node_modules and build output.
import { readdirSync, readFileSync, statSync } from "node:fs";
import { join, relative } from "node:path";

const SKIP = new Set(["node_modules", "dist", "out", "build", ".git", ".vite", "release"]);
const CODE = /\.(?:[cm]?js|tsx?)$/;

function walk(dir, files = []) {
  for (const name of readdirSync(dir)) {
    if (SKIP.has(name)) continue;
    const p = join(dir, name);
    if (statSync(p).isDirectory()) walk(p, files);
    else if (CODE.test(name) || name.endsWith(".html")) files.push(p);
  }
  return files;
}

const LINE_RULES = [
  [/\bnodeIntegration(?:InWorker|InSubFrames)?\s*:\s*true/, "nodeIntegration enabled: renderer code gets Node.js (checklist 2)"],
  [/\bcontextIsolation\s*:\s*false/, "contextIsolation disabled (checklist 3)"],
  [/\bsandbox\s*:\s*false/, "sandbox disabled (checklist 4)"],
  [/\bwebSecurity\s*:\s*false/, "webSecurity disabled (checklist 6)"],
  [/\ballowRunningInsecureContent\s*:\s*true/, "allowRunningInsecureContent enabled (checklist 8)"],
  [/\bexperimentalFeatures\s*:\s*true/, "experimentalFeatures enabled (checklist 9)"],
  [/\benableBlinkFeatures\s*:/, "enableBlinkFeatures used (checklist 10)"],
  [/\ballowpopups\b/, "allowpopups on a webview (checklist 11)"],
  [/@electron\/remote|\benableRemoteModule\s*:\s*true/, "remote module: renderer reaches main objects directly"],
  [/exposeInMainWorld\([^)]*\bipcRenderer\b\s*\)/, "ipcRenderer exposed to the renderer (checklist 20)"],
  [/exposeInMainWorld\([\s\S]*?\b(?:send|invoke|on)\s*:\s*\(\s*channel\b/, "renderer chooses the IPC channel name (checklist 20)"],
  [/\bipcRenderer\.(?:send|invoke)\(\s*channel\b/, "IPC channel name comes from a variable; use fixed names"],
  [/\bloadURL\(\s*["'`]http:\/\//, "loads content over plain HTTP (checklist 1)"],
  [/\bloadURL\(\s*["'`]file:\/\//, "file:// URL; serve the bundle from a custom protocol (checklist 18)"],
  [/\bRunAsNode\]\s*:\s*true/, "RunAsNode fuse left on (checklist 19)"],
  [/unsafe-eval/, "CSP allows unsafe-eval (checklist 7)"],
];

const findings = [];
const roots = process.argv.slice(2);
if (!roots.length) {
  console.error("usage: node check_electron_security.mjs <dir> [more dirs]");
  process.exit(2);
}
let mainFiles = 0;
let htmlFiles = 0;
for (const root of roots) {
  for (const file of walk(root)) {
    const rel = relative(process.cwd(), file);
    const text = readFileSync(file, "utf8");
    const lines = text.split("\n");
    lines.forEach((line, i) => {
      for (const [re, msg] of LINE_RULES) if (re.test(line)) findings.push(`${rel}:${i + 1}: ${msg}`);
    });
    if (file.endsWith(".html")) {
      htmlFiles++;
      if (!/Content-Security-Policy/i.test(text)) findings.push(`${rel}: no Content-Security-Policy meta tag (checklist 7)`);
      continue;
    }
    if (/new BrowserWindow\(/.test(text)) {
      mainFiles++;
      if (!/setWindowOpenHandler\(/.test(text)) findings.push(`${rel}: BrowserWindow without setWindowOpenHandler (checklist 14)`);
      if (!/["']will-navigate["']/.test(text)) findings.push(`${rel}: no will-navigate handler limiting navigation (checklist 13)`);
    }
    const handlers = [...text.matchAll(/ipcMain\.(?:handle|on)\(\s*["'`]([^"'`]+)["'`]\s*,\s*(?:async\s*)?\(([^)]*)\)\s*=>\s*\{([\s\S]*?)\n\}\);/g)];
    for (const [, channel, , body] of handlers) {
      if (!/senderFrame|assertTrustedSender|validateSender/.test(body)) findings.push(`${rel}: IPC handler "${channel}" does not check event.senderFrame (checklist 17)`);
    }
    for (const m of text.matchAll(/shell\.openExternal\(([^)]*)\)/g)) {
      const before = text.slice(Math.max(0, m.index - 300), m.index);
      if (!/^["'`]https:\/\//.test(m[1].trim()) && !/protocol|isAllowed|allowList|allowlist|startsWith\(\s*["'`]https:/.test(before)) {
        findings.push(`${rel}: shell.openExternal(${m[1].trim()}) without a URL check (checklist 15)`);
      }
    }
  }
}
for (const f of findings) console.log(f);
console.log(findings.length ? `${findings.length} finding(s)` : `ok: no findings (${mainFiles} window file(s), ${htmlFiles} HTML file(s))`);
process.exit(findings.length ? 1 : 0);

All files: source zip · Licence MIT · By Agent Loadout · First listed

Credits

Public work that inspired this loadout. The wording here is our own; follow the links for the originals.

Installing and testing

How do I install Electron desktop app rules in Claude Code?

From your project root, put AGENTS.md, CLAUDE.md, skills/electron-ipc-channel/SKILL.md at .claude/skills/electron-ipc-channel/SKILL.md, skills/electron-ipc-channel/references/main.ts at .claude/skills/electron-ipc-channel/references/main.ts, skills/electron-ipc-channel/references/preload.ts at .claude/skills/electron-ipc-channel/references/preload.ts, skills/electron-ipc-channel/references/renderer-api.d.ts at .claude/skills/electron-ipc-channel/references/renderer-api.d.ts, skills/electron-ipc-channel/references/flip-fuses.ts at .claude/skills/electron-ipc-channel/references/flip-fuses.ts, skills/electron-ipc-channel/scripts/check_electron_security.mjs at .claude/skills/electron-ipc-channel/scripts/check_electron_security.mjs. The "Claude Code" tab on this page has the curl commands, or download https://loadout.jnw-it.com/download/electron-app/claude-code.zip, which is already laid out. Do not overwrite an existing AGENTS.md or CLAUDE.md; merge it.

How do I install Electron desktop app rules in Codex CLI?

From your project root, put AGENTS.md, skills/electron-ipc-channel/SKILL.md at .agents/skills/electron-ipc-channel/SKILL.md, skills/electron-ipc-channel/references/main.ts at .agents/skills/electron-ipc-channel/references/main.ts, skills/electron-ipc-channel/references/preload.ts at .agents/skills/electron-ipc-channel/references/preload.ts, skills/electron-ipc-channel/references/renderer-api.d.ts at .agents/skills/electron-ipc-channel/references/renderer-api.d.ts, skills/electron-ipc-channel/references/flip-fuses.ts at .agents/skills/electron-ipc-channel/references/flip-fuses.ts, skills/electron-ipc-channel/scripts/check_electron_security.mjs at .agents/skills/electron-ipc-channel/scripts/check_electron_security.mjs. The "Codex CLI" tab on this page has the curl commands, or download https://loadout.jnw-it.com/download/electron-app/codex.zip, which is already laid out. Do not overwrite an existing AGENTS.md or CLAUDE.md; merge it.

How do I install Electron desktop app rules in Cursor?

From your project root, put AGENTS.md, skills/electron-ipc-channel/SKILL.md at .agents/skills/electron-ipc-channel/SKILL.md, skills/electron-ipc-channel/references/main.ts at .agents/skills/electron-ipc-channel/references/main.ts, skills/electron-ipc-channel/references/preload.ts at .agents/skills/electron-ipc-channel/references/preload.ts, skills/electron-ipc-channel/references/renderer-api.d.ts at .agents/skills/electron-ipc-channel/references/renderer-api.d.ts, skills/electron-ipc-channel/references/flip-fuses.ts at .agents/skills/electron-ipc-channel/references/flip-fuses.ts, skills/electron-ipc-channel/scripts/check_electron_security.mjs at .agents/skills/electron-ipc-channel/scripts/check_electron_security.mjs. The "Cursor" tab on this page has the curl commands, or download https://loadout.jnw-it.com/download/electron-app/cursor.zip, which is already laid out. Do not overwrite an existing AGENTS.md or CLAUDE.md; merge it.

How do I install Electron desktop app rules in Gemini CLI?

From your project root, put AGENTS.md, GEMINI.md, skills/electron-ipc-channel/SKILL.md at .agents/skills/electron-ipc-channel/SKILL.md, skills/electron-ipc-channel/references/main.ts at .agents/skills/electron-ipc-channel/references/main.ts, skills/electron-ipc-channel/references/preload.ts at .agents/skills/electron-ipc-channel/references/preload.ts, skills/electron-ipc-channel/references/renderer-api.d.ts at .agents/skills/electron-ipc-channel/references/renderer-api.d.ts, skills/electron-ipc-channel/references/flip-fuses.ts at .agents/skills/electron-ipc-channel/references/flip-fuses.ts, skills/electron-ipc-channel/scripts/check_electron_security.mjs at .agents/skills/electron-ipc-channel/scripts/check_electron_security.mjs. The "Gemini CLI" tab on this page has the curl commands, or download https://loadout.jnw-it.com/download/electron-app/gemini-cli.zip, which is already laid out. Do not overwrite an existing AGENTS.md or CLAUDE.md; merge it.

How do I install Electron desktop app rules in Antigravity CLI?

From your project root, put AGENTS.md, skills/electron-ipc-channel/SKILL.md at .agents/skills/electron-ipc-channel/SKILL.md, skills/electron-ipc-channel/references/main.ts at .agents/skills/electron-ipc-channel/references/main.ts, skills/electron-ipc-channel/references/preload.ts at .agents/skills/electron-ipc-channel/references/preload.ts, skills/electron-ipc-channel/references/renderer-api.d.ts at .agents/skills/electron-ipc-channel/references/renderer-api.d.ts, skills/electron-ipc-channel/references/flip-fuses.ts at .agents/skills/electron-ipc-channel/references/flip-fuses.ts, skills/electron-ipc-channel/scripts/check_electron_security.mjs at .agents/skills/electron-ipc-channel/scripts/check_electron_security.mjs. The "Antigravity CLI" tab on this page has the curl commands, or download https://loadout.jnw-it.com/download/electron-app/antigravity-cli.zip, which is already laid out. Do not overwrite an existing AGENTS.md or CLAUDE.md; merge it.

How do I install Electron desktop app rules in GitHub Copilot?

From your project root, put AGENTS.md, skills/electron-ipc-channel/SKILL.md at .agents/skills/electron-ipc-channel/SKILL.md, skills/electron-ipc-channel/references/main.ts at .agents/skills/electron-ipc-channel/references/main.ts, skills/electron-ipc-channel/references/preload.ts at .agents/skills/electron-ipc-channel/references/preload.ts, skills/electron-ipc-channel/references/renderer-api.d.ts at .agents/skills/electron-ipc-channel/references/renderer-api.d.ts, skills/electron-ipc-channel/references/flip-fuses.ts at .agents/skills/electron-ipc-channel/references/flip-fuses.ts, skills/electron-ipc-channel/scripts/check_electron_security.mjs at .agents/skills/electron-ipc-channel/scripts/check_electron_security.mjs. The "GitHub Copilot" tab on this page has the curl commands, or download https://loadout.jnw-it.com/download/electron-app/copilot.zip, which is already laid out. Do not overwrite an existing AGENTS.md or CLAUDE.md; merge it.

Has Electron desktop app rules been tested?

It passed the Level 1 automated install checks on 2026-10-17: the files parse, install to each agent's documented paths, and pass the safety scan. No AI agent has run it yet, so no agent pass or fail is claimed.

More for Claude Code, Codex, Cursor, Gemini CLI, Antigravity CLI and GitHub Copilot.