Milady Electrobun Build
Use when building an Electrobun app for distribution, setting up code signing, understanding platform-specific build requirements, or diagnosing build failures. Covers dev/canary/stable environments, all three platforms, toolchain prerequisites, artifact output, and CI/CD setup.
install
source · Clone the upstream repo
git clone https://github.com/milady-ai/milady
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/milady-ai/milady "$T" && mkdir -p ~/.claude/skills && cp -r "$T/.claude/plugins/electrobun-dev/skills/electrobun-build" ~/.claude/skills/milady-ai-milady-electrobun-build && rm -rf "$T"
manifest:
.claude/plugins/electrobun-dev/skills/electrobun-build/SKILL.mdsource content
Electrobun Build
Builds a distributable app bundle and installer for the current platform using
electrobun build.
Build Environments
| Environment | Command | Codesign | Updates | Patch gen |
|---|---|---|---|---|
| | No | Disabled | No |
| | Yes (if configured) | Enabled | Yes |
| | Yes (if configured) | Enabled | Yes |
ELECTROBUN_BUILD_ENV is set automatically by the CLI and passed to postBuild scripts — you do not set it manually.
Platform Prerequisites
macOS (Intel + Apple Silicon)
xcode-select --install # Xcode Command Line Tools brew install cmake
Produces:
.dmg installer + .app.tar.zst update tarball
Toolchain: clang++ + make + install_name_tool (all from Xcode CLT)
Architectures: arm64 (Apple Silicon), x64 (Intel) — build runs on matching host
Windows
- Visual Studio 2022 with component
Microsoft.VisualStudio.Component.VC.Tools.x86.x64 - cmake (available via VS installer or standalone)
The CLI uses
vswhere.exe to find VS and vcvarsall.bat to configure the environment automatically.
Produces:
.exe self-extracting installer (in a .zip) + .tar.zst update tarball
Toolchain: cl.exe + link.exe via MSVC
Architecture: x64 only
Linux
sudo apt-get install -y \ build-essential \ cmake \ pkg-config \ libgtk-3-dev \ libwebkit2gtk-4.1-dev \ libayatana-appindicator3-dev \ librsvg2-dev \ fuse \ libfuse2
libfuse2 is required for AppImage creation.
Produces:
.AppImage + .tar.zst update tarball
Toolchain: g++ + make + pkg-config
Architectures: x64, arm64
electrobun.config.ts — Build Options
General (build.*
)
build.*build: { bun: { entrypoint: "src/bun/index.ts", // default // + any Bun.build() options (splitting, minify, target, etc.) }, views: { // Each key becomes the view's URL scheme: mainview://index.html mainview: { entrypoint: "src/mainview/index.ts", // + any Bun.build() options per view }, }, copy: { // Record<sourcePath, destPathInBuildOutput> "src/assets/icon.png": "resources/icon.png", }, buildFolder: "build", // default: "build" artifactFolder: "artifacts", // default: "artifacts" targets: "current", // default: build for host platform useAsar: false, // default: false — pack assets into ASAR archive asarUnpack: ["*.node", "*.dll", "*.dylib", "*.so"], // always unpacked from ASAR cefVersion: undefined, // override bundled CEF version bunVersion: undefined, // override bundled Bun runtime version wgpuVersion: undefined, // override latest electrobun-dawn release locales: "*", // ICU locales to include ("*" = all); Linux/Windows only }
macOS (build.mac
)
build.macbuild: { mac: { bundleCEF: false, // bundle CEF instead of WKWebView (~120MB) bundleWGPU: false, // bundle Dawn for native GPU rendering defaultRenderer: "native", // "native" | "cef" codesign: false, // enable Apple code signing notarize: false, // enable notarization (requires codesign: true) icons: undefined, // path to .iconset folder or .icns file chromiumFlags: {}, // Record<string, string|true> — CEF-only flags entitlements: undefined, // path to custom entitlements.plist } }
Windows (build.win
)
build.winbuild: { win: { bundleCEF: false, // CEF is always needed on Windows (no OS webview) bundleWGPU: false, // bundle Dawn icons: undefined, // path to .ico file chromiumFlags: {}, // CEF Chromium flags } }
Linux (build.linux
)
build.linuxbuild: { linux: { bundleCEF: false, // bundle CEF instead of GTKWebKit bundleWGPU: false, // bundle Dawn icons: undefined, // icon file path chromiumFlags: {}, // CEF Chromium flags } }
Linux multi-view note: GTKWebKit is the default system webview. For apps with multiple views or needing consistent rendering,
is strongly recommended.bundleCEF: true
Code Signing (macOS)
Code signing runs automatically when
build.mac.codesign: true and ELECTROBUN_DEVELOPER_ID is set. It only runs when buildEnvironment !== "dev", host OS is macOS, and target OS is macOS.
Signing Order
- CEF framework internals (if
)bundleCEF: true - CEF helper applications
- All
files and executables inside.dylib
recursivelyMacOS/ - The
executablelauncher - The entire
bundle.app - The
installer.dmg
Required Environment Variables
export ELECTROBUN_DEVELOPER_ID="Developer ID Application: Your Name (TEAMID)" # Notarization (requires codesign: true) export ELECTROBUN_APPLEID="you@example.com" export ELECTROBUN_APPLEIDPASS="xxxx-xxxx-xxxx-xxxx" # app-specific password export ELECTROBUN_TEAMID="ABCDE12345"
Notarization Sequence
bundle zipped.app
— blocks until Apple respondsxcrun notarytool submit --wait- On success:
attaches ticket to bundlexcrun stapler staple
created, then also code-signed and notarized.dmg
Artifact Output
All artifacts land in
artifacts/ (or build.artifactFolder).
Naming Convention: {channel}-{os}-{arch}-{filename}
{channel}-{os}-{arch}-{filename}| Platform | Installer | Update Tarball | Manifest |
|---|---|---|---|
| macOS stable arm64 | | | |
| macOS canary arm64 | | | |
| macOS stable x64 | | | |
| Windows stable x64 | | | |
| Windows canary x64 | | | |
| Linux stable x64 | | | |
| Linux canary arm64 | | | |
Patch files:
{channel}-{os}-{arch}-{fromHash}.patch (generated if previous tarball available)
update.json
Contents
update.json{ "version": "1.0.0", "hash": "<sha256-of-uncompressed-tarball>", "platform": "macos", "arch": "arm64" }
version.json
Inside the App Bundle
version.jsonmacOS: MyApp.app/Contents/Resources/version.json Windows: MyApp/Resources/version.json Linux: MyApp/Resources/version.json
{ "version": "1.0.0", "hash": "<content-hash>", "channel": "stable", "baseUrl": "https://updates.example.com/", "name": "MyApp", "identifier": "com.example.myapp" }
Environment Variables Reference
Set by Electrobun CLI — passed to postBuild
scripts
postBuild| Variable | Example |
|---|---|
| / / |
| / / |
| / |
| |
| |
| |
| |
| |
Set by you — version and runtime overrides
| Variable | Purpose |
|---|---|
| Override CEF version without editing config |
| Override Bun runtime version |
| Force console output on Windows in production |
does not exist. Code signing is controlled byELECTROBUN_SKIP_CODESIGNandconfig.build.mac.codesign.buildEnvironment
GitHub Actions CI/CD Matrix
Official runners used by Electrobun's own release workflow:
strategy: matrix: include: - runner: macos-14 # Apple Silicon arch: arm64 - runner: macos-15-intel # Intel arch: x64 - runner: ubuntu-24.04 # Linux x64 arch: x64 - runner: ubuntu-24.04-arm # Linux ARM64 arch: arm64 - runner: windows-2025 # Windows x64 arch: x64
Required GitHub Secrets
| Secret | Purpose |
|---|---|
| Base64-encoded .p12 certificate |
| Certificate password |
| Apple Developer ID string |
| Apple ID email |
| App-specific password |
| Apple Team ID |
| Cloudflare R2 endpoint URL |
| R2 access key |
| R2 secret key |
| R2 bucket name |
| npm publish token |
macOS Certificate Import Step
- name: Install Apple Certificate run: | echo $MACOS_CERTIFICATE | base64 --decode > certificate.p12 security create-keychain -p "" build.keychain security import certificate.p12 -k build.keychain \ -P $MACOS_CERTIFICATE_PWD -T /usr/bin/codesign security list-keychains -d user -s build.keychain security set-keychain-settings -t 3600 -u build.keychain security unlock-keychain -p "" build.keychain
Common Build Failures
| Error | Cause | Fix |
|---|---|---|
| View URL not found | Config key doesn't match dir name | → URL must be |
| Blank window | Script tag points to not compiled | Use in HTML |
| Codesign fails locally | Certificate not in keychain | Run |
| Notarization fails | Hardened runtime without JIT entitlement | Add to entitlements.plist |
| Linux AppImage won't run | FUSE missing | |
| Windows MSVC not found | VS component missing | Install component via VS Installer |
| CEF build fails | cmake not installed | Install cmake for the platform |
not found | not set | Set in config |
| WGPU GC crash after frames | FFI objects not pinned | Push all GPU objects to array |