← Back to Konde Blog
PRODUCT

Shipping Sparkle integration for in-app updates

Konde Studio now self-updates with EdDSA-signed deltas, a native progress UI, and one-click relaunch. Here is why we picked Sparkle over rolling our own, and the three gotchas we hit shipping it.

Konde Studio v1.1 ships today, and the headline change is invisible: starting now, Studio updates itself. No more downloading a fresh DMG, dragging into Applications, force-quitting the running instance. You launch Studio, a small badge appears in the corner saying "v1.1.2 ready," you click Install, the new build downloads in the background, Studio relaunches in three seconds, you keep working.

It is the kind of feature you only notice when it is not there. Building it taught us a few things.

Why Sparkle, not roll-our-own

Sparkle is the de-facto auto-update framework for macOS apps. It has been around since 2006, ships with most non-App-Store Mac apps you have ever used (1Password, Sketch, Tower, Transmit), and is maintained by a small team that takes security seriously.

We considered rolling our own for about an afternoon. Three reasons we walked back:

  1. Cryptographic update verification is non-trivial. Sparkle 2 uses EdDSA signatures, supports delta updates (only download changed bytes), and verifies before extracting. Implementing this from scratch is the kind of week of engineering that gets done badly and then becomes a CVE.
  2. The native UI is good. Sparkle's progress sheet looks like macOS. Users trust it. We could have built our own modal — but the bar for trust on "we are about to replace your application binary" is high, and a native-feeling sheet clears it.
  3. Apple Notarization works out of the box. Sparkle handles the dance of staple-and-validate that Apple requires post-Catalina. If we had rolled our own, we would have spent days fighting Gatekeeper.

The three gotchas

Shipping was not free. Three things bit us.

Gotcha 1 — appcast.xml mime types

Sparkle pulls update metadata from an appcast — an RSS-flavoured XML feed at a stable URL. Cloudflare R2 serves these by default with application/octet-stream, which Sparkle correctly refused to parse. Fix: a _headers file forcing application/xml for the appcast path. One line, four hours of debugging.

Gotcha 2 — EdDSA key generation footgun

Sparkle ships a generate_keys tool. The default invocation creates a keypair and stashes the private key in your Keychain. Convenient — but if you have ever wiped your Mac's Keychain (or moved CI to a new build runner), you have just permanently lost your update signing key. We now keep the private key in a secrets vault and pass it explicitly to the build, not in the developer's Keychain.

Friendly reminder for anyone shipping Sparkle: write down your key recovery procedure before you write your first release.

Gotcha 3 — relaunch timing on Apple Silicon

After a successful update, Sparkle relaunches the app. On Apple Silicon, the relaunched process sometimes started before the file system had fully synced the new binary. The user saw "v1.1.2 installed" then their app launched into… v1.1.1. Confusing.

Fix: a small post-install script that syncs the FS and waits for the new binary's xattr metadata to settle before invoking Sparkle's relaunch helper. Three additional seconds on the relaunch path, no more version mismatch.

What you actually see as a user

  • A small badge appears at the top right of Studio when an update is ready.
  • Click the badge → Sparkle's native sheet opens with release notes pulled from this blog.
  • Click Install → progress bar.
  • The app relaunches itself. Your open project, agent sessions, and DBarn connections all restore.

Updates run in the background, so the download never blocks Studio. If you launch with no internet, you see no update prompt — Sparkle silently no-ops.

Opting out

Some of you (mostly enterprise users with strict change-management policies) want to pin a version. Settings → Updates → Manual updates only turns off all background polling. You can also pin to a specific channel — stable (default) or beta — if you want to ride the cutting edge.

What is next

Sparkle handles Studio itself. The next step is sharing the same auto-update primitives with bundled binaries — cloudflared, kdoc, the local model runners. When cloudflared ships a security patch, we want it pulled into your Studio install in the same way. That work lands in v1.2.

Until then: when you next open Studio, you should see a small "v1.1 ready" badge. Click it. Tell me on X if anything weird happens.

Share X LinkedIn Facebook