Cursor BYOK Frontend Guide
leookun/cursor-byok
Sets the rules for building the Cursor BYOK desktop app's React and Tauri frontend, especially its HTTP boundary and component state architecture.
A skill your agent uses when building, hardening, or shipping a cross-platform Electron desktop app — main/renderer/preload process model, typed contextBridge IPC, locking down…
$ npx skills add ericrisco/rsc-harness --skill electron -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install ericrisco/rsc-harness electron --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/ericrisco/rsc-harness.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/electron .claude/skills/electron && rm -rf skills-srcUse ~/.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/
Install the "electron" agent skill from https://github.com/ericrisco/rsc-harness/tree/main/skills/electron into .claude/skills/electron/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "electron", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/ericrisco/rsc-harness/tree/main/skills/electronType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add ericrisco/rsc-harness --skill electron -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install ericrisco/rsc-harness electron --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/ericrisco/rsc-harness.git skills-src && mkdir -p .agents/skills && cp -r skills-src/skills/electron .agents/skills/electron && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "electron" agent skill from https://github.com/ericrisco/rsc-harness/tree/main/skills/electron into .agents/skills/electron/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "electron", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add ericrisco/rsc-harness --skill electron -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install ericrisco/rsc-harness electron --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/ericrisco/rsc-harness.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/skills/electron .cursor/skills/electron && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "electron" agent skill from https://github.com/ericrisco/rsc-harness/tree/main/skills/electron into .cursor/skills/electron/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "electron", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/ericrisco/rsc-harness.git --path skills/electron--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add ericrisco/rsc-harness --skill electron -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install ericrisco/rsc-harness electron --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/ericrisco/rsc-harness.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/skills/electron .gemini/skills/electron && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "electron" agent skill from https://github.com/ericrisco/rsc-harness/tree/main/skills/electron into .gemini/skills/electron/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "electron", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install ericrisco/rsc-harness electronInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add ericrisco/rsc-harness --skill electron -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/ericrisco/rsc-harness.git skills-src && mkdir -p .github/skills && cp -r skills-src/skills/electron .github/skills/electron && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "electron" agent skill from https://github.com/ericrisco/rsc-harness/tree/main/skills/electron into .github/skills/electron/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "electron", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add ericrisco/rsc-harness --skill electron -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install ericrisco/rsc-harness electron --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/ericrisco/rsc-harness.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/skills/electron .opencode/skills/electron && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "electron" agent skill from https://github.com/ericrisco/rsc-harness/tree/main/skills/electron into .opencode/skills/electron/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "electron", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
electronA skill your agent uses when building, hardening, or shipping a cross-platform Electron desktop app — main/renderer/preload process model, typed contextBridge IPC, locking down…
Electron is an agent skill from ericrisco/rsc-harness. Use when building, hardening, or shipping a cross-platform Electron desktop app — main/renderer/preload process model, typed contextBridge IPC, locking down nodeIntegration/contextIsolation/sandbox/CSP, or packaging with signing and auto-update. NOT a Rust-backed shell on the native webview (that is tauri), nor the web UI inside it (that is react).
Its SKILL.md is about 2.9k tokens, which your agent loads only when the skill is triggered. The skill folder holds 8 other files, including scripts and reference files (for example `evals/README.md`, `evals/cases.yaml` and `references/packaging-and-updates.md`).
It sits in Frontend & Design, covering Frontend development. It works with React, Tauri and Rust. The repository describes itself as: Your agent invents things because it has no memory, and can't touch your database because it has no arms. rsc is the meta-harness that gives it both, plus the trade to know the… The licence is MIT.
Read from SKILL.md and the folder at commit 92fde8f. It shows what the files ask for, not the result of running them.
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.
Ships 1 file in scripts/ (Shell), which the agent can run.
Shell commands in SKILL.md call:
npmFrom the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md. Its commands use npm, which can reach the network depending on how they are called.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Electron loads about 2.9k tokens when it runs, and up to ~5.5k if it reads all its reference files. Until then it costs about 90 tokens; SKILL.md has 1,022 words of instructions outside code blocks.
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.
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); the scripts in this folder are not scanned.
The full file from ericrisco/rsc-harness at commit 92fde8f, republished under its MIT licence (© ericrisco). 1,022 words, ~2,917 tokens.
.claude/skills/electron/SKILL.md (or your agent's skills folder). This skill also uses 5 other files; get the full folder from GitHub.This skill owns the desktop shell: process model, IPC, security, packaging, signing,
auto-update. It does not own the web UI inside the window (../react/SKILL.md), the
Node backend logic, or the CI runner matrix.
An Electron app is three kinds of process. Code lives in exactly one; putting it in the wrong one is the root cause of most security holes.
| Process | Runtime | Trust | One per | Does |
|---|---|---|---|---|
| main | Node.js, full OS API | trusted | app | windows, menus, tray, dialogs, fs, child procs |
| renderer | Chromium, no Node | untrusted | window | your web UI; can run attacker JS if you load remote content |
| preload | isolated world, runs before page JS | semi-trusted | window | the only bridge: contextBridge exposes a tiny API |
The governing rule: the renderer is untrusted, the main process holds all privilege, and the preload is the only sanctioned bridge between them. Renderer-to-OS escalation is the dominant failure mode in real Electron apps, so everything below is a corollary.
Scaffold with Electron Forge (@electron/forge) — first-party, all-in-one
(scaffold → package → make → publish), and it gets new Electron features first.
npm init electron-app@latest my-app -- --template=vite-typescript
cd my-app && npm startPin to a supported major. Electron ships a new major every 8 weeks (tracking Chromium)
and supports only the latest 3 majors. As of June 2026 the stable line is Electron 42
(Chromium M148, Node 24); 43 lands 2026-06-30. Shipping on an EOL major means unpatched
Chromium CVEs — check package.json and bump if behind.
Project layout keeps the boundary visible:
src/
main.ts # main process — owns everything privileged
preload.ts # the bridge — contextBridge only
renderer/ # your web UI (untrusted)
ipc/types.ts # IPC contract shared by main + preloadModern Electron defaults are already secure (nodeIntegration:false,
contextIsolation:true, sandbox:true since Electron 20). Assert them explicitly anyway
so a careless edit can't silently weaken the window:
const win = new BrowserWindow({
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
nodeIntegration: false, // renderer gets NO require/process — never flip true
contextIsolation: true, // preload + page run in separate JS worlds
sandbox: true, // renderer in an OS sandbox; preload uses a limited API
webSecurity: true, // keep same-origin policy; never disable to "fix CORS"
allowRunningInsecureContent: false, // no mixed http content on https pages
},
});One why per flag: each removes a documented way for renderer-side script to reach Node or
the OS. Flipping any of them to the insecure value is what verify.sh fails on.
CSP via response headers, not a <meta> tag — meta CSP can't restrict the initial
document and is trivially bypassed for some directives. Set it in the main process:
session.defaultSession.webRequest.onHeadersReceived((details, cb) => {
cb({ responseHeaders: { ...details.responseHeaders,
'Content-Security-Policy': ["default-src 'self'; script-src 'self'"] } });
});Lock navigation. A renderer that can navigate to attacker content gets the renderer's privileges. Deny unexpected navigation and block new windows:
app.on('web-contents-created', (_e, contents) => {
contents.on('will-navigate', (e, url) => {
if (new URL(url).origin !== 'https://app.local') e.preventDefault();
});
contents.setWindowOpenHandler(() => ({ action: 'deny' })); // no tab-jacking
});Open real external links deliberately, after allow-listing the protocol:
function openExternal(url: string) {
const { protocol } = new URL(url);
if (protocol === 'https:' || protocol === 'mailto:') shell.openExternal(url);
}Which branch are you on?
sandbox:true + nav lockdown is enough.Fuses and the full hardened example live in references/security-and-ipc.md.
IPC is the seam between untrusted renderer and privileged main. Get it wrong and you've handed the OS to whatever script runs in the page.
Never expose ipcRenderer (or any of its methods) across the bridge. Sending the whole
module now yields an empty object on the other side — a deliberate footgun removal — and
exposing its methods lets the page call any channel with any payload.
// Bad — preload.ts: hands the renderer a universal IPC weapon (also: empty object now)
contextBridge.exposeInMainWorld('api', ipcRenderer);// Good — preload.ts: ONE function per channel, each wrapping a specific call
import { contextBridge, ipcRenderer } from 'electron';
contextBridge.exposeInMainWorld('api', {
readConfig: () => ipcRenderer.invoke('config:read'),
saveNote: (text: string) => ipcRenderer.invoke('note:save', text),
onSync: (cb: () => void) => ipcRenderer.on('sync:done', cb), // events: send/on
});Prefer ipcMain.handle + ipcRenderer.invoke (request/response, returns a Promise) for
anything that returns data. Reserve send/on for fire-and-forget events (progress, push
notifications). Validate every argument in main — a renderer message is an HTTP request
from an untrusted client:
ipcMain.handle('note:save', (_e, text: unknown) => {
if (typeof text !== 'string' || text.length > 10_000) throw new Error('bad input');
return saveNote(text); // never path.join(userInput) or eval it
});Share the contract as TypeScript types across both sides (ipc/types.ts) so a channel
rename breaks the build, not production. Full main + preload + window.api d.ts example:
references/security-and-ipc.md.
The renderer can't (and must not) touch the OS directly. When the UI needs a native menu,
tray icon, file dialog, system notification, custom protocol:// handler, or a
child_process, the renderer invokes an IPC channel and the main process performs the
action and returns a result. Same one-function-per-channel discipline as above.
For embedding web content in a region of a window, use WebContentsView —
BrowserView is deprecated since Electron 30. They share shape (both take webPreferences;
setBounds/getBounds/webContents carry over), so migration is mechanical.
Two real toolchains:
| Need | Use |
|---|---|
| New app, first-party alignment, features first | Electron Forge (ASAR integrity, universal macOS, scaffold→make→publish) |
| Differential/staged updates, multi-provider (GitHub/S3), richer config | electron-builder + electron-updater |
Code signing is a prerequisite for auto-update, not optional polish. macOS auto-update
(Squirrel.Mac) refuses to update an app that isn't signed and notarized; Windows
updates need an Authenticode-signed installer. So the order is always: sign → notarize →
publish → auto-update. Full Forge and builder configs, notarytool steps, Windows
Authenticode, and electron-updater + GitHub Releases wiring: references/packaging-and-updates.md.
The CI matrix that runs these builds across three OSes is github-actions' job; this skill
defines what to build and sign.
| Anti-pattern | Why it's wrong | Do instead |
|---|---|---|
nodeIntegration: true | Page JS gets require('fs'); any XSS becomes OS-level RCE | false; move the capability behind IPC |
contextIsolation: false | Page can rewrite the preload's globals | true (the default) |
sandbox: false without a reason | Drops the OS sandbox around the renderer | true; only relax for a measured, isolated need |
exposeInMainWorld('api', ipcRenderer) or its methods | Universal IPC weapon — any channel, any payload (and an empty object now) | One typed function per channel |
No arg validation in ipcMain.handle | Renderer is an untrusted client; you trust its input | Type-check + bound every arg before acting |
webSecurity: false to "fix CORS" | Disables same-origin policy app-wide | Keep true; proxy/handle CORS in main |
CSP only in a <meta> tag | Doesn't cover the initial document; bypassable | Set CSP in onHeadersReceived |
| Loading a remote URL into a Node-enabled window | Remote site runs with your app's privilege | Bundle UI locally; sandbox + nav lockdown for remote |
@electron/remote import | Sync main-object access = renderer→main RCE | Replace with explicit ipcMain.handle channels |
new BrowserView(...) | Deprecated since Electron 30, will be removed | new WebContentsView(...) |
| Auto-update with an unsigned/un-notarized build | Squirrel.Mac silently refuses; no updates ship | Sign + notarize (mac), Authenticode (win) first |
| Shipping on an EOL Electron major | Unpatched Chromium CVEs in your users' hands | Stay within the latest 3 majors |
| Heavy CPU work in the main process | Blocks the event loop → the whole UI freezes | utilityProcess/worker, or do it in the renderer |
Run scripts/verify.sh /path/to/your-electron-project to grep a target for insecure
patterns (nodeIntegration: true, contextIsolation: false, sandbox: false,
@electron/remote, new BrowserView, exposeInMainWorld(..., ipcRenderer)). It's read-only
and exits non-zero on any finding. With no argument it self-checks this skill's own example
snippets for the secure baseline. See references/security-and-ipc.md for the full checklist.
© ericrisco, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 5 other files (scripts, references) in skills/electron of ericrisco/rsc-harness.
Open the folder on GitHubat commit 92fde8f
Electron 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.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Electron this skillericrisco/rsc-harness | 156 | — | ~2.9k | Automated safety check: Pass | MIT | |
| Cursor BYOK Frontend Guideleookun/cursor-byok | 3.2k | — | ~1.9k | Automated safety check: Pass | MIT | |
| Reactflow Workflowveloxbase/veloxdb | 646 | — | ~897 | Automated safety check: Pass | MIT | |
| I18nhuoshen80/ReinaManager | 693 | — | ~177 | Automated safety check: Pass | AGPL-3.0 | |
| Frontend Testhuoshen80/ReinaManager | 693 | — | ~180 | Automated safety check: Pass | AGPL-3.0 | |
| NEAR dApp Builderinternet-court/internet-court-skill | 6.4k | 1 repos | ~684 | Automated safety check: Pass | Custom licence |
leookun/cursor-byok
Sets the rules for building the Cursor BYOK desktop app's React and Tauri frontend, especially its HTTP boundary and component state architecture.
veloxbase/veloxdb
Build and harden React Flow diagram surfaces in VeloxDB using @xyflow/react patterns (nodes, edges, viewport, controls, interactions, performance).
huoshen80/ReinaManager
使用 i18next-cli 检查、同步和整理本项目的国际化资源。涉及新增、修改、删除翻译键或国际化字符串,以及修复缺失翻译时使用。
huoshen80/ReinaManager
在 ReinaManager 项目内进行隔离前端验证,复用测试目录并回收测试资源。需要模拟批量数据、延迟、失败或交互回归时使用。
internet-court/internet-court-skill
Scaffolds new NEAR dApps with create-near-app or adds NEAR wallet sign-in, contract calls and transaction signing to an existing React or plain JavaScript app.
LanternOps/breeze
Quick reference for the Breeze Helper Tauri desktop app — architecture, Rust backend commands, React frontend, config files, IPC with the Go agent, helper chat API routes, tool approval flow, and…
ericrisco/rsc-harness
A skill your agent uses when designing or analyzing a controlled experiment — falsifiable hypothesis, sample size from an MDE, reading significance/CI/power, CUPED, or rescuing tests that won't go…
ericrisco/rsc-harness
A skill your agent uses when making a web UI conform to WCAG 2.2 Level AA — axe-core or Lighthouse a11y violations, keyboard operability, focus management, ARIA roles/names/live regions, contrast…
ericrisco/rsc-harness
A skill your agent uses when running or fixing paid acquisition on Google or Meta — campaign structure (Performance Max, Demand Gen, Search, Advantage+), platform-fit creative, budget/scaling rules…
ericrisco/rsc-harness
A skill your agent uses when measuring whether an LLM or agent system actually got better and gating merges on it: golden sets, fixing an inflated LLM-as-judge, scoring RAG (faithfulness, contextual…
ericrisco/rsc-harness
A skill your agent uses when a creative goal must become a finished media file: pick and order generative-media models per modality — AI voiceover, image-to-video clips, score — then glue them with…
ericrisco/rsc-harness
A skill your agent uses when instrumenting product or web analytics — GA4/PostHog SDK wiring, event taxonomy, funnels, double-counted events, consent gating, PII scrubbing.
Categories
A skill your agent uses when building, hardening, or shipping a cross-platform Electron desktop app — main/renderer/preload process model, typed contextBridge IPC, locking down…. Electron is an agent skill from ericrisco/rsc-harness. Use when building, hardening, or shipping a cross-platform Electron desktop app — main/renderer/preload process model, typed contextBridge IPC, locking down nodeIntegration/contextIsolation/sandbox/CSP, or packaging with signing and auto-update.
Electron fits situations like: shipping a cross-platform Electron desktop app — main/renderer/preload process model; typed contextBridge IPC; locking down nodeIntegration/contextIsolation/sandbox/CSP; packaging with signing and auto-update.
Run `npx skills add ericrisco/rsc-harness --skill electron -a claude-code`. Or copy the skill folder (skills/electron in ericrisco/rsc-harness) into .claude/skills/electron in your project. Claude Code loads it when a task matches its description.
Run `npx skills add ericrisco/rsc-harness --skill electron -a codex`. Or copy the skill folder (skills/electron in ericrisco/rsc-harness) into .agents/skills/electron in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add ericrisco/rsc-harness --skill electron -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, .gemini/skills/electron, .github/skills/electron and .opencode/skills/electron in your project.
Going by SKILL.md and its folder, Electron needs a shell for the scripts in its folder and the command-line tools its instructions call (npm). Our summary lists: Node.js; A Bash shell.
SKILL.md contains no URLs. Its commands use npm, which can reach the network depending on how they are called. This is read from the text; nothing was executed.
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. The check reads SKILL.md only: the scripts in the folder are not scanned, so read them before running anything.
Electron is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
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. Its references folder adds about 2.6k tokens, read only when the agent opens those files.
Skills that share tags, products or a category with Electron: Cursor BYOK Frontend Guide (leookun/cursor-byok, 3.2k stars), Reactflow Workflow (veloxbase/veloxdb, 646 stars), I18n (huoshen80/ReinaManager, 693 stars) and Frontend Test (huoshen80/ReinaManager, 693 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
ericrisco (a GitHub user) maintains it in ericrisco/rsc-harness, which has 156 GitHub stars. The repository holds 229 skills in this directory. The repository was last updated on October 6, 2026.
Source: ericrisco/rsc-harness on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.