Squirrel Example (native autoUpdater)
An Electron app that updates through the native Electron autoUpdater — Squirrel.Mac on macOS and Squirrel.Windows on Windows — with feed URLs resolved by the faynoSync JavaScript SDK. This maps to the squirrel_darwin and squirrel_windows updater types.
Repository: github.com/ku9nov/faynoSync-squirrel-example
Integration pattern
checkForUpdatesruns as an edge-first gate to decide whether an update exists.- If it does,
resolveNativeFeedresolves the correct Squirrel feed URL — edge-first, with automatic API fallback. - The resolved
feedURLis passed to the nativeautoUpdater.setFeedURL, and Squirrel downloads/installs.
Picking the updater per platform
squirrel_darwin and squirrel_windows use different URL shapes, so the example selects the updater from the runtime platform:
import { systemPlatform, systemArch } from '@faynosync/sdk-js';
function nativeFeedOptions() {
const platform = systemPlatform();
return {
owner,
appName: app_name,
version,
channel,
platform,
arch: systemArch(),
updater: platform === 'darwin' ? 'squirrel_darwin' : 'squirrel_windows',
};
}
Resolving the native feed
resolveNativeFeed does the edge-first resolution and tells you whether to start Squirrel at all:
import { autoUpdater } from 'electron';
const feed = await getClient().resolveNativeFeed(nativeFeedOptions());
if (!feed.updateAvailable) {
return; // nothing to do — Squirrel is never started
}
autoUpdater.setFeedURL({ url: feed.feedURL });
autoUpdater.checkForUpdates();
feed.source tells you whether the feed came from 'edge' or 'api'.
Why this goes through the SDK (edge details)
Pointing the native autoUpdater straight at a faynoSync URL breaks in several non-obvious cases that resolveNativeFeed normalizes:
no_contentvs204. Squirrel.Mac expects200 { "url": "<zip>" }or204 No Content. But the edge mirror returns200 { "status": "no_content" }(not a real204) when there's no update. The SDK reads that and returnsupdateAvailable: false, so you skip the native updater instead of feeding it a bad response.404on a cold edge. Until the API has warmed a version's edge object, the edge returns404. The SDK falls back to the API (which serves the feed and warms the edge for next time), so the first client isn't stuck.squirrel_windowsand/RELEASES. Squirrel.Windows appends/RELEASESto the feed URL itself. The edge response is a redirect to the absolute.../RELEASESfile, so the SDK strips the trailing/RELEASESand returns the directory asfeedURL— exactly whatsetFeedURLneeds.feed.urlstill carries the raw resolved resource (the.zipfor macOS, theRELEASESURL for Windows).
Squirrel.Windows fetches RELEASES and then the .nupkg deep in native code, so an auth error there is hard to trace. The example fetches RELEASES itself first and logs each .nupkg URL Squirrel will hit — that's where an unexpected 401/403 actually originates. See src/main/updater.js.
The native autoUpdater only runs in a packaged app and only on macOS/Windows; the example falls back to opening resp.updateUrl otherwise.
Related reading
- JavaScript SDK —
resolveNativeFeed,NativeFeedResult, and native updater feeds. - Electron Example —
electron-updatergeneric provider instead of native Squirrel. - Updaters Support —
squirrel_darwin/squirrel_windowsand theRELEASESoutput.