Electron-Updater Auto-Update Research
Feature fully implemented and released. This document is retained for historical context.
Date: 2026-02-13 Issue: #2065 - AppImage Update Info Status: Shipped in v2.7.6
Background
Issue #2065 requested embedding AppImage update metadata so third-party tools (Gear Lever, AppImageUpdate) could detect updates. This was implemented via post-processing with appimagetool (ADR-011), but the approach has a fundamental conflict: electron-builder uses its own proprietary update mechanism (electron-updater) that ignores the standard AppImage update information spec entirely. The two systems are incompatible, meaning the appimagetool post-processing adds metadata that no part of the electron-builder ecosystem reads.
This document investigates using electron-builder's native electron-updater module for in-app auto-updates instead.
How electron-updater Works
The update cycle follows four stages:
- Check — The app periodically (or on demand) queries a
latest-linux.ymlfile hosted alongside release assets. This YAML file contains the version, file name, SHA512 hash, and file size. - Download — If a newer version is found, the new AppImage is downloaded to a temporary location. The SHA512 hash is verified after download.
- Replace — The old AppImage file is replaced with the new one. On Linux, this is a simple file swap since AppImages are self-contained executables.
- Restart — The app relaunches from the new AppImage path.
The project already uses "provider": "github" with "releaseType": "draft" in its publish config, so electron-builder already generates and uploads latest-linux.yml during release builds. The infrastructure is largely in place.
Supported Formats
| Format | Support Level | Notes |
|---|---|---|
| AppImage | Stable | Full support — download, replace, restart. Most impactful target. |
| tar.gz | Stable | Same mechanism as AppImage (file replacement). |
| deb | Beta | Merged Nov 2022 (electron-builder PR #7060). Requires sudo/pkexec prompt. Immature. |
| rpm | Beta | Same as deb — requires elevated privileges, immature. |
| snap | N/A | Snap Store manages updates via snapd. Auto-update would conflict. |
| flatpak | N/A | Flatpak repos manage updates. Not applicable. |
The initial implementation should target AppImage only, since it has stable support and represents the distribution format where users most need auto-update (no package manager handling it for them).
Infrastructure Requirements
electron-updater with the GitHub provider requires no server infrastructure. The pieces are:
- GitHub Releases — Already used for publishing. Release assets serve as the download source.
latest-linux.yml— Auto-generated by electron-builder during--publish alwaysbuilds. Contains version, filename, SHA512 hash, and file size. Already being uploaded.- No custom server — The GitHub provider fetches
latest-linux.ymlfrom the GitHub Releases API directly. No update server to host or maintain.
The current "releaseType": "draft" configuration means releases start as drafts. electron-updater won't see a new version until the draft is published, which is actually desirable since it allows the maintainer to review release notes before users are notified.
Interaction with Distribution Channels
Auto-update must be disabled for distribution formats that have their own update channels. The updater should detect the packaging format at runtime:
- AppImage — Enable auto-update. Users have no package manager handling updates.
- snap — Disable.
snapdmanages updates through the Snap Store. - deb/rpm — Disable. Users typically manage updates through their package manager or manual downloads. The beta
deb/rpmupdater requiringsudoprompts would be confusing. - tar.gz — Could enable, but low priority since tar.gz users likely prefer manual management.
Detection can use process.env.APPIMAGE (set automatically when running from an AppImage) or check the app path for .AppImage extension.
Metrics and Analytics
electron-updater has no built-in analytics or telemetry. Options for tracking update adoption:
- GitHub Releases API — Exposes per-asset
download_count. This gives a proxy for how many users downloaded each version, though it doesn't distinguish new installs from updates. - No migration tracking — There's no way to know which version a user upgraded from without a custom analytics server, which would add complexity disproportionate to the value.
- Manual monitoring — Watch GitHub release download counts after publishing to gauge adoption speed.
For a project of this scale, GitHub download counts are sufficient. Building custom analytics infrastructure is not justified.
Implementation Reference: Vesktop
Vesktop (an Electron-based Discord client) provides a clean reference implementation in its updater.ts. Key patterns worth adopting:
- Conditional initialization — Only initializes the updater when running as AppImage (checks
process.env.APPIMAGE). - User-controlled updates — Shows a notification when an update is available; doesn't force-restart.
- Error handling — Catches update errors gracefully and logs them without crashing the app.
- Menu integration — Adds "Check for Updates" to the app menu.
UX Considerations
The update experience should respect user agency:
- Prompted, not silent — Show a notification or dialog when an update is available. Let the user choose when to restart.
- "Check for Updates" menu item — Allow manual checks from the application menu or tray menu.
- Update on quit — Offer to apply the update when the user closes the app, avoiding mid-session disruptions.
- No forced restarts — Never restart without user consent, especially during active calls or meetings.
- Version info — Show the current and available version in the update prompt so users can make informed decisions.
Security Considerations
- SHA512 validation — electron-updater verifies the SHA512 hash from
latest-linux.ymlagainst the downloaded file. This prevents tampered downloads. - No code signing on Linux — Linux doesn't have a standard code signing mechanism like macOS or Windows. The SHA512 check is the primary integrity guarantee.
- HTTPS transport — GitHub Releases are served over HTTPS, preventing man-in-the-middle attacks on the download.
- Draft release workflow — Since releases start as drafts, there's a review window before users are notified. This prevents accidental publication of broken releases.
Risks
- File permission issues — If the AppImage file permissions change (e.g., user moves it to a root-owned directory), the updater may fail to replace it. Error handling should detect this and inform the user.
- AppImage path changes — If the user renames or moves the AppImage between updates, the updater may lose track of the file.
process.env.APPIMAGEprovides the current path at runtime, mitigating this. - Draft release workflow — The current
"releaseType": "draft"config meanslatest-linux.ymlreferences a draft release. electron-updater may not find drafts via the public API. This needs testing — the maintainer may need to publish releases (or use pre-release) for auto-update to work. - Disk space — The updater downloads the new AppImage before replacing the old one, temporarily requiring double the disk space (~200MB). This is unlikely to be an issue on modern systems but should be documented.
Recommendation
Implement auto-update in phases:
Phase 1: AppImage Auto-Update (MVP)
Integrate electron-updater for AppImage distribution only. Detect AppImage at runtime via process.env.APPIMAGE, initialize the updater conditionally, and present a non-intrusive update notification. Add a "Check for Updates" menu item. Handle errors gracefully with user-facing messages.
Phase 2: UX Polish
Add update-on-quit behavior, progress indicators during download, and a "skip this version" option. Consider adding update status to the About dialog.
Phase 3: Evaluate deb/rpm (Future)
Once electron-updater's deb/rpm support matures (exits beta), evaluate whether to offer auto-update for those formats. This is low priority since package managers handle updates for those formats.
ADR-011 Disposition
ADR-011 should be marked as Superseded. The appimagetool post-processing approach embeds standard AppImage update info, but electron-builder's ecosystem ignores it entirely. The two mechanisms are incompatible: electron-updater uses latest-linux.yml and its own AppImageUpdater class, not the .upd_info ELF section that standard AppImage tools read.
The CI steps added by ADR-011 (downloading appimagetool, extracting, repacking, and uploading) add build time and complexity without producing working results within the electron-builder ecosystem. They should be removed.
If third-party AppImage update tool support is still desired in the future, it would need to be investigated as a separate concern after electron-updater is working.
References
- electron-builder Auto Update Documentation
- electron-updater Source (GitHub)
- Vesktop Updater Implementation
- AppImage Update Information Specification
- electron-builder Issue #2311 — AppImageUpdate Integration
- electron-builder PR #7060 — deb/rpm auto-update
- ADR-011: AppImage Update Information
- Issue #2065: AppImage Update Info