skills/community/electron-builder/SKILL.md
Comprehensive guide for electron-builder (v26.x) packaging, code signing, auto-updates, and release workflows. Use when: (1) configuring electron-builder builds (electron-builder.yml or config.js/ts), (2) setting up macOS/Windows code signing or notarization, (3) implementing auto-updates with electron-updater, (4) publishing to GitHub Releases, S3, or generic servers, (5) configuring platform targets (NSIS, DMG, AppImage, Snap, PKG, MSI), (6) working with build hooks (beforePack, afterSign, afterAllArtifactBuild), or (7) using the programmatic API. Triggers on: electron-builder, electron-updater, code signing, notarize, NSIS, DMG, AppImage, auto-update, publish releases, build hooks, electron packaging, electron distribution.
npx skillsauth add pedronauck/skills electron-builderInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Docs: https://www.electron.build (v26.8.x) Repo: https://github.com/electron-userland/electron-builder
Install:
pnpm add electron-builder -D
pnpm add electron-updater # If using auto-updates
Minimal config (electron-builder.yml):
appId: com.example.myapp
productName: My App
files:
- "out/**/*"
- "package.json"
mac:
target: dmg
category: public.app-category.developer-tools
win:
target: nsis
linux:
target:
- AppImage
- deb
publish:
provider: github
Build scripts in package.json:
{
"scripts": {
"build:mac": "electron-builder --mac",
"build:win": "electron-builder --win",
"build:linux": "electron-builder --linux",
"build:all": "electron-builder -mwl",
"release": "electron-builder --publish always"
}
}
electron-builder # Build for current platform
electron-builder -mwl # Build for all platforms
electron-builder --mac dmg # macOS DMG only
electron-builder --win nsis:ia32 # Windows NSIS 32-bit
electron-builder --linux deb tar.xz
electron-builder --dir # Unpacked dir (test builds)
electron-builder -p always # Build and publish
# Architecture flags
--x64 --ia32 --armv7l --arm64 --universal
# CLI config overrides
-c.extraMetadata.foo=bar
-c.mac.identity=null
-c.nsis.unicode=false
# Publish existing artifacts
electron-builder publish -f dist/*.exe -c electron-builder.yml
Publish flag values: onTag | onTagOrDraft | always | never
Config locations (checked in order):
package.json > "build" keyelectron-builder.yml (default, recommended)electron-builder.json / .json5 / .tomlelectron-builder.config.js / .ts--config <path>Do NOT name JS config electron-builder.js — conflicts with package name.
For full configuration options, file patterns, macros, icons, and directory settings: See references/configuration.md
| Property | Default | Description |
|---|---|---|
| appId | com.electron.${name} | Do not change once deployed. Used as bundle ID (macOS) and AUMID (Windows). |
| productName | package.json name | Display name (allows spaces) |
| compression | "normal" | "store" for fast test builds, "maximum" for release |
| asar | true | Pack source into asar archive |
| files | auto | Glob patterns for app source files |
| extraFiles | — | Files copied outside asar (e.g. native addons) |
| extraResources | — | Files copied to resources directory |
| forceCodeSigning | false | Fail build if not signed |
Available in artifactName, file patterns, and publish URLs:
${arch}, ${os}, ${platform}, ${name}, ${productName}, ${version}, ${channel}, ${ext}, ${env.VAR_NAME}
| Platform | Default | |---|---| | macOS | DMG + ZIP | | Windows | NSIS | | Linux (cross) | Snap + AppImage (x64) | | Linux (native) | Snap + AppImage (current arch) |
Signing is automatic when configured. Core environment variables:
| Env | Description |
|---|---|
| CSC_LINK | Certificate path/URL/base64 (.p12/.pfx) |
| CSC_KEY_PASSWORD | Certificate password |
| CSC_IDENTITY_AUTO_DISCOVERY | true/false (macOS keychain auto-discovery) |
| WIN_CSC_LINK | Windows cert (when cross-signing from macOS) |
| WIN_CSC_KEY_PASSWORD | Windows cert password |
export CSC_IDENTITY_AUTO_DISCOVERY=false
# Or in config: mac.identity: null
# For ad-hoc (ARM): mac.identity: "-"
mac:
hardenedRuntime: true
notarize: true # or { teamId: "TEAM_ID" }
Requires APPLE_ID, APPLE_APP_SPECIFIC_PASSWORD, APPLE_TEAM_ID env vars.
win:
azureSignOptions:
publisherName: "CN=Your Company"
endpoint: "https://eus.codesigning.azure.net"
certificateProfileName: "your-profile"
codeSigningAccountName: "your-account"
Requires AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_CLIENT_SECRET.
For complete code signing reference (CI setup, certificates, EV certs, cross-platform): See references/code-signing.md
// main process
import electronUpdater, { type AppUpdater } from "electron-updater";
export function getAutoUpdater(): AppUpdater {
const { autoUpdater } = electronUpdater;
return autoUpdater;
}
const autoUpdater = getAutoUpdater();
autoUpdater.checkForUpdatesAndNotify();
Do NOT call setFeedURL() — app-update.yml is auto-generated at build time.
// CORRECT
import electronUpdater from "electron-updater";
const { autoUpdater } = electronUpdater;
// WRONG (may fail with ESM)
import { autoUpdater } from "electron-updater";
macOS apps MUST be signed for auto-update. Squirrel.Windows NOT supported.
autoUpdater.on("error", (err) => {});
autoUpdater.on("checking-for-update", () => {});
autoUpdater.on("update-available", (info) => {});
autoUpdater.on("update-not-available", (info) => {});
autoUpdater.on("download-progress", (progress) => {
// .bytesPerSecond, .percent, .total, .transferred
});
autoUpdater.on("update-downloaded", (info) => {
autoUpdater.quitAndInstall();
});
import log from "electron-log";
autoUpdater.logger = log;
autoUpdater.logger.transports.file.level = "info";
For staged rollouts, custom updater instances, private repos, dev testing: See references/auto-update.md
publish:
provider: github
releaseType: draft
Set GH_TOKEN env var (personal access token with repo scope).
publish:
provider: s3
bucket: my-bucket-name
Set AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY.
publish:
provider: generic
url: https://example.com/releases
Upload artifacts + latest.yml manually.
| Condition | Default behavior |
|---|---|
| CI detected | onTagOrDraft |
| CI + tag pushed | onTag |
| npm script release | always |
Version determines channel: 1.0.0 = latest, 1.0.0-beta.1 = beta
For all publishers (Bitbucket, GitLab, Keygen, Snap Store, Spaces), workflows, and advanced config: See references/publishing.md
mac:
category: public.app-category.developer-tools
hardenedRuntime: true
darkModeSupport: true
target: dmg
entitlements: build/entitlements.mac.plist
notarize: true
nsis:
oneClick: true # false for assisted installer
perMachine: false
allowToChangeInstallationDirectory: false
createDesktopShortcut: true
deleteAppDataOnUninstall: false
include: build/installer.nsh # Custom NSIS script
differentialPackage: true
linux:
category: Development
desktop:
MimeType: "x-scheme-handler/myapp"
target:
- AppImage
- deb
- snap
For all target options (DMG, PKG, MAS, MSI, AppX, Snap, Flatpak, portable, custom NSIS scripts): See references/platform-targets.md
Execution order:
beforeBuild → beforePack → afterExtract → afterPack → [signing] →
afterSign → artifactBuildStarted → [build] → artifactBuildCompleted →
afterAllArtifactBuild
module.exports = {
afterSign: async (context) => {
if (context.electronPlatformName === "darwin") {
await notarize(context);
}
},
afterAllArtifactBuild: (result) => {
return ["/path/to/extra/file"]; // Additional files to publish
},
};
beforePack: "./scripts/before-pack.js"
afterSign: "./scripts/notarize.js"
// scripts/notarize.js
exports.default = async function(context) {
// context: { outDir, appOutDir, packager, electronPlatformName, arch, targets }
};
For all hooks, context interfaces, and programmatic API: See references/hooks-and-programmatic.md
# GitHub Actions pattern
mac:
target:
- target: dmg
arch: [x64, arm64]
win:
target:
- target: nsis
arch: [x64, ia32]
linux:
target:
- target: AppImage
arch: [x64, arm64]
- target: deb
arch: [x64, arm64]
publish:
provider: github
appId: com.example.myapp
productName: My App
copyright: Copyright 2024 Example Inc.
asar: true
compression: normal
forceCodeSigning: true
directories:
output: dist
buildResources: build
files:
- "out/**/*"
- "package.json"
mac:
target: [dmg, zip]
hardenedRuntime: true
notarize: true
category: public.app-category.developer-tools
win:
target: nsis
nsis:
oneClick: false
perMachine: false
allowToChangeInstallationDirectory: true
linux:
target: [AppImage, deb]
category: Development
publish:
provider: github
electronUpdaterCompatibility: ">= 2.16"
appId after release — NSIS uses it for registry GUIDsetFeedURL() — app-update.yml is auto-generatedelectron-builder.js conflicts with package name — use different filenameapp.setAppUserModelId(appId) in main process for Windows notificationsdevelopment
Deep review of branch diffs, working trees, or GitHub PRs at any size. Use when the user asks for CodeRabbit-grade review, an incremental re-review after new pushes, publication of findings to a PR, a cross-LLM peer-review verdict round, or conformance review against spec artifacts. Don't use for applying fixes, reviewing specs or PRDs as documents, or quick single-file feedback.
tools
Orchestrate Claude and Codex worker TUIs from a controller agent through herdr panes and the herdr socket CLI. Use when delegating bounded tasks to herdr worker panes, running user-activated plan-first delegations (Claude Code plan mode, Codex Plan mode), waiting on native agent status (idle, working, blocked, done), or verifying worker reports. Workers launch as interactive TUIs via herdr agent start — never through headless runners (compozy exec, claude -p, codex exec). Not for cmux workspaces (see cmux-orchestration) and not for end-user herdr control.
tools
TanStack Query, Router, and Form patterns for React. Use when writing useQuery/queryOptions, mutations, caching, file-based routes, search params, loaders, or TanStack Form validation. Don't use for TanStack Start, TanStack DB/collections, Zustand client state, or non-TanStack routing.
development
Use when the user wants to design, redesign, shape, critique, audit, polish, clarify, distill, harden, optimize, adapt, animate, colorize, extract, or otherwise improve a frontend interface. Covers websites, landing pages, dashboards, product UI, app shells, components, forms, settings, onboarding, and empty states. Handles UX review, visual hierarchy, information architecture, cognitive load, accessibility, performance, responsive behavior, theming, anti-patterns, typography, fonts, spacing, layout, alignment, color, motion, micro-interactions, UX copy, error states, edge cases, i18n, and reusable design systems or tokens. Also use for bland designs that need to become bolder or more delightful, loud designs that should become quieter, live browser iteration on UI elements, or ambitious visual effects that should feel technically extraordinary. Not for backend-only or non-UI tasks.