
Key takeaways
• Publishing a macOS desktop app in 2026 is a four-step pipeline. Sign with a Developer ID cert, package to .dmg or .pkg, notarize with xcrun notarytool, staple the ticket. Skip any step and macOS refuses to launch the app.
• altool --notarize-app is dead. Apple deprecated it in Xcode 13 and fully removed it from xcrun on 1 November 2023. Every working pipeline in 2026 uses notarytool. If your build script still says altool, it is broken.
• Electron’s 2026 toolchain is scoped. Use @electron/osx-sign and @electron/notarize (not the old unscoped electron-notarize), Electron Forge 7+ for new projects, and Hardened Runtime with allow-jit entitlement only.
• The whole thing ships from CI in 5–15 minutes per release. Initial setup (Developer ID, GitHub Actions, secrets) is a 2–3 week investment. After that it is a one-click release, with notarization latency the only variable.
• Electron is not the only answer. Tauri 2 ships 2–5 MB binaries and native-level memory use, SwiftUI ships a native macOS app at 40% the RAM footprint of Electron. Electron still wins on team velocity and cross-platform reach — pick by constraint, not by habit.
Why Fora Soft wrote this macOS publishing playbook
We have shipped desktop clients for video surveillance, streaming, e-learning, and enterprise SaaS products on macOS for more than a decade — Electron, native Swift, and (more recently) Tauri. Along the way we hit every trap Apple has ever shipped: signing regressions on arm64 migration, the 2023 removal of altool, Hardened Runtime entitlement conflicts with native Node modules, notarization timeouts during launch week. This article is the shortlist of what still works in 2026.
A few concrete references that inform the advice below: our desktop clients for VALT — a secure video-surveillance SaaS used by 770+ law-enforcement and medical organisations — ship to Mac operators who require verifiably notarised builds every release. BrainCert’s proctoring desktop companion has to pass stapled-notarisation checks under sketchy corporate antivirus setups; we learned what breaks first. And our product troubleshooting-and-optimisation service regularly takes on desktop projects where a previous team shipped a signed-but-not-notarised app that Apple is now blocking.
If you’d rather skip straight to shipping, we build and publish macOS desktop apps end-to-end, including the CI signing/notarisation pipeline that most teams put off for months.
Notarisation broken on your release branch?
Get a 30-minute call with a Fora Soft engineer who has shipped dozens of signed/notarised Electron and native macOS apps — typical outcome: your CI pipeline goes green within the week.
Why publishing on macOS is harder than it looks
macOS treats unsigned or unnotarised apps as hostile by default. Gatekeeper, XProtect, and the Notary service form three layers of checks that every app launches through on modern macOS. If your build fails any of them, the user sees a red-bordered “cannot be opened” dialog — or, since macOS 15 Sequoia, is routed through System Settings and a three-click confirmation to run the app at all. The friction is real: measured install-to-first-run conversion drops 40–60% for unnotarised Mac apps.
The historical friction point is that Apple has rewritten its notarisation tooling three times. The first generation used xcrun altool --notarize-app with an Apple ID and app-specific password. Apple deprecated that path in Xcode 13 and removed it entirely on 1 November 2023. The replacement is xcrun notarytool, which has different flags, different auth options, and — critically — faster turnaround (typically 2–15 minutes instead of 20–60). Any guide older than 2023 is describing a pipeline that no longer exists; any build script that still shells out to altool is currently broken, whether or not your tests have noticed yet.
Second friction point: every part of the app that ships as a binary has to be individually signed with the Hardened Runtime, including native Node modules, Electron Framework helpers, Squirrel update helpers, and any bundled CLI tools. One unsigned dylib somewhere in node_modules/ will fail notarisation with a cryptic log file. The Electron Forge and electron-builder ecosystems hide most of this, but when they fail, you need to understand what is happening underneath.
The four-step macOS publishing pipeline in 2026
At the Unix level, every macOS publishing pipeline does the same four things in the same order. Understand these and the tooling choice is a detail.
| Step | What it does | Command | Typical time |
|---|---|---|---|
| 1. Code sign | Prove authorship with a Developer ID cert | codesign --deep --options runtime |
10–60 s |
| 2. Package | Wrap the .app in a .dmg, .zip or .pkg | electron-builder --mac dmg |
30 s–3 min |
| 3. Notarize | Upload to Apple’s Notary service for malware scan | xcrun notarytool submit --wait |
2–15 min |
| 4. Staple | Embed the notarisation ticket so offline launches work | xcrun stapler staple |
1–5 s |
Miss step 3 and the user sees a “this app is damaged and can’t be opened” message. Miss step 4 and the app works only when the user has internet access at first launch — otherwise Gatekeeper cannot reach the Apple server that hosts the ticket, and it treats the app as unnotarised. Both are real bugs we have seen in production support engagements.
Reach for the full four-step pipeline when: you plan to distribute outside the Mac App Store — direct .dmg, Homebrew Cask, enterprise MDM, auto-update via Sparkle or electron-updater. The Mac App Store pipeline is separate and its own section below.
Step 1 — Code signing with a Developer ID certificate
Every macOS app distributed outside the Mac App Store needs a Developer ID Application certificate — a $99/year Apple Developer Program membership and about 30 minutes of setup. There are two cert types you will interact with:
Developer ID Application — signs the .app bundle. Required for notarisation. Identifies your organisation. Revocable by Apple if misused (privacy policy violation, malware).
Developer ID Installer — signs .pkg installers. Separate from the Application cert. Only needed if you ship as a package installer instead of a drag-to-Applications .dmg.
Hardened Runtime is mandatory
The Notary service rejects any app not signed with the Hardened Runtime flag (--options runtime). Hardened Runtime blocks code injection, library swaps, and some debugger attachments. Electron apps need exactly one entitlement exception: com.apple.security.cs.allow-jit, because the V8 JavaScript engine JITs bytecode to native at runtime. Anything more permissive — especially allow-unsigned-executable-memory — will either fail notarisation or raise security review flags on the Mac App Store.
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>com.apple.security.cs.allow-jit</key> <true/> </dict> </plist>
Add this as build/entitlements.mac.plist in an Electron project and reference it from electron-builder.yml or forge.config.js. Only add more entitlements when a specific feature (microphone, camera, network server, file access) demands it — each extra entitlement is another attack surface and another App Review risk.
Step 2 — Packaging as .dmg, .zip, or .pkg
macOS accepts three distribution packages, each with different trade-offs.
.dmg (Disk Image). The Mac-native drag-to-Applications experience. Best for consumer apps. Supports a custom background, license agreement, and an install-by-drag UX that feels native. Electron Forge, electron-builder, and native Xcode builds all produce DMGs natively.
.zip. The right pick when auto-update frameworks (Sparkle, electron-updater with Squirrel.Mac) are downloading deltas. Smaller than DMG, faster to extract, no mount overhead. Usually invisible to the user because the auto-updater unzips and swaps the bundle itself.
.pkg (Installer Package). Best for enterprise MDM deployment and apps that install system services or agents. Slightly more friction for consumer downloads, but the only sane choice if your app needs a helper daemon, a LaunchAgent, or admin privileges during install. Requires the separate Developer ID Installer cert.
Reach for .dmg when: shipping a consumer or prosumer app direct-download; reach for .pkg when the app installs daemons, launch agents, or system extensions; reach for .zip only for auto-update payloads, not initial distribution.
Step 3 — Notarising with xcrun notarytool
Notarisation is Apple’s automated malware scan. You upload your signed package, Apple scans it on their servers, and returns either “accepted” (with a ticket you can staple) or a rejection log explaining what broke. The 2026 tool is xcrun notarytool, shipped as part of Xcode Command Line Tools.
Three authentication options — pick by context
1. App-specific password (simplest). Generate from appleid.apple.com → App-Specific Passwords. Pass via --password. Good for local dev and small-team CI. The friction point is rotation — every team change means regenerating.
2. App Store Connect API key (recommended for CI). Download a .p8 private key from App Store Connect. Pass via --key --key-id --issuer. No per-user password; rotatable centrally; survives team turnover. This is what we use on Fora Soft CI.
3. Keychain profile (safest for local). Run notarytool store-credentials once, store the profile in the Keychain, then pass --keychain-profile. The password never hits an env var or a build log.
End-to-end commands
# 1. Sign the .app bundle (Hardened Runtime + entitlements) codesign --deep --force --verify --verbose \ --options runtime \ --entitlements build/entitlements.mac.plist \ --sign "Developer ID Application: Acme Inc (XXXXXXXXXX)" \ dist/Acme.app # 2. Package into a .dmg (electron-builder does this automatically) electron-builder --mac dmg # 3. Submit for notarization, wait for result (typical: 2-15 minutes) xcrun notarytool submit dist/Acme-1.0.0.dmg \ --apple-id "$APPLE_ID" \ --team-id "$APPLE_TEAM_ID" \ --password "$APPLE_APP_PASSWORD" \ --wait # 4. Staple the ticket so the app launches offline too xcrun stapler staple dist/Acme-1.0.0.dmg # 5. Verify everything with Gatekeeper spctl -a -vvv --type install dist/Acme-1.0.0.dmg
Electron teams usually wire this into afterSign / afterAllArtifactBuild hooks in electron-builder.yml, using @electron/notarize (the scoped replacement for the deprecated electron-notarize). On Electron Forge 7+, the @electron-forge/maker-dmg plus the osxNotarize config block wire the whole pipeline in about 20 lines of config.
Need the notarisation CI pipeline built once, properly?
Fora Soft runs a 1-week Mac publishing sprint: Developer ID + App Store Connect API keys, GitHub Actions workflow, signing + notarisation + stapling + release publishing, tested against Ventura / Sonoma / Sequoia. Hand-off includes runbook and secrets rotation.
Step 4 — Staple, then verify, then ship
Stapling embeds the notarisation ticket into the artifact so Gatekeeper can verify it offline. If you do not staple, Gatekeeper has to fetch the ticket from Apple on first launch — which breaks for air-gapped installs, corporate networks that block Apple’s notarisation host, and the first 30 seconds after a conference Wi-Fi sign-in. Always staple.
After stapling, run spctl -a -vvv against the artifact. Successful output contains “source=Notarized Developer ID” and the cert identity. Anything else — “source=Unnotarized Developer ID,” “rejected,” or CSSM errors — means something is still wrong. Capture this in CI so the build fails closed if the pipeline regresses.
The Electron toolchain in 2026 — what to pick
Electron’s publishing ecosystem has consolidated around a few canonical packages. The old unscoped modules (electron-notarize, electron-osx-sign) are deprecated in favour of their scoped successors (@electron/notarize, @electron/osx-sign). If your package.json still references the old names, upgrade.
| Package | What it does | Status | Recommend for |
|---|---|---|---|
| Electron Forge 7+ | Unified build/package/publish CLI | Official, current | New projects |
| electron-builder | Build + multi-target packaging | Community, mature | Existing projects, complex targets |
| @electron/osx-sign | Sign .app bundles | Official, current | Any signing workflow |
| @electron/notarize | Wrap notarytool |
Official, current | Any notarisation workflow |
| electron-updater | Auto-update via Squirrel.Mac | Community, current | Most Electron apps |
| electron-notarize (unscoped) | Old notarisation wrapper | Deprecated | Delete from package.json |
Our default for new Electron projects: Electron Forge 7+ with the DMG and ZIP makers, @electron/notarize via the osxNotarize hook, universal arm64 + x64 builds via the macUniversal maker, and GitHub Actions with App Store Connect API keys stored as repo secrets. Total setup: one day for a senior; two to three for someone new to the stack.
Alternatives to Electron — when not to use it
Electron is the right pick for most desktop apps in 2026 — cross-platform reach, broad ecosystem, fast team onboarding. But it is not the only choice, and for some products the alternatives deliver materially better outcomes.
Tauri 2. Rust-backend, system-webview-frontend. Bundles of 2–10 MB (versus 100–200 MB for a comparable Electron app), ~30–40% less memory at idle, near-native startup. The tradeoff: smaller ecosystem, fewer off-the-shelf Node packages, a Rust learning curve for the backend. Great for a shipping focused on bundle size, resource usage, or high-volume deployments.
Native Swift / SwiftUI. macOS-only but uncompromising on platform polish, performance, and native API access. Makes sense for apps that are 80%+ Mac users, deeply integrate with macOS (Finder, Spotlight, Shortcuts, system services) or are targeted at prosumer Mac audiences willing to pay for native. Our Swift 6 features guide and MVVM-C architecture playbook carry over mostly intact.
.NET MAUI / Avalonia. Right if the team is already deep in C#. Avalonia in particular produces small cross-platform binaries with a native look-and-feel, and has been production-ready since 2023. Smaller community than Electron but credible for LOB apps.
Auto-updates — Sparkle, Squirrel.Mac, and delta strategy
Desktop apps need an update story. Without one, every bug fix or security patch requires the user to re-download and reinstall — a large portion of them will not, and within a year your install base is running five different vulnerable versions. Updates matter enough that our seamless app updates guide treats them as a product surface of their own.
Sparkle is the 20-year-old native macOS choice. Adopted by 1Password, Sketch, Things, and most premium Mac apps. Background download, silent install, cryptographic signature verification, staged rollout, release notes. Excellent for native Swift apps; usable from Electron with a shim.
electron-updater (Squirrel.Mac) is the Electron default. Works with GitHub Releases, S3, generic HTTPS, or a custom server. Delta updates keep bandwidth small. Integrates with electron-builder and Electron Forge via a few lines of config.
Staged rollout. Never ship a release to 100% of your user base on day one. Start at 10% for 24 hours, 50% for 48 hours, 100% thereafter — and wire crash telemetry (Sentry, Crashlytics) to the rollout so a regression auto-pauses the next stage. This is the single biggest post-launch risk reduction a desktop app can buy.
Five notarisation errors you will hit — and how to fix them
1. “The binary is not signed with a valid Developer ID certificate.” A native module, helper binary, or framework inside the bundle was not signed. Run codesign --deep or, better, use @electron/osx-sign’s auto-discovery. Native Node modules with postinstall scripts are the usual culprit.
2. “The executable does not have the hardened runtime enabled.” Missing --options runtime on one of the nested binaries. Usually a helper CLI you bundled. Re-run signing with the flag.
3. “The signature of the binary is invalid.” You modified the bundle after signing (updated a config file, ran a post-build script). Re-sign after every modification; a single extra byte invalidates the signature.
4. “com.apple.security.cs.allow-unsigned-executable-memory is not allowed.” Older Electron builds had this entitlement for dev builds. Remove it from production entitlements; modern Electron runs fine with just allow-jit.
5. “status: Invalid” with empty developer log URL. Usually a corrupted upload. Retry once. If it persists, the artifact is likely not a valid bundle — e.g., you are submitting an unsigned .app inside a .zip. Sign first, zip second.
Distribution channel comparison
| Channel | Rev share | Discovery | Review | Best fit |
|---|---|---|---|---|
| Developer ID + direct DMG | 100% to you | Your marketing | None (just notarisation) | B2B, prosumer, power users |
| Mac App Store | 70% (85% after year 1 subs) | Built-in | 24–48h App Review | Consumer, impulse-buy apps |
| Homebrew Cask | 100% to you | Dev community | Community PR | Developer tools |
| Enterprise MDM (.pkg) | 100% to you | B2B sales | None | Enterprise, regulated industries |
| Setapp | Revenue share | Subscription catalog | Setapp approval | Prosumer, recurring-use tools |
Most B2B apps ship Developer ID + direct download first, add the Mac App Store once the product is mature, and skip Setapp unless the product naturally fits a subscription bundle. Consumer productivity apps do the opposite — Mac App Store first for discovery, direct download as a paid pro tier. Pick by who your audience is and where they currently find apps.
Wiring the pipeline into GitHub Actions
Here is the minimal macOS publish workflow we use on internal Fora Soft projects. It runs on a macos-14 runner, imports the signing identity from a base64-encoded .p12, and invokes Electron Forge’s publish target which handles signing + notarisation internally.
name: release-macos
on: { push: { tags: ['v*'] } }
jobs:
release:
runs-on: macos-14
env:
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_APP_PASSWORD: ${{ secrets.APPLE_APP_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
CSC_LINK: ${{ secrets.MAC_CERTS }}
CSC_KEY_PASSWORD: ${{ secrets.MAC_CERTS_PASSWORD }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: 20 }
- run: npm ci
- run: npm run make -- --arch=universal
- run: npm run publish
Run time on a macos-14 runner for a 120 MB Electron app is typically 12–18 minutes end-to-end: 4–6 min build, 1–2 min sign, 5–10 min notarise, 30 s staple + publish. GitHub Actions bills macOS runners at 10× Linux minutes, so allow about $2–4 per release if you are on a Team plan. For teams shipping many releases per day, dedicated macOS build boxes (a Mac Mini or Mac Studio on a continuous-integration service like CircleCI or BuildKite) pays back quickly.
Mini case — rescuing a stuck macOS release
Situation. A Fora Soft client running a streaming SaaS product had an Electron desktop companion app with a broken release pipeline: every build failed notarisation after Apple removed altool. The team had been shipping unnotarised updates for three months, losing install-conversion data from users who could not launch the app. Their last working release was on macOS Ventura; newer users on Sonoma saw the “cannot be opened” dialog at install.
One-week sprint. Day 1: audit. The existing pipeline used electron-notarize 1.x (unscoped, unmaintained) calling altool. Days 2–3: upgrade to @electron/notarize 3.x and move to App Store Connect API key authentication. Day 4: replace the entitlements.plist (it still had allow-unsigned-executable-memory) with a minimal allow-jit-only file. Day 5: wire the pipeline into GitHub Actions, test against macOS Ventura/Sonoma/Sequoia matrix. Day 6: publish a canary to 10% of users, monitor Sentry for regressions. Day 7: full rollout.
Outcome. Full pipeline runs in 14 minutes per release. Install-to-first-run conversion recovered from 54% (broken) to 91% within two weeks. Subsequent releases go out weekly with a one-click git tag. The team retains the runbook for future rotations. Want a similar release-pipeline rescue?
Release pipeline stuck on deprecated tooling?
Fora Soft runs one-week macOS-pipeline rescue sprints with a senior Node/macOS engineer plus Agent Engineering support — typical cost 30–40% below an equivalent agency scoping because the agents do the log triage and entitlement audits.
A decision framework — macOS publishing in five questions
Q1. Is your audience B2B, enterprise, or power-user? Ship Developer ID + direct DMG first. The Mac App Store is a distraction until the product is stable.
Q2. Do you need cross-platform (Windows/Linux) reach? Yes → Electron or Tauri. No → Swift/SwiftUI, with the performance and polish payoff that implies.
Q3. Is bundle size a real constraint? Electron apps start around 100–200 MB. Tauri lands at 2–10 MB. For slow-network distribution, corporate MDM size limits, or a competitive story that leans on “fast”, Tauri wins the trade-off.
Q4. Is your team already deep in JavaScript/TypeScript? Yes → Electron Forge 7+ with TypeScript template. The team ships faster and the maintenance burden stays linear with team size.
Q5. Do you need auto-updates? Assume yes. Every desktop app does. Wire electron-updater or Sparkle on day one; staged rollout from day two; telemetry on day three.
Five macOS publishing pitfalls to avoid
1. Using deprecated tooling. altool, electron-notarize (unscoped), electron-osx-sign (unscoped), and any guide written before 2024 describing a workflow that no longer works. Audit your package.json and scripts.
2. Over-permissive entitlements. Every extra entitlement is an attack surface. Start with allow-jit only; add others only with a documented feature justification.
3. Skipping stapling. Stapler is so cheap it is free. Skipping it breaks the app for air-gapped installs and corporate networks that block Apple’s Gatekeeper endpoint. Always staple.
4. Shipping without staged rollout. 100% rollout on day one turns a bug into an outage. Wire a 10% → 50% → 100% staged rollout with automatic pause on crash-rate regression. Our crash-proof software playbook covers the broader pattern.
5. Storing credentials in repo. App-specific passwords and .p12 certs committed to git are the single most common root cause of credential breaches we see in desktop projects. Use GitHub Actions secrets, 1Password Secrets Automation, or App Store Connect API keys. Rotate quarterly.
KPIs — what to measure on a macOS desktop app
Publishing KPIs. Notarisation time P50 (< 10 min), release-pipeline time (< 20 min end-to-end), release frequency (target: weekly or better), broken-build escape rate (< 2% of releases). These tell you whether the pipeline is healthy.
Install KPIs. Install-to-first-run conversion (target: > 90%), first-day retention by macOS version, update adoption rate (% of install base on latest version within 7 days, target > 70%). These tell you whether the app is actually launching.
Quality KPIs. Crash-free sessions (target > 99.5%), hang rate (< 0.5%), memory footprint on iPhone-like hardware, CPU utilisation at idle. Same Quality-of-Service metrics as mobile — same thresholds apply. Our testing-at-every-stage guide covers how to bake these into CI.
When NOT to build a macOS desktop app at all
Sometimes the right macOS app is no macOS app. Scenarios where the usual advice is wrong:
1. Your product is a SaaS with zero offline use-case. A Progressive Web App in Safari gives you installability, offline caching, notifications, and zero notarisation overhead. Unless you need filesystem, hardware, or system-tray access, PWA wins.
2. Your Mac audience is <10% of total users. Building and maintaining a macOS client costs roughly 30–40% of what the web client costs per year. Do not pay that unless you have the users.
3. You ship weekly features with Slack-style velocity. Desktop auto-update latency is typically 2–7 days from release to majority-adoption. If your product iterates faster than that, your users will be perpetually on stale versions. Web or a hybrid PWA fits that tempo better.
FAQ
Is xcrun altool still usable for notarisation in 2026?
No. Apple removed altool --notarize-app on 1 November 2023. The only supported command-line tool for notarisation in 2026 is xcrun notarytool, shipped with Xcode 14+ and current Xcode Command Line Tools. If your build script still references altool, it is broken.
Do I need an Apple Developer Program membership to publish a macOS desktop app?
Yes, if you want the app to launch without warnings on any recent macOS. The $99/year membership gives you the Developer ID certificate you need to sign, and access to the Notary service. Without it, your users will see “app is damaged” or “unidentified developer” errors that break install-to-first-run conversion by 40–60%.
How long does notarisation actually take?
Typical P50 on the modern notarytool is 2–10 minutes for a 100–200 MB Electron bundle. P95 around 15 minutes. Occasional Apple-side delays during major macOS releases (June betas, October releases) can push it to 30–60 minutes, but those are rare. Always use --wait so your CI job blocks until the result is back.
Electron Forge or electron-builder — which should I pick?
For new projects in 2026, Electron Forge 7+ is the official default and the lowest-friction path. It bundles signing, notarisation, universal binaries, and auto-update publishers in one CLI. electron-builder is still excellent for existing projects or complex multi-target builds (think Windows Store, Snap, Flatpak, plus macOS). Avoid mixing both.
Should I build a universal binary (arm64 + x86_64)?
Yes, in 2026 the answer is almost always universal. Apple Silicon is the majority of shipping Macs and Intel machines are still supported. A universal binary is ~40% larger than a single-arch build but gives you one artifact for all users. Use the macUniversal maker in Forge, or arch: universal in electron-builder. Ship one binary; your download page stays simpler.
Is Tauri production-ready?
Tauri 2 (released late 2024) is production-ready for apps that can live with a Rust backend and the system webview (WKWebView on macOS). Companies like 1Password, Cloudflare, and Fig ship Tauri apps in production. The tradeoff is a smaller ecosystem than Electron and a Rust learning curve. For apps where bundle size, memory, or startup-time are the story, it is a strong choice.
How do I handle auto-updates securely?
Three rules. One: always serve updates over HTTPS. Two: always verify the download’s cryptographic signature against a pinned public key (Sparkle has EdDSA built-in; electron-updater verifies against the Developer ID signature in the payload). Three: stage rollouts 10% → 50% → 100% with crash telemetry auto-pausing the next stage on regression. Skipping any of these turns a bad release into an outage.
What is the difference between Mac App Store and Developer ID distribution?
Mac App Store distribution requires the App Store cert, sandboxing, and App Review (24–48h). You pay 15–30% rev share but get discovery and automatic in-app purchases. Developer ID distribution is direct download — you keep 100% of revenue and ship as fast as you can notarise, but discovery is entirely on you. Most B2B apps start Developer ID; consumer apps tend to start App Store.
What to Read Next
Releases
Seamless app updates without breaking users
Staged rollouts, feature flags, crash-regression auto-pause — the post-launch playbook.
Reliability
How to build crash-proof software in 2026
SLOs, circuit breakers, DORA metrics, feature flags — how desktop apps stay above 99.5% crash-free.
Native macOS
Swift 6 features for native Mac apps
Strict concurrency, typed throws, embedded Swift — the case for going native instead of Electron.
Architecture
The 2026 Apple MVVM-C playbook
Coordinators, DI, Swift 6 concurrency — architecture for native Apple apps that survives production.
Quality
What to do if there are too many bugs
Root-causes, QA, automated review — when bug load is the symptom, not the problem.
Ready to ship a macOS desktop app properly?
Publishing on macOS in 2026 is a four-step pipeline: sign, package, notarise with xcrun notarytool, staple the ticket. Skip any step and Gatekeeper refuses to launch your app; use deprecated tooling and your CI silently starts shipping broken builds. The Electron toolchain has consolidated around Electron Forge 7+, @electron/osx-sign, and @electron/notarize; the alternatives (Tauri, native Swift) earn their place on bundle size, memory, or platform polish.
Set the pipeline up once, properly, and every release afterwards is a one-click git tag that ships in 15 minutes. The cost is a couple of focused weeks. The payback is every week thereafter. If you want a partner who has been doing this for a decade across video, e-learning, surveillance, and SaaS products, that is the shape of what Fora Soft does — and Agent Engineering now compresses the setup by another 30–40% compared with traditional shops.
Let’s ship your macOS desktop app.
30-minute call with a Fora Soft engineer who has done this dozens of times — you leave with a concrete migration path, a pipeline blueprint, and an honest estimate, whether or not we end up working together.



.avif)

Comments