electrobun-best-practices by 0xbigboss/claude-code
npx skills add https://github.com/0xbigboss/claude-code --skill electrobun-best-practicesElectrobun 使用 TypeScript 和 Bun 构建跨平台桌面应用程序。本技能提供了安全默认值、类型化 RPC 模式以及构建/更新/分发的操作指南。
文档:https://blackboard.sh/electrobun/docs/
请始终与 typescript-best-practices 技能一同加载。
Electrobun API 发展迅速。在依赖高级选项或平台特定行为之前,请根据当前文档和 CLI 输出进行验证。
Electrobun 应用程序作为 Bun 应用程序运行:
electrobun/bun 导入electrobun/view 导入Bun 和浏览器上下文之间的 IPC 使用 postMessage、FFI 以及(在某些路径中)加密的 WebSocket。
bunx electrobun init
bun install
bun start
推荐的脚本:
{
"scripts": {
"start": "electrobun run",
"dev": "electrobun dev",
"dev:watch": "electrobun dev --watch",
"build:dev": "bun install && electrobun build",
"build:canary": "electrobun build --env=canary",
"build:stable": "electrobun build --env=stable"
}
}
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
对于不受信任或第三方内容,请使用此基线配置:
import { BrowserWindow } from "electrobun/bun";
const win = new BrowserWindow({
title: "External Content",
url: "https://example.com",
sandbox: true, // 禁用 RPC,事件仍然有效
partition: "persist:external",
});
win.webview.setNavigationRules([
"^*", // 默认阻止所有内容
"*://example.com/*", // 仅允许受信任的域名
"^http://*", // 强制使用 HTTPS
]);
win.webview.on("will-navigate", (e) => {
console.log("nav", e.data.url, "allowed", e.data.allowed);
});
安全检查清单:
sandbox: true。partition 值进行隔离。<electrobun-webview> 预加载脚本的 host-message 负载。PATHS.RESOURCES_FOLDER;请使用 Utils.paths.userData。// src/shared/types.ts
import type { RPCSchema } from "electrobun/bun";
export type MyRPC = {
bun: RPCSchema<{
requests: {
getUser: { params: { id: string }; response: { name: string } };
};
messages: {
logToBun: { msg: string };
};
}>;
webview: RPCSchema<{
requests: {
updateUI: { params: { html: string }; response: boolean };
};
messages: {
notify: { text: string };
};
}>;
};
// bun 端
import { BrowserView, BrowserWindow } from "electrobun/bun";
import type { MyRPC } from "../shared/types";
const rpc = BrowserView.defineRPC<MyRPC>({
handlers: {
requests: {
getUser: ({ id }) => ({ name: `user-${id}` }),
},
messages: {
logToBun: ({ msg }) => console.log(msg),
},
},
});
const win = new BrowserWindow({
title: "App",
url: "views://mainview/index.html",
rpc,
});
await win.webview.rpc.updateUI({ html: "<p>Hello</p>" });
// 浏览器端
import { Electroview } from "electrobun/view";
import type { MyRPC } from "../shared/types";
const rpc = Electroview.defineRPC<MyRPC>({
handlers: {
requests: {
updateUI: ({ html }) => {
document.body.innerHTML = html;
return true;
},
},
messages: {
notify: ({ text }) => console.log(text),
},
},
});
const electroview = new Electroview({ rpc });
await electroview.rpc.request.getUser({ id: "1" });
electroview.rpc.send.logToBun({ msg: "hello" });
使用 before-quit 进行关闭前的清理工作,而不是依赖 process.on("exit") 来处理异步任务。
import Electrobun from "electrobun/bun";
Electrobun.events.on("before-quit", async (e) => {
await saveState();
// e.response = { allow: false }; // 可选:取消退出
});
重要注意事项:
before-quit。通过 Utils.quit()/process.exit() 进行的程序化退出是可靠的。ApplicationMenu。runtime.exitOnLastWindowClosed: false,然后通过 Tray 驱动用户体验。partition 值。bundleCEF: true 和 defaultRenderer: "cef"。sandbox: true 会禁用 RPC)。setNavigationRules 的顺序;最后一个匹配项生效。^* 放在首位。release.baseUrl 和上传的 artifacts/ 命名({channel}-{os}-{arch}-...)。canary 与 stable)。Session.fromPartition(...) 管理 cookie。ELECTROBUN_BUILD_ENV、ELECTROBUN_OS、ELECTROBUN_ARCH)。每周安装次数
21
代码仓库
GitHub 星标数
36
首次出现
11 天前
安全审计
安装于
opencode18
gemini-cli17
amp17
cline17
github-copilot17
codex17
Electrobun builds cross-platform desktop apps with TypeScript and Bun. This skill gives safe defaults, typed RPC patterns, and operational guidance for build/update/distribution.
Docs: https://blackboard.sh/electrobun/docs/
Always load typescript-best-practices alongside this skill.
Electrobun APIs evolve quickly. Before relying on advanced options or platform-specific behavior, verify against current docs and CLI output.
Electrobun apps run as Bun apps:
electrobun/bunelectrobun/viewIPC between bun and browser contexts uses postMessage, FFI, and (in some paths) encrypted WebSockets.
bunx electrobun init
bun install
bun start
Recommended scripts:
{
"scripts": {
"start": "electrobun run",
"dev": "electrobun dev",
"dev:watch": "electrobun dev --watch",
"build:dev": "bun install && electrobun build",
"build:canary": "electrobun build --env=canary",
"build:stable": "electrobun build --env=stable"
}
}
Use this baseline for untrusted or third-party content:
import { BrowserWindow } from "electrobun/bun";
const win = new BrowserWindow({
title: "External Content",
url: "https://example.com",
sandbox: true, // disables RPC, events still work
partition: "persist:external",
});
win.webview.setNavigationRules([
"^*", // block everything by default
"*://example.com/*", // allow only trusted domain(s)
"^http://*", // enforce HTTPS
]);
win.webview.on("will-navigate", (e) => {
console.log("nav", e.data.url, "allowed", e.data.allowed);
});
Security checklist:
sandbox: true for untrusted content.partition values for isolation.host-message payloads from <electrobun-webview> preload scripts.PATHS.RESOURCES_FOLDER at runtime; use Utils.paths.userData.// src/shared/types.ts
import type { RPCSchema } from "electrobun/bun";
export type MyRPC = {
bun: RPCSchema<{
requests: {
getUser: { params: { id: string }; response: { name: string } };
};
messages: {
logToBun: { msg: string };
};
}>;
webview: RPCSchema<{
requests: {
updateUI: { params: { html: string }; response: boolean };
};
messages: {
notify: { text: string };
};
}>;
};
// bun side
import { BrowserView, BrowserWindow } from "electrobun/bun";
import type { MyRPC } from "../shared/types";
const rpc = BrowserView.defineRPC<MyRPC>({
handlers: {
requests: {
getUser: ({ id }) => ({ name: `user-${id}` }),
},
messages: {
logToBun: ({ msg }) => console.log(msg),
},
},
});
const win = new BrowserWindow({
title: "App",
url: "views://mainview/index.html",
rpc,
});
await win.webview.rpc.updateUI({ html: "<p>Hello</p>" });
// browser side
import { Electroview } from "electrobun/view";
import type { MyRPC } from "../shared/types";
const rpc = Electroview.defineRPC<MyRPC>({
handlers: {
requests: {
updateUI: ({ html }) => {
document.body.innerHTML = html;
return true;
},
},
messages: {
notify: ({ text }) => console.log(text),
},
},
});
const electroview = new Electroview({ rpc });
await electroview.rpc.request.getUser({ id: "1" });
electroview.rpc.send.logToBun({ msg: "hello" });
Use before-quit for shutdown cleanup instead of relying on process.on("exit") for async work.
import Electrobun from "electrobun/bun";
Electrobun.events.on("before-quit", async (e) => {
await saveState();
// e.response = { allow: false }; // optional: cancel quit
});
Important caveat:
before-quit. Programmatic quit via Utils.quit()/process.exit() is reliable.ApplicationMenu with role-based items.runtime.exitOnLastWindowClosed: false, then drive UX from Tray.partition values per account.bundleCEF: true and defaultRenderer: "cef" in platform config.sandbox: true disables RPC).setNavigationRules ordering; last match wins.^* first only when you intentionally run strict allowlist mode.release.baseUrl and uploaded artifacts/ naming ({channel}-{os}-{arch}-...).canary vs stable).Weekly Installs
21
Repository
GitHub Stars
36
First Seen
11 days ago
Security Audits
Gen Agent Trust HubPassSocketPassSnykWarn
Installed on
opencode18
gemini-cli17
amp17
cline17
github-copilot17
codex17
React 组合模式指南:Vercel 组件架构最佳实践,提升代码可维护性
122,000 周安装
Session.fromPartition(...).ELECTROBUN_BUILD_ENV, ELECTROBUN_OS, ELECTROBUN_ARCH).