Major Changes
-
Feat!: nest
files,extraResourcesandextraFilesunderfileOptions#103198f55928—electron-builder,app-builder-lib,builder-util-runtimeThe three file-copy lists live in a
fileOptions?: FilesBuildOptions | nullproperty at the configuration root and in every platform section (mac,mas,masDev,win,linux), the same waydirectoriesgroups the build directories:fileOptions.files,mac.fileOptions.extraResources, and so on.PlatformSpecificBuildOptionsdoes not extendFilesBuildOptions, and the TypeScript types and the JSON schema only havefileOptions.Flat
files/extraResources/extraFileskeys in a config file, anextendsparent, a-c.files=…override or theconfigobject passed tobuild()are applied as theirfileOptionscounterparts before the configuration is validated, logging one warning per process that names the keys found and where they belong. When a flat key and itsfileOptionscounterpart are set on the same object,fileOptionswins and the build warns about the conflict. A CLI override or a parent config's flat key is merged withfileOptions. AfileOptionsthat is not an object (for example a list of globs written directly under it) fails the build with a message showing the nested form.Code that reads
files,extraResourcesorextraFilesfrom the loaded configuration (for example a hook readingcontext.packager.config.files, orbuildResult.configuration.extraResources) gets thefileOptionsvalue, with a warning per key: the loaded configuration and its platform sections forward these reads through non-enumerable properties, which stay out of the effective config,JSON.stringifyandObject.keys. Assigning them throws a configuration error naming thefileOptionsproperty to set instead.deepAssign(builder-util-runtime) copies only enumerable own properties, so the forwarding properties are never copied into merged options.electron-builder migrate-schema(static and JS/TS configs) moves flat keys underfileOptionsat the root and per platform. A flat key also set underfileOptionsis removed with a warning, since the build ignores it.See https://www.electron.build/docs/migration/v27-breaking-changes#file-options-fileoptions
-
Fix: confine linked files to the workspace and package-manager store by real path; opt in to external links with
fileOptions.allowExternalLinks. A file of the app (packed intoapp.asaror copied withasar: false) that is a symlink, or is reached through one, is packaged only when its real path is inside the workspace root, the project or app directory, or the package-manager store (pnpmstoreDir/virtualStoreDirfromnode_modules/.modules.yaml). Any other one, such as annpm linkor afile:dependency outside the workspace, fails withInvalidConfigurationError(codeERR_ELECTRON_BUILDER_FILE_OUTSIDE_WORKSPACE), which names the file, its real path and thefileOptions.allowExternalLinksentry that allows it (true, or a list of directories, relative to the project directory or absolute, that linked files may resolve into; at the top level or per platform; defaultfalse, with a one-time warning when it allows a link). See https://www.electron.build/docs/contents#linked-files-must-resolve-inside-the-workspace#1032108e8044—app-builder-lib -
Fix: confine copies to the app output directory by real path, so that a symlink among copied files (app directory,
extraResources/extraFiles/extraDistFilessources,node_modules) cannot make electron-builder write or package files elsewhere on the build machine; opt in to external links withfileOptions.allowExternalLinks.copyDir(extraResources/extraFiles) and theasar: falseapp copy refuse a destination whose directory resolves outside the app output directory, replace (never follow) a symlink at a destination file, and recreate a symlink only when it stays inside the output (or, for extraResources/extraFiles, leads into the workspace or the package-manager store, with a one-time warning). The fixed-name files written after the copies (app-update.yml,package-type,apparmor-profile, NSISelevate.exe, the snapcommand.sh,Squirrel.exeand the Squirrel execution stub) replace a symlink at their name instead of writing through it. Windowszip/7zarchives, the NSIS app package, AppX/MSIX and Squirrel.Windows packages, which store what a symlink points to, refuse a symlink that leaves the app. An intended symlink of this kind is allowed by thefileOptions.allowExternalLinksbuild option (true, or a list of directories its real target may be in; at the top level or per platform, a platform's value replacing the top-level one), with a one-time warning; a write through a symlink is always refused. Errors areInvalidConfigurationErrorwith codeERR_ELECTRON_BUILDER_PATH_OUTSIDE_ROOT, suggest thefileOptions.allowExternalLinksentry and link to https://www.electron.build/docs/contents#symlinks-that-leave-the-app-are-refused. New builder-util helpers:assertWritableWithin,prepareFixedNameWrite,WriteContainment,resolvePhysicalPath,findEscapingSymlinks,assertNoSymlinkLeaves,ExternalLinkPolicy.#1032108e8044—app-builder-lib,builder-util,electron-builder-squirrel-windows -
Feat(flatpak): build bundles with
flatpakandflatpak-builderdirectly, without@malept/flatpak-bundler, and build in unprivileged containers#103163f1d50b—app-builder-libThe flatpak target now runs
flatpakandflatpak-builderitself, and the@malept/flatpak-bundlerdependency is removed. A failed command prints the tool's output in the build error, and five known failures (Failure spawning rofiles-fuse, abwrap:failure inflatpak build-export,No remote refs found,Command 'electron-wrapper' not foundwhen rofiles-fuse cannot mount the app directory, andexecvp appstream-composewhen aflatpak-builderolder than 1.4 composes AppStream metadata with the freedesktop SDK 24.08 or newer) log how to fix them first. A build withflatpak.moduleswarns once whenflatpak-builderis older than 1.4.4, which the 24.08 and newer SDKs recommend for meson and cmake modules. The scratch directory is removed when the build ends.New options:
flatpak.additionalArgspasses extra arguments to the tools, by tool:flatpakBuilder,buildExportandbuildBundle. With{ flatpakBuilder: ["--disable-rofiles-fuse"], buildExport: ["--disable-sandbox"] }the target builds in CI containers that have neither FUSE nor user namespaces (#10306).flatpak.installOrUpdateRefs,"all"(the default) or a list of"runtime","sdk"and"base": the refs that are left out are used as installed, without aflatpak installorflatpak update, and a missing one fails the build before anything is downloaded.[]builds with the refs of an image or an offline machine, and where the build user cannot update the base app (based on the options proposed in #10313).
BREAKING CHANGE:
flatpak>= 1.12.4 andflatpak-builder>= 1.2.2 are required, and checked before a runtime is installed. The stock packages of Ubuntu 22.04, Debian 12, RHEL 8 and 9 and newer releases meet this; v26 accepted older tools.DEBUG=@malept/flatpak-bundlerno longer has any effect, and a flatpak build warns once whenDEBUGstill names it: useDEBUG=electron-builderto log every command.BREAKING CHANGE:
flatpak.runtimeVersionandflatpak.baseVersiondefault to26.08instead of20.08, which Flathub reports as end-of-life. A build that sets neither is built for the26.08runtime, and the build machine installs the26.08runtime, SDK and base app if they are missing (about 3.2 GB). A build that leaves either option unset warns once, naming electron-builder v27 and the migration guide. Set both to"20.08"to keep the previous ones.BREAKING CHANGE: the default
flatpak.finishArgsgrant--filesystem=xdg-downloadinstead of--filesystem=home: with read/write access to the home directory, code running in the app could write~/.config/autostartor~/.bashrcand so run outside the sandbox at the next login. App data under~/.var/appand files picked in a dialog are not affected; paths the app opens on its own outside Downloads are. They also leave out--talk-name=org.freedesktop.Notificationsunless the base isorg.electronjs.Electron2.BaseAppolder than23.08, whose libnotify predates the notification portal; on desktops without a portal backend for notifications, notifications no longer appear. Builds that setflatpak.finishArgsare not affected, and a build that uses the defaults warns once, naming electron-builder v27 and the migration guide. To keep the v26 permissions, setfinishArgsto the v26 list from the migration guide.BREAKING CHANGE: a
flatpak.filesdestination or aflatpak.symlinkslink that leaves the app prefix with..fails the build with anInvalidConfigurationError, before anything is installed. It was written outside the app in the build directory, for example over the app'smetadata. The pairs offlatpak.filesare copied one after another, and a directory can no longer be copied onto a symlink to a directory: v26 copied through the link, and the build now fails withCannot overwrite non-directory with directory(ERR_FS_CP_DIR_TO_NON_DIR). Symlinks inside a copied directory are kept as they are. The errors of the tool-version check and of the app-prefix check say that they are new in electron-builder v27 and link the migration guide.
Minor Changes
-
Feat(app-builder-lib): warn at build start when a
process.envvariable removed in v26 → v27 is still set#10293d2c979b—app-builder-lib- Added
warnOnRemovedEnvVars()(registry inapp-builder-lib/src/util/removedEnvVars.ts), invoked once per build from thePackagerconstructor so both the CLI and programmaticbuild()API surface the same guidance. When a removed variable is still present in the environment it is otherwise silently ignored — this logs a one-time deprecation warning naming the variable and its replacement. - Covers the removed toolset-path overrides (
APPIMAGE_TOOLS_PATH,MKSQUASHFS_PATH,LINUX_TOOLS_MAC_PATH,CUSTOM_FPM_PATH,ELECTRON_BUILDER_NSIS_DIR,ELECTRON_BUILDER_NSIS_RESOURCES_DIR,CUSTOM_NSIS_RESOURCES,ELECTRON_BUILDER_WINE_TOOLSET_DIR,ELECTRON_BUILDER_7ZIP_PATH,ELECTRON_BUILDER_ICONS_TOOLSET_DIR,ELECTRON_BUILDER_OSSL_SIGNCODE_PATH,ELECTRON_BUILDER_RCEDIT_PATH,ELECTRON_BUILDER_WINDOWS_KITS_PATH,SIGNTOOL_PATH) →toolsets.*/win.sign; theUSE_SYSTEM_*toggles;ELECTRON_BUILDER_BINARIES_ALLOW_HTTP→ELECTRON_BUILDER_DANGEROUSLY_ALLOW_HTTP;CI_BUILD_TAG→CI_COMMIT_TAG; andALLOW_ELECTRON_BUILDER_AS_PRODUCTION_DEPENDENCY→ignoredProductionDependencies. - Internal/test-only variables (
JEST_WORKER_ID,TEST_SET_BABEL_PRESET) andnpm_lifecycle_event(set by npm for every script) are intentionally excluded from the runtime scan. - Migration docs: filled the previously undocumented removed vars in the v27 breaking-changes catalogue (the toolset-path family plus
MKSQUASHFS_PATH), added a "Replace with" column, and documented theELECTRON_BUILDER_BINARIES_ALLOW_HTTPrename and the removednpm run releaseimplicit-publish behavior.
- Added
-
Feat(builder-util):
log.limit({ key, max, scope })/log.once(key, scope)emit a keyed message at most N times (per process, or per scope object), replacing hand-rolled "already warned" flags; electron-updater counts once-per-updater warnings internally without changing the injectableLoggerinterface. Both share one limiter (wrap()on any{ info, warn, error, debug? }logger, includingconsole), and itsLogLevel,LogLimitOptions,LoggerLikeandLimitedLoggertypes are now exported from builder-util-runtime (builder-util re-exports them)#103025cbbc8d—electron-builder,app-builder-lib,builder-util,builder-util-runtime -
Fix(asar):
asar.orderingis now honored — the documented option was typed but never applied to the archive electron-builder packs (it packs through@electron/asar's stream API, which takes no ordering option). Listed files are packed first, in the order of the file (same line syntax as@electron/asar: optional leading/or<count>:prefix, blank lines ignored), directories keep their positions, everything else follows in its original order; coverage is logged.#103108eff005—app-builder-lib -
Feat(snap):
"default"insnapcraft.core24.plugsnow merges the remaining entries into the full default plug set (includingbrowser-supportand, without thegnomeextension, the content-snap plugs), deduplicated by name, with descriptor objects overriding a default plug's attributes#10294efec238—app-builder-lib -
Feat(flatpak): warn about
--no-sandboxand the flatpak id, and fix the wrapper,useWaylandFlags, MIME types and failed builds#103163f1d50b—app-builder-lib- Warns once per build when
--no-sandboxreaches the flatpak'selectron-wrapper, naminglinux.executableArgsand/orflatpak.executableArgsas its source: inside flatpak, Chromium's sandbox works through zypak, and the flag gives renderer processes every permission of the app. The flag is kept.linux.executableArgsare merged into the flatpak options, and an emptyflatpak.executableArgsadds nothing:--no-sandboxfor the AppImage alone belongs inappImage.executableArgs, andflatpak.executableArgs: nullleaves all oflinux.executableArgsout of the flatpak. - Warns once per build when the flatpak id is derived from the package name (neither
linux.appIdnorappIdis set: the id names the app's~/.var/app/<id>data directory, and another vendor's bundle with the samecom.electron.<name>id installs over the app), and whendesktopNameis set but is not<flatpak id>.desktop(the bundle's desktop entry is named after the id, and Electron names the app's windows afterdesktopName, so desktops cannot match the two). - The
electron-wrapperscript replaces itself with the app (exec) instead of staying as its parent shell, and tests the session with the POSIX=: the==failed with "unexpected operator" where/bin/shis dash, and dropped the Wayland flags. flatpak.useWaylandFlagspicks its flags by Electron version: none from Electron 38, which chooses Wayland by itself in a Wayland session (the build logs that the option has no effect),--ozone-platform=waylandfrom Electron 16, and--enable-features=UseOzonePlatform --ozone-platform=waylandbefore that or for an unknown version. From Electron 16 the wrapper no longer adds a second--enable-features, which could replace one inexecutableArgs; a build with Electron 16 to 37 warns once about the change, naming electron-builder v27 and the migration guide.- An invalid flatpak id (fewer than three elements, an empty element or one starting with a digit, more than 255 characters), such as
com.myapporcom.electron.3d_viewerfrom a package named3d-viewer, fails the build before the runtime, SDK and base app are installed, with anInvalidConfigurationErrornaming the rule. It failed inflatpak-builder, after those were installed (about 3.2 GB for the default version). - The
__flatpak-<arch>stage directory is removed from the output directory when preparing it fails, for example on an invalid desktop entry or a missing license file. - The MIME types of
fileAssociations(everymimeTypethat is set) are declared in the bundle'sshare/mime/packages/<id>.xml, which flatpak exports, as the AppImage and deb/rpm targets do: the desktop entry listed the types, but nothing defined a custom one. SetmimeTypeonly for a type of your own: each is declared with the description<productName> document, which for a standard type such astext/markdowncan change how the desktop describes every such file. List standard types inlinux.mimeTypes, which only adds them to the desktop entry.
- Warns once per build when
-
Feat(asar):
asar.contentAlignment— align the start of every packed file's content insideapp.asarto a multiple of N bytes (zero padding between files; order, sizes and per-file integrity unchanged). Meant for differential updates withnsis.differentialPackage: "store-asar": the asar header stores absolute content offsets, so without alignment a change that grows a file by one byte shifts every later offset and most of the header is re-downloaded; with512a small length-changing edit measured 414 KB → 139 KB of differential download for 2.2 % more asar size. Off by default.#10311a4ff5db—app-builder-lib
Patch Changes
-
Chore(deps): update @electron/___ dependencies to
latest#10244a49daae—app-builder-lib -
Fix: encode GitLab publisher package path segments
#101404b6e63f—electron-publish -
Fix: escape Squirrel project URLs in nuspec XML
#1014109a2f30—electron-builder-squirrel-windows -
Fix: stop retry backoff immediately when cancelled
#1012668aa2ff—builder-util-runtime -
Fix(appimage): resolve a
toolsets.appimageversion pin to exactly that release instead of letting any pin other than"1.0.3"float to the newest bundle, and reject unknown versions with anInvalidConfigurationErrorrather than downloading without a checksum#1029186298ab—app-builder-lib -
Fix(snap): pack legacy-base (core18/core20/core22) template snaps with the
mksquashfsfromtoolsets.appimageinstead of the hardwired legacy"0.0.0"bundle, whose mksquashfs supports only gzip/xz, socompression: "lzo"(andlinux.compression: "store", which maps to lzo) builds again (#7013); atoolsets.appimage: "0.0.0"pin combined withlzonow fails early with anInvalidConfigurationErrorinstead of insidemksquashfs#1029186298ab—app-builder-lib -
Fix(nsis): the installer copies itself into
%LOCALAPPDATA%\<app>-updateronly when the app has anapp-update.yml. Before, every install kept that copy, which only electron-updater reads (as the base for a differential download), so apps without an update configuration carried a second copy of their installer, and the uninstaller left it behind. After, those apps get no copy; apps with an update configuration keep it as before.#102610df65dc—app-builder-lib -
Fix(nsis): log once when the installer skips keeping its copy for electron-updater's differential download cache because
resources/app-update.ymlwas not found#1029838fe001—app-builder-lib -
Fix(nsis): point the removed
customNsisBinary/customNsisResourcesbuild error andmigrate-schemawarning at the custom NSIS migration guide and thetoolsets.nsisbundle docs, and fix their stale breaking-changes anchor#102867e42d2f—app-builder-lib -
Fix: retry an Electron/toolset download that times out instead of failing the build. Before, a silent connection ended in undici's 300s headers/body timeout, which was not treated as retryable, and the 10 minute cap on a download was one
AbortSignal.timeout()shared by all attempts, so no attempt could follow it. After, each attempt gets its own 10 minute cap, and an attempt that hits it or undici's timeouts is retried once, with a warning in the log.#10269e7d9cad—app-builder-lib -
Fix(docs): repair broken links and anchors across the docs site and JSDoc, and export the
SnapOptions24,SnapOptionsLegacy,SnapOptionsCustomandRemoteBuildOptionstypes fromapp-builder-libso their API reference pages are generated#103052fdbcae—app-builder-lib,builder-util-runtime -
Refactor: once-only build and updater warnings use
log.once/log.limit(and the updater's per-instance counter) instead of hand-rolled flags and sets; a concurrently resolved NSIS ProgID notice can no longer print twice#103036fe881e—app-builder-lib -
Fix: reject shell line-break characters
#101318854be3—builder-util -
Fix: honor uppercase http(s) proxy environment variables
#10132ea41d9a—builder-util -
Fix: reject aborted S3 upload responses
#1014580c9c3f—app-builder-lib,electron-publish -
Fix: enforce workspace path boundaries for asar
#10135ed43b10—app-builder-lib -
Fix: accept forward slashes in isOutsidePath on Windows
#103070dffd5b—app-builder-lib -
Fix: bump @electron/rebuild to 4.2.1 so cross-platform builds from one node_modules no longer reuse a native module built for another platform (#10031)
#10308067913d—app-builder-lib -
Fix(asar): a missing
asar.orderingfile now fails with a configuration error naming the paths tried and the v27 migration notes, builds that apply an ordering file warn once that the option is now honored, ordering lines with\separators match on macOS and Linux, and lines naming a directory no longer count as missing in the coverage log#10320866bb00—app-builder-lib -
Fix: contain mapped app file destinations
#10137bb6b24c—app-builder-lib -
Fix(snap): core24 no longer requests
browser-supportwithallow-sandboxby default (the Snap Store rejects it for non-vetted publishers); default core24 snaps now launch with--no-sandboxand omitchrome-sandbox, and an explicitly configuredallow-sandboxlogs a store-review warning#10294efec238—app-builder-lib -
Docs(blockmap): state the regions size/sha512 guarantee for file-output mode only
#10325d2af5d1—app-builder-lib -
Fix(linux): validate
.desktopentry keys and values before writing them, for every Linux target#103163f1d50b—app-builder-libThe desktop entry of every Linux target that writes one is checked before it is written, so a configuration can no longer produce a corrupt
.desktopfile. The build fails with anInvalidConfigurationErrornaming the group and the key for a value with\ror\ninside it (fromlinux.desktop.entry,desktopActions,linux.category,linux.mimeTypes,fileAssociationsorprotocols), whose second line would become a new key or group of the file; a key that GLib, which most desktops read the file with, rejects (empty, or with=, a line break, or brackets other than a trailing locale such asName[de]), which makes it ignore the whole file; and adesktopActionsname with[,]or a control character. Write such a value on one line, with a newline in a string value as\n. Line breaks at the end of a value, as in a YAML block scalar, are dropped, and values are otherwise still written as given, so escapes such as\;keep working. Keys that the specification does not allow but desktop environments read, such asX_Foo, are kept. -
Fix(snap): stop deleting
chrome-sandboxfrom the sharedlinux-unpackeddir when building a core18/core20/core22 template snap. The delete raced the other Linux targets, so a deb, rpm or AppImage built in the same run could ship withoutchrome-sandbox(no SUID sandbox fallback), and AppImage could fail withENOENT. The snap still omitschrome-sandbox; themksquashfsinput list already filters it out.#10327798adc4—app-builder-lib
Full Changelog: https://github.com/electron-userland/electron-builder/compare/electron-builder@27.0.0-alpha.10...electron-builder@27.0.0-alpha.11