Skip to content
cccskills
FreePublished on GitHub

desktop-updates-electron-updater

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

The English summary is being prepared. Showing the original description.

Works withAWS
See how to install

Files included (6)

  • SKILL.md13.4 KB
  • examples/channels-and-rollouts.md5.8 KB
  • examples/core.md10.4 KB
  • examples/testing.md6.3 KB
  • metadata.yaml649 B
  • reference.md9.8 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

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

(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.


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.


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 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 enables allowDowngrade

Key point: Users on alpha receive alpha, beta, and stable releases. Users on beta receive beta and stable. Users on latest (stable) only receive stable releases. See examples/channels-and-rollouts.md.


Pattern 5: Staged Rollouts

Roll out updates gradually by setting stagingPercentage in your metadata YAML file. The updater assigns each installation a persistent random ID and compares it against the percentage.

# latest.yml (manually edited after publishing)
version: 2.1.0
stagingPercentage: 10 # Ship to 10% of users first

Key point: Increment the version when pulling a broken staged release -- users already on the broken version will not downgrade to the same version number. See examples/channels-and-rollouts.md.


Pattern 6: Error Handling and Retry

Network failures during update checks are common. Wrap retry logic around the check and always handle the error event.

const MAX_RETRIES = 3;
const RETRY_DELAY_MS = 30_000; // 30 seconds

autoUpdater.on("error", (error) => {
  log.error("Auto-update error:", error.message);
  // Notify renderer for user-facing feedback
  mainWindow.webContents.send("update-error", error.message);
});

Key point: The error event fires for network failures, signature verification failures, and corrupted downloads. Never ignore it -- unhandled errors in the updater crash the main process. See examples/core.md for retry with exponential backoff.


Pattern 7: Testing Locally

Use dev-app-update.yml and forceDevUpdateConfig to test the update flow without packaging.

# dev-app-update.yml (project root)
provider: generic
url: http://localhost:8080/updates
if (!app.isPackaged) {
  autoUpdater.forceDevUpdateConfig = true;
}

Key point: You still need a local HTTP server serving the update artifacts (installer + latest.yml). Minio is commonly used as a local S3-compatible server for this purpose. See examples/testing.md.

</patterns>

<decision_framework>

Decision Framework

Which Update Approach?

Building with electron-builder?
+-- YES --> Use electron-updater (this skill)
+-- NO  --> Building with Electron Forge?
    +-- YES --> Using Squirrel maker?
    |   +-- YES --> Use Electron's built-in autoUpdater module
    |   +-- NO  --> Can use electron-updater with custom config
    +-- NO  --> Distributing via app store?
        +-- YES --> Use the store's native update mechanism
        +-- NO  --> Use electron-updater with generic provider

Which Provider?

Where are your releases hosted?
+-- GitHub Releases (public or private repo)
|   +-- Use provider: github
+-- AWS S3 or compatible (MinIO, Backblaze B2)
|   +-- Use provider: s3
+-- DigitalOcean Spaces
|   +-- Use provider: spaces
+-- Any HTTP(S) server (Nginx, CDN, custom)
|   +-- Use provider: generic
+-- Keygen (license-gated updates)
    +-- Use provider: keygen

autoDownload: true vs false?

Should updates download automatically?
+-- App is small (<50 MB) and users expect seamless updates?
|   +-- autoDownload: true (default) + checkForUpdatesAndNotify()
+-- App is large or users are on metered connections?
|   +-- autoDownload: false + show download prompt in UI
+-- Enterprise environment with IT-managed rollouts?
    +-- autoDownload: false + admin-controlled trigger

</decision_framework>


Detailed resources:


<red_flags>

RED FLAGS

Critical Issues:

  • Calling checkForUpdates() or checkForUpdatesAndNotify() outside app.isPackaged guard -- causes errors and unnecessary network calls in development
  • Not handling the error event on autoUpdater -- unhandled update errors crash the main process
  • Shipping unsigned macOS builds -- auto-update silently fails without code signing
  • Calling quitAndInstall() immediately without user confirmation -- forces restart, risks data loss
  • Using Electron's built-in autoUpdater module instead of importing from electron-updater -- different API, different behavior, no Linux support

Architecture Issues:

  • Running update logic in the renderer process -- electron-updater must run in the main process only
  • Checking for updates on every app launch without a cooldown -- hammers the update server, especially with large user bases
  • Not using autoInstallOnAppQuit when autoDownload is true -- users never get the update if they don't explicitly restart
  • Mixing Squirrel.Windows and NSIS updater patterns -- they are incompatible (Squirrel uses .nupkg delta files, NSIS uses blockmap-based differential downloads)

Staged Rollout Mistakes:

  • Setting stagingPercentage: 0 expecting it to block all updates -- behavior is undefined at 0; use channels for access control instead
  • Not incrementing version when pulling a broken staged release -- users already on the broken version stay there
  • Editing stagingPercentage in latest.yml without re-signing -- signature validation fails

Common Mistakes:

  • Forgetting generateUpdatesFilesForAllChannels: true when using beta/alpha channels -- only the current channel's YAML is generated
  • Using allowPrerelease: true on the client instead of proper channels -- allowPrerelease only works with GitHub provider and is less predictable than channels
  • Not setting autoUpdater.logger during debugging -- update failures are silent without logging configured
  • Hardcoding update URLs instead of using electron-builder publish config -- the build process auto-generates correct metadata only when publish is configured

Gotchas & Edge Cases:

  • checkForUpdatesAndNotify() returns null when app.isPackaged is false -- it silently skips in dev
  • Differential downloads (blockmap) only work for NSIS on Windows -- macOS and Linux always do full downloads
  • quitAndInstall(true) (silent mode) only works on Windows NSIS -- macOS ignores the isSilent parameter
  • The download-progress event does not fire when differential download is used -- only fires for full downloads
  • On Windows, the updater verifies the code signature of the downloaded installer by default (verifyUpdateCodeSignature) -- unsigned updates are rejected
  • setFeedURL() overrides the provider from electron-builder config at runtime -- useful for switching environments but can cause confusion if called unintentionally

</red_flags>


<critical_reminders>

CRITICAL REMINDERS

(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)

Failure to follow these rules will cause silent update failures, crashes, or data loss for end users.

</critical_reminders>

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

More skills from this repository

Hugging Face Inference SDK patterns for TypeScript/Node.js — InferenceClient setup, chat completion, text generation, streaming, embeddings, image generation, audio transcription, translation, summarization, and Inference Endpoints

The English summary is being prepared. Showing the original description.

agents-inc/skills25Updated Oct 17, 2026

LiteLLM proxy server setup, TypeScript client patterns via OpenAI SDK, model routing, fallbacks, load balancing, spend tracking, virtual keys, and production deployment

The English summary is being prepared. Showing the original description.

agents-inc/skills25Updated Oct 17, 2026

Serverless GPU compute platform for AI model deployment — web endpoints, GPU functions, model serving, and TypeScript client patterns

The English summary is being prepared. Showing the original description.

agents-inc/skills25Updated Oct 17, 2026

Local LLM inference with the Ollama JavaScript client -- chat, streaming, tool calling, vision, embeddings, structured output, model management, and OpenAI-compatible endpoint

The English summary is being prepared. Showing the original description.

agents-inc/skills25Updated Oct 17, 2026

Replicate SDK patterns for TypeScript/Node.js -- client setup, predictions, streaming, webhooks, file handling, model versioning, deployments, and training

The English summary is being prepared. Showing the original description.

agents-inc/skills25Updated Oct 17, 2026

Together AI SDK patterns for TypeScript — client setup, chat completions, streaming, structured output, function calling, embeddings, image generation, fine-tuning, and OpenAI-compatible endpoints

The English summary is being prepared. Showing the original description.

agents-inc/skills25Updated Oct 17, 2026

See all skills by agents-inc

Report a problem with this skill