Back to Home

Electron Guide - Cross-Platform Desktop Apps

Auto-Updates

Ship updates confidently. Auto-updates keep users on the latest version without manual downloads— critical for security patches and feature releases.

Desktop apps don't have the luxury of "just refresh the page." Users run old versions for months unless you make updates frictionless. Auto-updates solve this—your app checks for updates, downloads in the background, and installs on next launch.

How Auto-Updates Work

The update flow is straightforward: check for updates → download if available → install on restart. The complexity is in the details: differential updates, rollback handling, and user experience.

Check

Query update server

Download

Background download

Verify

Check signature

Install

On next restart

🎯 VibeBlaster Update Strategy

VibeBlaster checks for updates on launch and every 4 hours. Downloads happen silently in the background. When ready, users see a subtle notification: "Update available. Restart to install." No forced restarts, no interruptions.

For critical security patches, I use a more prominent banner—but still let users choose when to restart.

Setting Up electron-updater

electron-updater is the standard solution. It works with GitHub Releases, S3, or any static file server. Configuration lives in your package.json or electron-builder config.

Installation

npm install electron-updater

Included with electron-builder. Handles differential updates, code signing verification, and platform-specific installers.

Update Providers

  • GitHub Releases - Free, easy setup
  • S3/Spaces - More control, private
  • Generic server - Any static host
  • Private server - Full control

Configuration

Add publish configuration to your package.json. This tells electron-updater where to check for updates.

// package.json
{
  "build": {
    "appId": "com.yourcompany.yourapp",
    "publish": {
      "provider": "github",
      "owner": "your-username",
      "repo": "your-repo"
    }
  }
}

Basic Implementation

The update logic lives in your main process. Listen for events and communicate with the renderer to show progress and prompt for restart.

import { autoUpdater } from 'electron-updater';

// Configure behavior
autoUpdater.autoDownload = false;  // Let user choose
autoUpdater.autoInstallOnAppQuit = true;

// Check on launch (after 3 second delay)
app.whenReady().then(() => {
  setTimeout(() => autoUpdater.checkForUpdates(), 3000);
});

// Handle events
autoUpdater.on('update-available', (info) => {
  // Notify renderer: "Update v{info.version} available"
  mainWindow.webContents.send('update-available', info);
});

autoUpdater.on('download-progress', (progress) => {
  // Send progress to renderer for UI
  mainWindow.webContents.send('download-progress', progress.percent);
});

autoUpdater.on('update-downloaded', () => {
  // Notify renderer: "Ready to install"
  mainWindow.webContents.send('update-ready');
});

// IPC handler for user-initiated install
ipcMain.on('install-update', () => {
  autoUpdater.quitAndInstall();
});

Update UX: Don't Be Annoying

The worst update experiences interrupt users mid-task. The best are invisible until the user is ready. Download silently, notify subtly, let users choose when to restart.

❌ Bad UX

  • • Modal popup interrupting work
  • • Forced restart without warning
  • • "Update now or quit" ultimatums
  • • Download blocking the UI
  • • No progress indication

✅ Good UX

  • • Subtle notification badge/banner
  • • "Restart when you're ready"
  • • Background download
  • • Progress bar if user wants to see it
  • • Release notes available

Update Notification Pattern

Show a non-intrusive banner when an update is ready. Include version number and what's new. Let users dismiss or install.

Version 2.1.0 is ready to install

New: Dark mode, performance improvements

⚠️ Security Updates Are Different

For critical security patches, be more insistent. Show a prominent warning explaining the risk. Consider blocking certain features until updated. But still don't force-restart—give users time to save their work.

Release Channels & Staged Rollouts

Don't ship updates to everyone at once. Use channels (stable, beta) and staged rollouts (10% → 50% → 100%) to catch issues before they affect all users.

🟢 Stable

Production releases. Thoroughly tested. Default for all users.

channel: 'latest'

🔵 Beta

Pre-release features. Opt-in users help find bugs before stable.

channel: 'beta'

🟣 Alpha

Internal testing. Unstable, may break. Developers only.

channel: 'alpha'

Staged Rollout Strategy

Roll out to a percentage of users first. Monitor crash reports and feedback. If issues arise, pause the rollout before it affects everyone.

Day 1: 10%
Day 3: 50%
Day 7: 100%

💡 Differential Updates

electron-updater supports differential updates—only downloading changed files instead of the full app. A 120MB app might have a 5-20MB update. Enable with differentialDownload: true. Faster downloads, happier users.

When Updates Go Wrong: Rollback

Sometimes updates break things. You need a plan for when that happens—monitoring to detect issues, and a way for users to recover.

Detect Issues

  • Crash reporting - Sentry, Bugsnag
  • Health checks - App starts successfully?
  • User feedback - Support tickets spike?
  • Metrics - Usage patterns change?

Recovery Options

  • Pause rollout - Stop new installs
  • Hotfix - Ship fix as new version
  • Manual rollback - Link to previous version
  • Auto-rollback - Detect crash loops, revert

⚠️ The Crash Loop Problem

If an update causes the app to crash on startup, users are stuck—they can't open the app to download a fix. Implement crash detection: if the app crashes 3 times in a row on startup, offer to reinstall the previous version or reset to defaults.

Auto-Update Best Practices

Download in background, don't block UI
Let users choose when to restart
Show progress and release notes
Use staged rollouts for major releases
Code sign all releases (required for auto-update)
Monitor crash rates after each release
Have a rollback plan ready
Test updates on all platforms before release

Updates Are Just the Beginning

You can now ship updates confidently—users get new features and security patches without lifting a finger. Combined with staged rollouts, you can iterate quickly while catching issues early.

Next up: Testing. Before you can ship updates confidently, you need to know they work. Let's build a testing strategy that catches bugs before users do.