Back to Home

Electron Guide - Cross-Platform Desktop Apps

Packaging & Distribution

Turn your Electron app into installers users can download and run. Code signing, notarization, and multi-platform builds—the final steps to production.

Packaging is where many developers get stuck. Code signing is confusing, notarization is slow, and platform differences are frustrating. But it's essential—unsigned apps trigger scary warnings, and users won't trust software that looks suspicious.

What You're Building

Each platform has its own installer format and distribution expectations. Users expect a .dmg on macOS, an .exe installer on Windows, and an AppImage or .deb on Linux.

macOS

  • .dmg - Drag to Applications
  • .pkg - Guided installer
  • .zip - Direct download

Requires code signing + notarization

Windows

  • NSIS .exe - Standard installer
  • .msi - Enterprise deployment
  • Portable - No install needed

Code signing prevents SmartScreen warnings

🐧 Linux

  • AppImage - Universal, portable
  • .deb - Debian/Ubuntu
  • .rpm - Fedora/RHEL

No signing required, but recommended

🎯 VibeBlaster Distribution

VibeBlaster ships as a signed .dmg for macOS and signed NSIS installer for Windows. The whole build process runs in GitHub Actions—push a tag, and installers appear on the Releases page 20 minutes later. No manual steps.

electron-builder Configuration

electron-builder is the standard tool for packaging Electron apps. It handles bundling, code signing, notarization, and creating platform-specific installers—all from a single configuration.

Essential Configuration

Add this to your package.json. The key settings are appId (unique identifier), productName (display name), and publish (for auto-updates).

{
  "build": {
    "appId": "com.yourcompany.yourapp",
    "productName": "Your App Name",
    
    "directories": {
      "output": "release",
      "buildResources": "build"
    },

    "files": [
      "dist/**/*",
      "package.json"
    ],

    "mac": {
      "category": "public.app-category.productivity",
      "target": ["dmg", "zip"],
      "hardenedRuntime": true,
      "notarize": { "teamId": "YOUR_TEAM_ID" }
    },

    "win": {
      "target": ["nsis"],
      "signingHashAlgorithms": ["sha256"]
    },

    "linux": {
      "target": ["AppImage", "deb"],
      "category": "Utility"
    },

    "publish": {
      "provider": "github"
    }
  }
}

Build Commands

npm run build:mac → .dmg + .zip

npm run build:win → .exe installer

npm run build:linux → AppImage + .deb

Output Structure

release/

├── YourApp-1.0.0.dmg

├── YourApp-1.0.0-mac.zip

├── YourApp Setup 1.0.0.exe

└── YourApp-1.0.0.AppImage

Code Signing: Why It Matters

Code signing proves your app comes from you and hasn't been tampered with. Without it, users see scary warnings: "Windows protected your PC" or "App can't be opened because it's from an unidentified developer."

Unsigned App Consequences

  • macOS: "App is damaged and can't be opened" or Gatekeeper blocks it
  • Windows: SmartScreen warning, users must click through scary dialogs
  • Auto-updates: Won't work without code signing
  • User trust: Looks like malware, users won't install

macOS Signing

  1. 1. Join Apple Developer Program ($99/year)
  2. 2. Create "Developer ID Application" certificate
  3. 3. Export as .p12 file from Keychain
  4. 4. Set CSC_LINK and CSC_KEY_PASSWORD env vars
  5. 5. electron-builder signs automatically

Also requires notarization (Apple scans your app)

Windows Signing

  1. 1. Purchase code signing certificate (~$200-500/year)
  2. 2. Providers: DigiCert, Sectigo, SSL.com
  3. 3. Export as .pfx file
  4. 4. Set WIN_CSC_LINK and WIN_CSC_KEY_PASSWORD
  5. 5. electron-builder signs automatically

EV certificates eliminate SmartScreen warnings immediately

Environment Variables for CI

Store certificates as base64-encoded secrets in your CI system. Never commit certificates to git.

# macOS
CSC_LINK: base64-encoded .p12 certificate
CSC_KEY_PASSWORD: certificate password
APPLE_ID: your-apple-id@email.com
APPLE_APP_SPECIFIC_PASSWORD: app-specific password
APPLE_TEAM_ID: your team ID

# Windows
WIN_CSC_LINK: base64-encoded .pfx certificate
WIN_CSC_KEY_PASSWORD: certificate password

macOS Notarization

Starting with macOS 10.15 (Catalina), apps must be notarized by Apple to run without warnings. Notarization uploads your app to Apple's servers for malware scanning. It takes 5-15 minutes.

Notarization Flow

1

Build & Sign

electron-builder

2

Upload to Apple

notarytool

3

Apple Scans

5-15 minutes

Staple Ticket

Ready to ship

💡 electron-builder Handles This

With the right config and environment variables, electron-builder automatically uploads to Apple, waits for approval, and staples the ticket. You just run npm run build:mac and wait. Check the notarization status in Apple's developer portal if something goes wrong.

Automated Builds in CI

The best setup: push a git tag, and CI automatically builds, signs, and publishes installers for all platforms. No manual steps, no "works on my machine" issues.

GitHub Actions Release Workflow

# .github/workflows/release.yml
name: Release

on:
  push:
    tags: ['v*']

jobs:
  build:
    strategy:
      matrix:
        include:
          - os: macos-latest
            build_cmd: build:mac
          - os: windows-latest
            build_cmd: build:win
          - os: ubuntu-latest
            build_cmd: build:linux
    
    runs-on: ${{ matrix.os }}
    
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      
      - run: npm ci
      - run: npm run ${{ matrix.build_cmd }}
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          CSC_LINK: ${{ secrets.MAC_CERT }}
          CSC_KEY_PASSWORD: ${{ secrets.MAC_CERT_PASSWORD }}
          # ... other secrets
      
      - uses: softprops/action-gh-release@v1
        with:
          files: release/*
          draft: true

✓ CI Benefits

  • • Reproducible builds every time
  • • Build on actual target OS (not cross-compile)
  • • Certificates stay in CI secrets
  • • Automatic GitHub Releases

⚠️ Watch Out For

  • • macOS notarization adds 10-20 min to builds
  • • Windows signing can timeout
  • • Large artifacts may need cleanup
  • • Test installers before releasing

Packaging Best Practices

Always code sign—unsigned apps look like malware
Test installers on clean machines before release
Use CI/CD for reproducible builds
Keep certificates in CI secrets, never in git
Build macOS universal binaries (Intel + Apple Silicon)
Minimize bundle size—exclude dev dependencies
Include proper icons for all platforms
Draft releases first, publish after testing

Your App Is Ready to Ship

You can now build signed installers for all platforms and distribute them to users. Combined with auto-updates, your release process is fully automated—push a tag and wait for installers.

Next up: Performance. Your app works, it's packaged, it's signed—now let's make sure it's fast and doesn't eat all your users' RAM.