Streambert Auto Update Check: How It Notifies Users of New Releases

Streambert automatically polls the GitHub releases API on startup, compares semantic versions using a normalization algorithm, and displays a fixed banner notification when an update is detected, allowing users to download and install the appropriate platform-specific installer through a guided modal interface.

Streambert, the open-source streaming application maintained at truelockmc/streambert, implements a comprehensive Streambert auto update check notify users pipeline that eliminates the need for manual version monitoring. The system queries GitHub's releases endpoint with an 8-second timeout, parses stable (non-prerelease) versions, and surfaces non-intrusive UI notifications when newer builds are available. This architecture ensures users remain on current stable releases while retaining full control over installation timing.

How Streambert Detects Available Updates

The detection logic resides in [src/utils/updates.js](https://github.com/truelockmc/streambert/blob/main/src/utils/updates.js), where the checkForUpdates() function orchestrates the entire Streambert auto update check notify users workflow. The function initiates a fetch request to https://api.github.com/repos/truelockmc/streambert/releases?per_page=10 with an Accept: application/vnd.github+json header and an 8-second abort signal to prevent UI blocking during slow network conditions.

The response filtering prioritizes stability by selecting only the first release that is neither a draft nor a prerelease. Version comparison relies on normaliseVersion(), which strips leading "v" characters, pads missing patch numbers, and converts components to integers for reliable three-part semver evaluation via semverGt().

Asset mapping occurs immediately after version confirmation. The code iterates over data.assets and maps file extensions (.appimage, .exe, .dmg, .deb) to platform-specific keys (appimage, exe, dmg_arm64, etc.), ensuring the subsequent download phase selects the correct installer format for the user's operating system.

Manual Update Detection

Developers or power users can programmatically trigger the update check:

import { checkForUpdates } from "./utils/updates";

(async () => {
  try {
    const info = await checkForUpdates();
    console.log("Update info:", info);
    if (info.hasUpdate) {
      window.dispatchEvent(
        new CustomEvent("streambert:show-update", { detail: info })
      );
    }
  } catch (e) {
    console.error("Failed to fetch updates:", e);
  }
})();

Configuring Startup Auto-Checks

The automatic check executes through a useEffect hook in [src/App.jsx](https://github.com/truelockmc/streambert/blob/main/src/App.jsx#L103-L112) that runs once on component mount. The hook first verifies user preferences via storage.get("autoCheckUpdates") before invoking checkForUpdates().

useEffect(() => {
  if (!storage.get("autoCheckUpdates")) return;
  checkForUpdates()
    .then((r) => {
      if (r.hasUpdate) setUpdateBanner(r);
    })
    .catch(() => {});
}, []);

When hasUpdate returns true, the result object populates the updateBanner state variable, triggering the notification UI. Users can disable this behavior through the application's settings, which updates the underlying local storage value accessed by the storage utility in [src/utils/storage.js](https://github.com/truelockmc/streambert/blob/main/src/utils/storage.js).

Rendering the Update Notification Banner

Upon detecting an update, Streambert auto update check notify users functionality renders a fixed-position banner at the top of the interface (defined at lines 15-31 of App.jsx). The conditional React fragment checks the updateBanner state:

{
  updateBanner && (
    <div className="update-banner">
      🎉 Streambert v{updateBanner.latest} is available!
      <button onClick={() => setShowUpdateModal(true)}>
        Install Update
      </button>
      <button onClick={() => setUpdateBanner(null)}>✕</button>
    </div>
  );
}

Clicking Install Update toggles the showUpdateModal boolean, while the dismiss button clears updateBanner from state, effectively hiding the notification until the next check cycle or application restart.

The Update Modal and Installation Flow

The [src/components/UpdateModal.jsx](https://github.com/truelockmc/streambert/blob/main/src/components/UpdateModal.jsx) component receives the updateInfo object and manages the complete download and installation sequence. The modal first detects the appropriate installer format via window.electron.detectUpdateFormat(), which the main process pre-populates based on the current platform.

The component renders a markdown changelog through renderChangelog(), supporting headings, lists, and images to communicate release notes effectively. When the user confirms installation, the renderer invokes:

const result = await window.electron.downloadAndInstallUpdate({
  url: assetUrl,
  format,
});

IPC Communication and Progress Tracking

The [src/ipc/player.js](https://github.com/truelockmc/streambert/blob/main/src/ipc/player.js#L198-L425) file registers the ipcMain.handle('download-and-install-update') listener, which streams the installer to the system temporary directory while emitting progress events back to the renderer via mw.webContents.send('update-progress', {...}).

The download pipeline supports cancellation through a cancelRef flag checked during the streaming process. If the user clicks Cancel, the abort mechanism halts the download and cleans up partial files. Errors during fetch or execution display a red error message within the modal, accompanied by a fallback link to manually download the release from GitHub.

Post-Update Cache Invalidation

To prevent data conflicts between versions, [src/App.jsx](https://github.com/truelockmc/streambert/blob/main/src/App.jsx#L89-L101) implements a cache-flushing mechanism on every startup. The code compares window.electron.getAppVersion() against localStorage.getItem('streambert_lastVersion'). When these values diverge, indicating a recent upgrade, the application invokes clearAppCaches() to purge stale TMDB data and UI state, then updates the stored version string.

This ensures that schema changes or API modifications in new releases operate on clean state without legacy data interference.

Summary

  • Streambert auto update check notify users functionality relies on checkForUpdates() in src/utils/updates.js to poll GitHub releases with an 8-second timeout and robust semver comparison.
  • The startup check in App.jsx respects the autoCheckUpdates preference stored via the storage utility, only polling when explicitly enabled.
  • Update notifications render as a fixed banner showing the new version and offering one-click installation or dismissal.
  • UpdateModal.jsx handles format detection, changelog rendering, and coordinated downloads via the download-and-install-update IPC channel defined in src/ipc/player.js.
  • The main process streams installers to temporary storage, reports real-time progress, and supports cancellation while spawning the appropriate system installer.
  • Automatic cache clearing occurs after version changes to eliminate stale data conflicts.

Frequently Asked Questions

How does Streambert determine which installer format to download?

The system maps GitHub release asset extensions to platform-specific keys (.exe for Windows, .dmg for macOS, .appimage or .deb for Linux) in src/utils/updates.js. The UpdateModal component then calls window.electron.detectUpdateFormat() to identify the correct asset URL for the current operating system architecture, ensuring users receive compatible binaries without manual selection.

Can users disable automatic update notifications?

Yes. The application checks storage.get("autoCheckUpdates") during the startup useEffect in App.jsx. Users can toggle this boolean preference in the application settings; when disabled, the Streambert auto update check notify users pipeline skips the GitHub API call entirely, though manual checks remain possible through developer console commands.

What happens if the GitHub API is unreachable during the check?

The fetch request in checkForUpdates() uses AbortSignal.timeout(8000) to limit the request duration to 8 seconds. If the network is unavailable or the API returns an error, the promise rejects silently (caught by .catch(() => {}) in the startup hook), leaving the application state unchanged and preventing UI stalls or error banners from disrupting the user experience.

How does Streambert handle installation after the download completes?

The main process handler in src/ipc/player.js streams the installer to os.tmpdir(), sets executable permissions where necessary (e.g., chmod +x for Linux AppImages), and spawns the installer using execFile or platform-equivalent methods. On Windows, this launches the .exe installer; on macOS, it opens the .dmg or mounts the disk image; on Linux, it executes the AppImage or package manager installation, all while the modal displays an indeterminate progress animation until the installer exits.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →