How Auto-Updating Works with electron-builder and electron-updater

Updated

electron-builder ships auto-update support through a companion library called electron-updater. The mechanism is: you publish a build plus update metadata to a provider (GitHub Releases, S3, and others), your packaged app checks that metadata on launch, downloads a newer version when one exists, and applies it on restart. It supports differential updates, staged rollouts, and multiple providers with minimal configuration. The main conditions for it to work are that your app is packaged by electron-builder, that you actually publish the artifacts and metadata somewhere the app can reach, and that the update feed is configured to point at that location.

The two halves: build-time and runtime

Auto-updating is split across two stages, and confusing them is the most common source of "it doesn't update" problems.

Stage Tool What it does
Build/publish electron-builder Produces installers, portable builds, and distribution-ready archives, plus the update metadata files the runtime reads
Runtime electron-updater Checks the feed, downloads the new version, and applies it

electron-builder's job is to make the artifacts and metadata exist. electron-updater's job is to consume them inside the running app. If either half is missing, nothing updates.

What electron-builder publishes

When you build for distribution, electron-builder generates the platform installers and archives, and alongside them the metadata that describes the latest version and where to get it. That metadata is what electron-updater fetches first — it is the "is there something newer?" answer, and it points at the actual update payload.

Because the metadata and the binaries are produced together by the same build, the version numbers and file references stay consistent as long as you publish the whole output rather than hand-picking files.

What electron-updater does at runtime

The runtime flow is a short sequence:

  1. Check — the app queries the configured provider for the latest metadata.
  2. Compare — electron-updater compares the published version against the running app's version.
  3. Download — if a newer version exists, it downloads the update. With differential updates, it can fetch only the changed portions rather than the entire package, which reduces download size.
  4. Apply — the update is installed and takes effect, typically on the next restart.

You control when checks happen (for example, on launch or on a schedule) and how the user is prompted, but the check → compare → download → apply sequence is the core loop.

Providers and staged rollouts

electron-updater is not tied to one hosting service. It supports multiple providers — GitHub Releases, S3, and more — so you can keep updates wherever your release process already lives. Switching providers is largely a configuration change rather than a rewrite of your update logic.

Staged rollouts let you release a new version to a subset of users first instead of everyone at once. This matters because an auto-update path is hard to reverse: if a bad build reaches all users simultaneously, they all break together. A staged rollout gives you a chance to catch problems on a smaller population before widening the release.

Code signing and notarization

Auto-updating interacts with platform trust requirements. electron-builder provides macOS notarization and Windows Authenticode signing out of the box, so users see trusted, verified apps. Signing is not just a polish step — an unsigned or improperly signed update can be rejected by the operating system, which means the update downloads but never successfully applies.

Common reasons auto-update fails

  • Metadata not published. The build succeeded locally but the update metadata never reached the provider, so the app always sees "no update."
  • Feed points at the wrong place. The configured provider or release channel doesn't match where you actually published.
  • Version not bumped. If the published version isn't higher than the running version, electron-updater correctly decides there's nothing to do.
  • Signing/notarization gaps. The download completes but the OS blocks installation.
  • Testing against a dev build. Auto-update is a packaged-app behavior; running from a development environment doesn't exercise the same path.

Deciding whether this fits your project

electron-updater is a reasonable choice if you already package with electron-builder and want updates delivered through infrastructure you control or already use (GitHub Releases, S3, and similar), with differential downloads and staged rollouts available without building a custom update system. It is less suited if you need a fully managed update service with its own dashboard, or if your distribution model doesn't involve publishing versioned artifacts to a reachable provider at all.