Guide

Sign and notarize your Electron or Tauri Mac app from Windows or Linux

You can write an Electron or Tauri app on Windows or Linux. The macOS release is different. Apple's signing and notarization tools only run on macOS. Without them, Mac users see a warning and the app does not open. This page shows the build, sign and notarize steps, with commands we ran.

Why the Mac step needs macOS

Three Apple tools do the work. codesign signs the app. notarytool sends it to Apple's notary service. stapler attaches the ticket Apple sends back. All three ship with macOS and Xcode. There is no Windows or Linux version from Apple.

The framework docs agree. Tauri says to run tauri build on a Mac computer. Electron Forge says Xcode is required for notarization. We also tried the Linux side on GitHub Actions. Electron Forge on Ubuntu made a .deb and an .rpm. Asking it for a macOS package failed.

What you need before release day

  • A paid Apple Developer Program membership. Apple lists it at 99 USD a year.
  • A Developer ID Application certificate. Only the Account Holder of the team can create one, in Xcode or on the developer site.
  • An app-specific password for your Apple Account, or an App Store Connect API key.
  • Your Team ID, the 10 character code from your developer account.

Apple's notary service also asks for the hardened runtime and a secure timestamp. electron-builder turns on the hardened runtime with one line in its config, shown below.

What an unsigned build looks like

We built the official create-tauri-app template with no certificate. These are the checks we ran on the result:

npm create tauri-app@latest tauri-app -- --template vanilla --manager npm --yes
cd tauri-app && npm install
rustup target add aarch64-apple-darwin x86_64-apple-darwin
npm run tauri build -- --target universal-apple-darwin

APP=src-tauri/target/universal-apple-darwin/release/bundle/macos/tauri-app.app
lipo -archs "$APP"/Contents/MacOS/*
codesign --verify --deep --strict --verbose=2 "$APP"
spctl -a -vv "$APP"

The output on a GitHub macos-26 runner:

x86_64 arm64
tauri-app.app: code object is not signed at all
tauri-app.app: rejected
source=no usable signature

The build took 4 minutes. It made an 8.23 MiB universal .app and a 3.57 MiB .dmg. The Electron Forge .dmg was not better. codesign showed Signature=adhoc and TeamIdentifier=not set, and spctl rejected it. Gatekeeper blocks builds like these on your users' Macs.

Electron Forge: sign and notarize in make

Forge signs and notarizes during npm run make when the config asks for it. This is the example from Forge's macOS signing guide:

// forge.config.js
module.exports = {
  packagerConfig: {
    osxSign: {},
    osxNotarize: {
      appleId: process.env.APPLE_ID,
      appleIdPassword: process.env.APPLE_PASSWORD,
      teamId: process.env.APPLE_TEAM_ID
    }
  }
};

Then build each architecture. We added the DMG maker to the default template first. Both builds took under 25 seconds each:

npm install --save-dev @electron-forge/maker-dmg
npm run make -- --arch=arm64
npm run make -- --arch=x64

We also tried --arch=universal on the default template. It failed with "the number of mach-o files is not the same between the arm64 and x64 builds". The electron-builder docs also say per-architecture builds are the most reliable.

electron-builder: notarize: true

electron-builder reads the certificate and the Apple login from environment variables. Its notarization page shows this config:

# electron-builder.yml
mac:
  notarize: true
  sign:
    hardenedRuntime: true

# environment
CSC_LINK=/path/to/developer-id.p12
CSC_KEY_PASSWORD=...
APPLE_ID=you@example.com
APPLE_APP_SPECIFIC_PASSWORD=xxxx-xxxx-xxxx-xxxx
APPLE_TEAM_ID=ABCDE12345

Tauri: set the variables, then build

Tauri signs and notarizes inside tauri build when these variables are set. The names come from Tauri's macOS signing guide:

export APPLE_SIGNING_IDENTITY="Developer ID Application: Your Name (ABCDE12345)"
export APPLE_ID=you@example.com
export APPLE_PASSWORD=xxxx-xxxx-xxxx-xxxx
export APPLE_TEAM_ID=ABCDE12345
npm run tauri build -- --target universal-apple-darwin

Notarize any app by hand

For other toolkits, or to redo one step, run Apple's tools yourself. These commands come from Apple's notarization docs. Save your login once, then zip, submit and wait:

xcrun notarytool store-credentials "notarytool-password" \
  --apple-id "you@example.com" --team-id ABCDE12345 \
  --password xxxx-xxxx-xxxx-xxxx

ditto -c -k --keepParent "MyApp.app" "MyApp.zip"
xcrun notarytool submit MyApp.zip --keychain-profile "notarytool-password" --wait
xcrun stapler staple "MyApp.app"

Apple says notarization typically takes less than an hour. You cannot staple a ZIP, so staple the .app and zip it again. You can also submit and staple the .dmg itself. If the status is Invalid, read the log:

xcrun notarytool log <submission-id> --keychain-profile "notarytool-password" developer_log.json

Doing it on a rented Mac

A MacRun day pass is a dedicated M6 Mac mini for $15. Xcode 27.1 is installed, so codesign, notarytool and stapler are ready. Node and Rust are not preinstalled. You have admin rights and Homebrew, so you can install them yourself.

  • Connect over Tailscale with SSH, or open the desktop with any VNC viewer.
  • Sign in to Xcode with your Apple Account and create the Developer ID certificate there.
  • Export the certificate with its key to a .p12 file and keep it, for CI later.
  • Clone your repo, build, notarize, and download the stapled .dmg.

The Mac is wiped when the pass ends. Push your code and copy the .p12 off first. For Xcode over a remote screen, see our guide to Xcode from Windows.

Who should not rent a Mac for this

  • Teams with CI already. A GitHub macOS runner can sign and notarize with secrets. Our Electron job billed 2 minutes, about 12 cents. The Tauri job billed 5, about 31 cents. Notary wait time adds minutes. See our GitHub Actions guide.
  • Linux-only pipelines. rcodesign is an open source tool that signs and notarizes from Linux or Windows. It needs an App Store Connect API key. It is not an Apple tool, and its last release was 0.29.0 in November 2024.
  • Weekly releases. A monthly runner is $104for the first month, then $139 a month. Buying a used Mac may cost less over a year.

Frequently asked questions

Can I notarize a Mac app on Windows?

+

Not with Apple's tools. codesign, notarytool and stapler only run on macOS. The open source rcodesign tool can sign and notarize from Windows or Linux, but Apple does not make or support it.

Do I need a paid Apple Developer account to notarize?

+

Yes. You need a Developer ID Application certificate, which comes with the Apple Developer Program at 99 USD a year. Tauri's docs say a free account cannot notarize.

Can Electron Forge build a Mac .dmg on Linux?

+

In our test, no. Electron Forge on Ubuntu made only a .deb and an .rpm, and a forced macOS package failed. On a macOS 26 runner, the same template made a .dmg and a .zip for arm64 and x64.

How do I make a universal Mac build?

+

With Tauri, add both Rust targets and run tauri build --target universal-apple-darwin. That gave us one .app with x86_64 and arm64. With Electron Forge, the default template failed to merge, so build arm64 and x64 separately.

How long does Apple notarization take?

+

Apple says it typically takes less than an hour. The --wait flag keeps notarytool running until Apple answers, so you do not have to poll.

How much does a Mac for one release cost?

+

A MacRun day pass is $15 for a dedicated M6 Mac mini with Xcode installed. A week is $59. You pay once and nothing renews.

Related guides