Skip to main content

Example Apps

These are runnable reference applications that wire real desktop update flows to a faynoSync instance. Each one targets a different updater. The Electron, Squirrel, and Tauri apps show how the JavaScript SDK fits in — from a simple edge-first update check to full native-feed resolution. The Velopack and Sparkle apps are the exceptions: faynoSync serves each one its native feed, so their stock clients need no SDK.

Every example is a complete, buildable app on GitHub. The snippets in these docs are trimmed to the update logic only (SDK calls, feed wiring, edge handling); the repositories contain the full UI, packaging, and CI.

Which example maps to what

ExampleFramework / updater libraryfaynoSync updater typeHow the SDK is used
ElectronElectron + electron-updater (generic provider)electron-builder (*.yml)SDK checkForUpdates as an edge-first gate, then the feed directory is derived from packageUrls and handed to electron-updater.
SquirrelElectron native autoUpdater (Squirrel.Mac / Squirrel.Windows)squirrel_darwin / squirrel_windowsSDK resolveNativeFeed resolves the feed edge-first (API fallback), then setFeedURL.
TauriTauri + @tauri-apps/plugin-updatertauriSDK checkForUpdates as an edge-first gate; the native plugin does the signature-verified install.
VelopackVelopack (Python, stock client)velopackNo SDK — the stock Velopack UpdateManager reads faynoSync's native feed directly.
SparkleSparkle (native macOS AppKit, stock client)sparkleNo SDK — the stock Sparkle SPUStandardUpdaterController reads faynoSync's materialized appcast directly.

Why the SDK sits in front of the native updater

This applies to the Electron, Squirrel, and Tauri examples. (Velopack and Sparkle are different — see the Velopack and Sparkle pages — because faynoSync serves each a native feed straight from the CDN, so there is no SDK in front.)

Native updaters (electron-updater, Squirrel, tauri-plugin-updater) are good at downloading and installing, but they poll the API on every check and don't know about faynoSync's edge (CDN) responses. In those three examples the SDK runs first:

  • On the common no-update path, the SDK's edge-first checkForUpdates (or resolveNativeFeed) answers from the CDN and sends the optimized /telemetry/beacon, so the API and the native updater are never invoked.
  • Only when an update actually exists does the native updater start, using a feed URL the SDK resolved — pointing at the edge when it's warm, falling back to the API (which warms the edge) on a miss.

Some of the per-example code looks unusual out of context (deriving a feed directory from a package URL, treating 200 { "status": "no_content" } as "no update", stripping /RELEASES). Those are edge-delivery details the SDK normalizes — each page explains them where they appear.

Prerequisites

The three SDK apps read the same configuration (owner, app name, channel, BASE_URL, EDGE_URL, and an optional report key) from a .env file; see each repo's .env.example. The Velopack app is a Python project configured through environment variables instead (feed base, API base, TUF_ENABLED, ASK_API, and so on), and the Sparkle app is a native macOS project configured through Info.plist keys (SUFeedURL/SparkleFeedBaseURL, SUPublicEDKey, FaynoSync*) — see each repo. All of them expect an app configured on your faynoSync instance with the matching channel/platform/arch and the relevant updater enabled on the platform.

  • JavaScript SDKcheckForUpdates, resolveNativeFeed, reportEvent, and edge fallback behavior.
  • Updaters Support — how each updater type shapes the server response.
  • Edge delivery — how faynoSync publishes cached JSON/feeds for CDN delivery.