v27 Breaking Changes
v27 moves the entire electron-builder ecosystem to native ES modules, raises the minimum runtime to Node.js 22.12.0, and hard-deletes the deprecated APIs that accumulated since v22. Every breaking change in the release is catalogued in this section.
Most projects need only a Node.js bump plus one command. Run the automated migrator and follow the step-by-step migration walkthrough →.
This section is the canonical reference for what changed in v27. For the how — the ordered upgrade steps, the automated migrator, and the checklist — see the v26 → v27 migration walkthrough. New, additive features are listed on What's New in v27.
- The
build()API is unchanged; configuration keys that were renamed or restructured are rewritten automatically bymigrate-schemaand keep their v26 behavior, and exported types that survive keep their shape. - CJS
require()continues to work without code changes on supported Node.js versions. - Every config-level breaking change that has a mechanical v27 equivalent is rewritten automatically by
electron-builder migrate-schema(look for the Auto ✓ marker on the Config page). The config keys it cannot rewrite,squirrelWindows.customSquirrelVendorDirand a custom NSIS bundle innsis.customNsisBinary/customNsisResources, are reported with a warning. Runtime, CLI, env-var, and behavior changes require manual action — see whatmigrate-schemadoes and does not do.
electron-builder migrate-schema # apply changes in place
electron-builder migrate-schema --dry-run # preview only
This handles every change marked Auto ✓ on the Config page. See the walkthrough for flags and serialization caveats.
Breaking changes at a glance
The changes are split by where you fix them. Each page opens with its own at-a-glance table, and each entry says how the build tells you about it.
| Page | What's on it | Changes |
|---|---|---|
| Config | Removed, renamed and restructured config keys. migrate-schema rewrites most of them; any left behind fail the build. | 25 |
| Build & Publish | Node.js and CLI, toolsets and environment variables, dependency collection and validation, signing checks, publishing and update metadata, Flatpak build tooling. | 32 |
| Runtime (Shipped App) | What changes on users' machines: auto-update defaults and the electron-updater API, macOS entitlements and DMG, NSIS file associations, the Linux launcher, Flatpak and Snap defaults. | 21 |
| Developer-Only | Only if you write code against electron-builder: ESM packaging, the programmatic and plugin APIs, build hooks and custom signers, custom NSIS and maintainer scripts, type exports. | 10 |
How v27 tells you about breaking changes
Most v27 breaking changes announce themselves when a build runs into them:
- Removed or moved config keys fail the build with one error that lists each key, its replacement and a link to its section.
- Most build and publish changes fail the build or log a warning with a link to their section: missing dependencies, mismatched native binaries, removed environment variables, signing-key and publisher checks, Flatpak and Snap defaults, and more.
- Some runtime defaults get an advisory from
migrate-schema(nsis-webinstallers, per-machine NSIS builds, macOS entitlements, feed URLs with a query string), and electron-updater logs a warning when app code uses a changed API.
The quickest way through an upgrade is:
- Run
migrate-schema. - Run a normal build.
- Run a publishing build: the signing-key, S3 and update-feed checks only run when publishing.
- Follow the links in any errors or warnings.
- Check the list below: those changes won't tell you.
Changes that won't tell you
Silent
| Change | Affects you if | Page |
|---|---|---|
DMG filesystem defaults to APFS | You support macOS older than 10.13 (High Sierra) | Runtime |
http-parser dropped from the default pacman depends | Your Arch package relies on http-parser | Runtime |
Linux targets launch through a *-launcher script; AppImage adds --no-sandbox only for the legacy FUSE2 runtime | You ship a custom .desktop file, AppArmor profile or MIME handler, or need the Chromium sandbox off in an AppImage | Runtime |
| Windows update signature verification fails closed | Your users' machines may block PowerShell (AppLocker / WDAC), or your update installers are catalog-signed. Updates fail only on those machines | Runtime |
The nsis-web installer verifies its app package | You run one web installer with a --package-file from another build | Runtime |
verifyUpdateCodeSignature renamed (shim until v28) | Your app sets verifyUpdateCodeSignature, or a subclass redeclares _verifyUpdateCodeSignature | Runtime |
| macOS names are no longer NFD-normalized | Your product name has accented characters and external tooling matches the bundle filename | Build |
An empty GitHub tagNamePrefix is honored | You set tagNamePrefix: "" (v26 still tagged v1.2.3) | Config |
npm run release no longer publishes | Your release script relied on its name to publish | Build |
The embedded update feed follows target-level publish | You set publish on a target (e.g. nsis.publish), or the first provider has publishAutoUpdate: false | Build |
latest*.yml drops the top-level path / sha512 | App code or tooling reads info.path / info.sha512, or you still ship electron-updater 2.15 or older | Build |
NSIS customInstallMode macro guard casing | Your custom NSIS script defines customInstallmode (lowercase m) | Developer |
Info log only
| Change | Affects you if | Page |
|---|---|---|
Toolsets resolve to "latest"; Wine is the host install | You build Windows targets on macOS (install Wine), or need a legacy bundle | Build |
Azure Trusted Signing uses signtool /dlib | You need the legacy PowerShell signing path | Build |
node_modules are filtered by cpu / os on every build | You bundle a cross-arch or cross-OS optional binary on purpose | Build |
electron / electron-builder are excluded from the copied node_modules | You need electron-builder inside the app | Build |
Silent in the common case
| Change | Affects you if | Page |
|---|---|---|
macOS default entitlements drop allow-unsigned-executable-memory | Your app needs that entitlement. Only the library-validation part gets a build warning | Runtime |
S3 publishing needs awsCredentials.source | You publish to S3. Builds that don't publish don't check it | Build |
| macOS: the ASAR integrity digest is embedded | You merge separately built x64 and arm64 apps with @electron/universal yourself. The build only warns when you have an afterPack hook | Runtime |
What migrate-schema covers
v27 adds electron-builder migrate-schema, which rewrites your config to v27 form in place and auto-migrates static (json/json5/yaml/package.json) and programmatic (.js/.ts/.cjs/.mjs) configs. TOML configs are parsed and the required changes printed, but not written. See the walkthrough for flags and the before/after of every rewrite.
It rewrites every entry marked Auto ✓ on the Config page: removed keys (electronCompile, framework/nodeVersion/launchUiVersion, disableDefaultIgnoredFiles, appImage.systemIntegration, linux.syncDesktopName, mac.gatekeeperAssess), the nativeModules, asar (root and platform-level), fileOptions (root and platform-level), mac.sign, mac.universal, win.sign, electronGet, and snapcraft restructurings, GitHub vPrefixedTagName → tagNamePrefix, includePdb → fileOptions.excludedExts, helper-bundle-id, squirrelWindows.noMsi, root-level directories in package.json, and toolsets.* values v27 rejects (null, the retired appimage: "1.0.2"). Values with no v27 equivalent (for example nativeRebuilder: "legacy" or electronDownload.strictSSL) are dropped with a warning.
It warns but leaves in place what cannot be rewritten mechanically: squirrelWindows.customSquirrelVendorDir, a custom NSIS bundle in customNsisBinary / customNsisResources (→ toolsets.nsis; it does move customNsisBinary.debugLogging → installerDebugLogging), a custom mac.sign signer combined with sibling signing options, an includePdb value v26 rejected, and, in JS/TS configs, platform-level asarUnpack next to root-level ASAR options, an includePdb whose value is not a literal, or, for includePdb: true, a platform section the codemod cannot read or a root fileOptions.excludedExts with an element it cannot read (a spread, an identifier, a call; readable platform lists still get "!pdb").
It prints an advisory (without changing the config) for runtime defaults and behavior changes you should check: an nsis-web target (disableWebInstaller), nsis.perMachine or nsisWeb.perMachine set to true (per-machine NSIS updates), a custom win.sign.sign hook without win.sign.publisherName, unless win.verifyUpdateCodeSignature is false (publisher name), a win.sign.publisherName entry that is not a distinguished name, e.g. a bare name (publisher name DN), win.sign: false / null or win.sign.publisherName: null, unless win.verifyUpdateCodeSignature is false (missing publisher name), a generic publish configuration whose url has a query string (update credentials), a fileOptions.files pattern that names .pdb files (includePdb → fileOptions.excludedExts), and a mac/mas/masDev section that names no entitlements file (tightened default entitlements).
It does not touch anything outside the config: CLI flags, environment variables, custom NSIS scripts, Linux maintainer scripts, app code using the electron-updater API, or plugins using PlatformPackager. Every change on the Build, Runtime and Developer pages is a manual step.