Skip to content

/desktop-updates-electron-updater

Cross-platform auto-update patterns with electron-updater (electron-builder ecosystem)

shell
$ npx -y skills add agents-inc/skills --skill desktop-updates-electron-updater --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.
  • You can call itInvoke it directly when you want it.
  • Slash command/desktop-updates-electron-updater
How auto-invocation works

Context preview

The summary Claude sees to decide when to auto-load this skill.

Cross-platform auto-update patterns with electron-updater (electron-builder ecosystem)

SKILL.md

desktop-updates-electron-updater.SKILL.md
name: desktop-updates-electron-updater
description: Cross-platform auto-update patterns with electron-updater (electron-builder ecosystem)

Electron Auto-Update Patterns

> **Quick Guide:** Use `electron-updater` (from electron-builder) for cross-platform auto-updates. It supports macOS (DMG), Windows (NSIS), and Linux (AppImage/DEB/RPM). Configure a provider (GitHub, S3, generic server) in your `electron-builder` config. The updater emits lifecycle events: `checking-for-update` -> `update-available` -> `download-progress` -> `update-downloaded`. Set `autoDownload: false` for manual download control. Use channels (`latest`/`beta`/`alpha`) for staged releases and `stagingPercentage` for gradual rollouts. Code signing is mandatory on macOS and strongly recommended on Windows.

---

<critical_requirements>

CRITICAL: Before Using This Skill

> **All code must follow project conventions in CLAUDE.md** (kebab-case, named exports, import ordering, `import type`, named constants)

**(You MUST guard update checks with `app.isPackaged` -- calling `checkForUpdates()` in development causes confusing errors and network calls to non-existent endpoints)**

**(You MUST handle the `error` event on the updater -- unhandled update errors crash the main process)**

**(You MUST code-sign macOS builds -- unsigned apps cannot auto-update and the updater silently fails)**

**(You MUST NOT call `quitAndInstall()` without confirming the user's intent -- forcing a restart mid-work causes data loss)**

**(You MUST use named constants for all intervals and timeouts -- no magic numbers in `setInterval` or retry logic)**

</critical_requirements>

---

**Auto-detection:** electron-updater, autoUpdater from electron-updater, checkForUpdates, checkForUpdatesAndNotify, update-available, update-downloaded, download-progress, quitAndInstall, autoDownload, stagingPercentage, dev-app-update.yml, NsisUpdater, MacUpdater, AppImageUpdater, setFeedURL, allowPrerelease, allowDowngrade, forceDevUpdateConfig, disableDifferentialDownload

<philosophy>

**When to use:**

  • Implementing auto-updates in Electron apps built with electron-builder
  • Configuring update providers (GitHub Releases, S3, generic HTTP server)
  • Setting up update channels for beta/alpha testing
  • Implementing staged rollouts with percentage-based distribution
  • Controlling download behavior (manual download, progress tracking)
  • Handling update errors with retry strategies
  • Testing the update flow locally during development

**When NOT to use:**

  • Apps packaged with Electron Forge using Squirrel (use Electron's built-in `autoUpdater` module instead)
  • Apps distributed exclusively through platform app stores (macOS App Store, Microsoft Store) -- those have their own update mechanisms
  • Apps that only need to check for updates and show a "download from website" link (no in-app update needed)

</philosophy>

---

<patterns>

Key Patterns

Pattern 1: Basic Setup with Lifecycle Events

Import `autoUpdater` from `electron-updater` (not Electron's built-in module). Wire up lifecycle events in the main process after the app is ready.

import { autoUpdater } from "electron-updater";

const CHECK_INTERVAL_MS = 4 * 60 * 60 * 1000; // 4 hours

function setupAutoUpdater(mainWindow) {
  if (!app.isPackaged) return; // Never check in development

  autoUpdater.on("update-available", (info) => {
    mainWindow.webContents.send("update-available", info);
  });

  autoUpdater.on("update-downloaded", (info) => {
    mainWindow.webContents.send("update-downloaded", info);
  });

  autoUpdater.on("error", (error) => {
    log.error("Update error:", error);
  });

  autoUpdater.checkForUpdatesAndNotify();
  setInterval(() => autoUpdater.checkForUpdates(), CHECK_INTERVAL_MS);
}

**Key point:** `checkForUpdatesAndNotify()` checks and shows a native OS notification when an update downloads. Use `checkForUpdates()` for silent checks when you handle UI yourself. See [examples/core.md](examples/core.md).

---

Pattern 2: Manual Download Control

Set `autoDownload: false` to let users decide when to download. This is essential for metered connections or large updates.

autoUpdater.autoDownload = false;

autoUpdater.on("update-available", (info) => {
  // Show UI prompt -- user decides whether to download
  mainWindow.webContents.send("update-available", info);
});

// User clicks "Download" in the renderer
ipcMain.handle("start-update-download", () => {
  return autoUpdater.downloadUpdate();
});

**Key point:** With `autoDownload: false`, the `download-progress` and `update-downloaded` events only fire after you explicitly call `downloadUpdate()`. See [examples/core.md](examples/core.md).

---

Pattern 3: Update Providers

Configure where the updater looks for releases. The provider is set in your `electron-builder` config file and can be overridden at runtime with `setFeedURL()`.

# electron-builder.yml -- GitHub provider (default if GH_TOKEN set)
publish:
  provider: github
  owner: my-org
  repo: my-app
# electron-builder.yml -- Generic HTTP server
publish:
  provider: generic
  url: https://releases.example.com/updates
# electron-builder.yml -- S3 bucket
publish:
  provider: s3
  bucket: my-app-releases
  region: us-east-1
  path: /releases

**Key point:** The first provider in the list is the auto-update source. Additional providers are publishing targets only. See [examples/core.md](examples/core.md) for runtime `setFeedURL()` override.

---

Pattern 4: Update Channels (Stable/Beta/Alpha)

Channels distribute pre-release versions to specific user groups. Append `-beta` or `-alpha` to your `package.json` version to produce channel-specific metadata files.

{ "version": "2.1.0-beta" }
# electron-builder.yml
generateUpdatesFilesForAllChannels: true
// Switch channel at runtime
autoUpdater.channel = "beta";
// Setting channel automatically en
Read more
Read it on GitHub ↗

Showing the first part of this file.

Ships withagents-inc-skills

The official skills marketplace for Agents Inc. 150+ skills covering everything from React and Prisma to Redis, ElevenLabs, and infrastructure tooling. Pick the skills that match your stack and install them via Claude Code. Need more control?

Get the whole plugin, auto-invoked