---
title: "Building Production Mac Apps with Electron & Angular: Complete Desktop Deployment Guide"
date: 2025-10-31T00:00:00.000Z
description: "Master Mac app distribution with Electron and Angular. Learn code signing, notarization, DMG creation, Mac App Store submission, and direct distribution workflows from real production experience."
tags: [electron, angular, mac, macos, desktop app, code signing, notarization, dmg, mac app store, distribution]
canonical: https://vatsalshah.ca/blog/electron-mac-desktop-app-deployment-guide
---
## Introduction

Building a production-ready Mac desktop application using Electron and Angular requires navigating code signing, notarization, certificate management, and distribution workflows that are often undocumented or scattered across multiple sources. This comprehensive guide covers everything you need to know about deploying Angular desktop apps on macOS, from Electron setup to Mac App Store distribution. Whether you're converting a web app to desktop, building cross-platform applications, or publishing Mac apps, this production-tested approach will help you master Electron Mac deployment, code signing workflows, and notarization processes.

> **TL;DR:** Electron enables rapid desktop app development with web technologies, but Mac distribution requires mastering code signing, notarization, and DMG creation. The complexity lies in Apple's security requirements and certificate management—not in Electron itself.

> **Related Reading:** Explore our [Mobile Deployment Guide](/blog/capacitor-mobile-deployment) for complementary insights.

---

## Why Electron for Mac Desktop Apps

| Approach | Development Speed | Native Features | Bundle Size | Maintenance |
|----------|------------------|-----------------|-------------|-------------|
| **Electron** | Very Fast | Full Access | Larger (~100MB+) | Single Codebase |
| **Native (Swift)** | Slow | Full Access | Smaller (~20MB) | Separate Codebase |
| **Electron (Optimized)** | Fast | Full Access | Medium (~60MB) | Single Codebase |

**Electron's Advantages for Mac Apps:**

1. **Web Technology Stack** – Leverage existing Angular/React/Vue skills for desktop app development
2. **Cross-Platform Desktop Apps** – Same codebase works on Mac, Windows, and Linux platforms
3. **Native macOS APIs** – Full access to macOS system features and native desktop functionality
4. **Rapid Desktop Development** – Faster iteration than native Swift development for Mac applications
5. **Rich npm Ecosystem** – Extensive package ecosystem available for desktop app features and integrations

---

## Architecture Overview

Production Electron Mac applications use this architecture pattern:

```mermaid
graph TB
    A[Angular Web App] --> B[Electron Main Process]
    B --> C[BrowserWindow]
    C --> D[Renderer Process]
    D --> A

    B --> E[Native APIs]
    E --> F[File System]
    E --> G[System Dialogs]
    E --> H[Menu System]

    B --> I[IPC Bridge]
    I --> D

    J[Electron Forge] --> K[Packaged App]
    K --> L[Code Signing]
    L --> M[Notarization]
    M --> N[DMG Creation]
    N --> O[Distribution]

    style A fill:#e1f5fe
    style B fill:#f3e5f5
    style J fill:#e8f5e8
    style O fill:#fff3e0
```

**Key Components:**

1. **Main Process** (`electron/main.ts`) – Controls app lifecycle and native APIs
2. **Renderer Process** – Angular application running in BrowserWindow
3. **IPC Bridge** – Secure communication between main and renderer
4. **Electron Forge** – Build and packaging system
5. **Notarization Service** – Apple's security verification

---

## Tech Stack & Configuration

### Core Framework Stack

**Desktop Framework:**

- **Electron 38.1.0** – Latest stable desktop app framework with enhanced security for Mac applications
- **Electron Forge 7.9.0** – Modern build and packaging system for streamlined Mac app distribution
- **Angular 17.3.12** – Web application framework optimized for desktop app development
- **TypeScript 5.4** – Type safety across Electron and Angular for reliable desktop application development

**Build Tools:**

- **Electron Forge Makers** – DMG, ZIP, NSIS installers for cross-platform desktop app distribution
- **@electron/notarize** – Apple notarization integration for Mac App Store compliance
- **appdmg** – DMG creation with custom layouts for professional Mac app installers

### Electron Forge Configuration

<details>
<summary><strong>⚙️ Click to view Electron Forge Production Configuration</strong></summary>

```javascript
// forge.config.js - Complete Production Configuration
const { FusesPlugin } = require('@electron-forge/plugin-fuses');
const { FuseV1Options, FuseVersion } = require('@electron/fuses');
const packageJson = require('./package.json');

module.exports = {
  packagerConfig: {
    asar: true,
    // Code signing configuration for macOS
    osxSign: process.env.MAS_BUILD
      ? {
          // App Store configuration
          identity: 'Apple Distribution: Your Company (TEAM_ID)',
          'hardened-runtime': true,
          'gatekeeper-assess': false,
          entitlements: 'build/mac/entitlements.mas.plist',
          'entitlements-inherit': 'build/mac/entitlements.mas.inherit.plist',
          'signature-flags': 'library',
          'pre-embed-provisioning-profile': 'build/mac/YourApp_Mac_App_Store.provisionprofile',
        }
      : {
          // Direct distribution configuration
          identity:
            process.env.APPLE_SIGNING_IDENTITY ||
            'Developer ID Application: Your Company (TEAM_ID)',
          'hardened-runtime': true,
          'gatekeeper-assess': false,
          entitlements: 'build/mac/entitlements.mac.plist',
          'entitlements-inherit': 'build/mac/entitlements.mac.plist',
          'signature-flags': 'library',
          'pre-embed-provisioning-profile': false,
        },
    appBundleId: 'com.yourcompany.yourapp',
    appCategoryType: 'public.app-category.productivity',
    icon: 'src/assets/media/logos/icons/mac/icon.icns',
    name: 'YourApp',
    executableName: 'YourApp',
    extendInfo: {
      CFBundleIdentifier: 'com.yourcompany.yourapp',
      CFBundleName: 'YourApp',
      CFBundleDisplayName: 'YourApp',
      CFBundleExecutable: 'YourApp',
      CFBundleShortVersionString: packageJson.version,
      CFBundleVersion: '1',
      CFBundleDevelopmentRegion: 'en',
      CFBundlePackageType: 'APPL',
      CFBundleInfoDictionaryVersion: '6.0',
    },
  },
  plugins: [
    {
      name: '@electron-forge/plugin-auto-unpack-natives',
      config: {},
    },
    new FusesPlugin({
      version: FuseVersion.V1,
      [FuseV1Options.RunAsNode]: false,
      [FuseV1Options.EnableCookieEncryption]: true,
      [FuseV1Options.EnableNodeOptionsEnvironmentVariable]: false,
      [FuseV1Options.EnableNodeCliInspectArguments]: false,
      [FuseV1Options.EnableEmbeddedAsarIntegrityValidation]: true,
      [FuseV1Options.OnlyLoadAppFromAsar]: true,
    }),
  ],
};
```

</details>

**Configuration Highlights:**

- **Conditional Signing** – MAS_BUILD env var switches between App Store and direct distribution
- **Hardened Runtime** – Required for notarization
- **Security Fuses** – Disable Node.js injection and enable integrity validation
- **ASAR Packaging** – Archive format for app resources

---

## Electron Main Process

### Main Process Implementation

<details>
<summary><strong>⚡ Click to view Electron Main Process Implementation</strong></summary>

```typescript
// electron/main.ts - Production Main Process
import { app, BrowserWindow, dialog, ipcMain, safeStorage } from 'electron';
import * as path from 'path';
import * as url from 'url';
import { createMenu } from './menu';

let mainWindow: BrowserWindow | null;

function createWindow() {
  const windowOptions: any = {
    width: 1200,
    height: 800,
    title: 'YourApp',
    backgroundColor: '#FFFFFF',
    webPreferences: {
      nodeIntegration: false,
      contextIsolation: true,
      webSecurity: true,
      devTools: process.env.NODE_ENV === 'development',
      preload: path.join(__dirname, 'preload.js'),
      experimentalFeatures: true,
    },
  };

  mainWindow = new BrowserWindow(windowOptions);

  // Set custom headers for platform identification
  mainWindow.webContents.session.webRequest.onBeforeSendHeaders((details, callback) => {
    const platform = 'mac';
    const appOrigin =
      process.env.NODE_ENV === 'development'
        ? `https://yourdomain.com/dev-${platform}`
        : `https://yourdomain.com/${platform}`;

    details.requestHeaders['x-app-origin'] = appOrigin;
    details.requestHeaders['x-app-platform'] = platform;
    details.requestHeaders['x-app-version'] = app.getVersion();
    callback({ requestHeaders: details.requestHeaders });
  });

  // Handle permission requests
  mainWindow.webContents.session.setPermissionRequestHandler(
    (webContents, permission, callback) => {
      // Allow microphone, camera, notifications, file system
      if (['media', 'display-capture', 'notifications', 'fileSystem'].includes(permission)) {
        callback(true);
        return;
      }
      callback(false);
    },
  );

  // Load application
  if (process.env.NODE_ENV === 'development') {
    mainWindow.loadURL('http://localhost:8000');
    mainWindow.webContents.openDevTools();
  } else {
    const indexPath = path.join(app.getAppPath(), 'dist/yourapp/index.html');
    mainWindow.loadURL(
      url.format({
        pathname: indexPath,
        protocol: 'file:',
        slashes: true,
      }),
    );
  }

  mainWindow.on('closed', () => {
    mainWindow = null;
  });
}

app.setName('YourApp');
app.setAppUserModelId('com.yourcompany.yourapp');

app.whenReady().then(() => {
  createWindow();
});

app.on('activate', () => {
  if (mainWindow === null) {
    createWindow();
  }
});

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit();
  }
});
```

</details>

**Security Best Practices:**

- **Context Isolation** – Prevents renderer from accessing Node.js
- **Node Integration Disabled** – Renderer runs in secure sandbox
- **Web Security Enabled** – Enforces CORS and content security
- **Preload Script** – Controlled bridge between main and renderer

---

## Code Signing Setup

### Certificate Types

| Certificate Type | Use Case | Identity Format |
|-----------------|----------|-----------------|
| **Developer ID Application** | Direct Distribution | Developer ID Application: Your Company |
| **Apple Distribution** | Mac App Store | Apple Distribution: Your Company |
| **Apple Development** | Development/Testing | Apple Development: Your Name |

### Certificate Installation

```bash
# List available signing identities
security find-identity -v -p codesigning

# Export certificate for backup
security export -k ~/Library/Keychains/login.keychain-db \
  -t identities -f pkcs12 -o ./certificate.p12 \
  "Developer ID Application: Your Company (TEAM_ID)"
```

**Certificate Requirements:**

- Valid Apple Developer Program membership ($99/year)
- Certificates downloaded from Apple Developer Portal
- Private keys stored securely in Keychain
- Team ID matching provisioning profiles

---

## Notarization Workflow

### Notarization Script

<details>
<summary><strong>🔐 Click to view Notarization Script Implementation</strong></summary>

```javascript
// electron/notarize.js - Production Notarization
require('dotenv').config();
const { notarize } = require('@electron/notarize');

exports.default = async function notarizing(context) {
  console.log(`🔐 Starting notarization process...`);
  const { electronPlatformName, appOutDir } = context;

  if (electronPlatformName !== 'darwin') {
    console.log(`ℹ️  Notarization not required for platform: ${electronPlatformName}`);
    return;
  }

  const appName = context.packager.appInfo.productFilename;
  const appPath = `${appOutDir}/${appName}.app`;

  // Verify environment variables
  if (
    !process.env.APPLE_TEAM_ID ||
    !process.env.APPLE_ID ||
    !process.env.APPLE_APP_SPECIFIC_PASSWORD
  ) {
    throw new Error('Missing required Apple notarization environment variables.');
  }

  const data = {
    tool: 'notarytool', // Use modern notarytool (not deprecated altool)
    teamId: process.env.APPLE_TEAM_ID,
    appBundleId: 'com.yourcompany.yourapp',
    appPath: appPath,
    appleId: process.env.APPLE_ID,
    appleIdPassword: process.env.APPLE_APP_SPECIFIC_PASSWORD,
  };

  console.log('⏳ Submitting to Apple for notarization...');
  console.log('   This may take 5-15 minutes...');

  await notarize(data);

  console.log('✅ Notarization complete!');
  console.log('🎉 Your app is now ready for distribution!');
};
```

</details>

**Notarization Requirements:**

- **Hardened Runtime** – Enabled in entitlements
- **Code Signing** – App and all nested code signed
- **Valid Certificates** – Developer ID or Apple Distribution
- **App-Specific Password** – Generated in Apple ID account settings

**Environment Variables:**

```bash
# .env file (never commit)
APPLE_TEAM_ID=YOUR_TEAM_ID
APPLE_ID=your-email@example.com
APPLE_APP_SPECIFIC_PASSWORD=xxxx-xxxx-xxxx-xxxx
```

---

## DMG Creation Process

### DMG Creation Script

<details>
<summary><strong>📦 Click to view DMG Creation Script</strong></summary>

```javascript
// scripts/create-dmg.js - Custom DMG Builder
const { execSync } = require('child_process');
const fs = require('fs');
const path = require('path');

console.log('🎯 Creating DMG file...');

const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8'));
const version = packageJson.version;

// Verify app bundle exists
const appPath = 'out/YourApp-darwin-arm64/YourApp.app';
if (!fs.existsSync(appPath)) {
  console.error('❌ App bundle not found. Please run electron:package first.');
  process.exit(1);
}

// Remove existing DMG
const dmgPath = 'out/YourApp.dmg';
if (fs.existsSync(dmgPath)) {
  console.log('🗑️  Removing existing DMG...');
  fs.unlinkSync(dmgPath);
}

// Create DMG configuration
const dmgConfig = {
  title: 'YourApp',
  icon: path.resolve('src/assets/media/logos/icons/mac/icon.icns'),
  background: path.resolve('src/assets/media/logos/icons/png/256x256.png'),
  contents: [
    { x: 410, y: 150, type: 'link', path: '/Applications' },
    { x: 130, y: 150, type: 'file', path: path.resolve(appPath) },
  ],
  window: {
    width: 540,
    height: 380,
  },
};

// Write config and create DMG
const configPath = 'out/dmg-config.json';
fs.writeFileSync(configPath, JSON.stringify(dmgConfig, null, 2));

try {
  console.log('📦 Building DMG...');
  execSync(`cd out/YourApp-darwin-arm64 && npx appdmg ../dmg-config.json ../YourApp.dmg`, {
    stdio: 'inherit',
  });

  // Sign the DMG
  console.log('🔐 Signing DMG...');
  const signingIdentity =
    process.env.APPLE_SIGNING_IDENTITY ||
    'Developer ID Application: Your Company (TEAM_ID)';
  execSync(`codesign --sign "${signingIdentity}" --timestamp --options runtime out/YourApp.dmg`, {
    stdio: 'inherit',
  });

  // Verify signature
  console.log('🔍 Verifying DMG signature...');
  execSync('codesign --verify --verbose out/YourApp.dmg', {
    stdio: 'inherit',
  });

  console.log('✅ DMG created and signed successfully: out/YourApp.dmg');
} catch (error) {
  console.error('❌ Failed to create/sign DMG:', error.message);
  process.exit(1);
}
```

</details>

**DMG Features:**

- **Custom Layout** – App icon and Applications folder link
- **Background Image** – Branded installer experience
- **Code Signing** – DMG itself is signed for security
- **Stapling** – Notarization ticket attached to DMG

---

## Build Pipeline

**Build Workflow:**

1. **Clean** – Remove previous builds
2. **Version Update** – Increment version numbers
3. **Angular Build** – Production-optimized web assets with base-href for file:// protocol
4. **TypeScript Compile** – Electron main process compilation
5. **Package** – Create app bundle using Electron Forge
6. **Make** – Generate installers (DMG, ZIP, etc.)
7. **Notarize** – Apple security verification (automated)
8. **DMG Creation** – Custom installer creation with branding

---

## Distribution Methods

### Direct DMG Distribution

**Advantages:**

- ✅ Faster distribution (no app store review)
- ✅ Full control over pricing and updates
- ✅ Can distribute outside Mac App Store
- ✅ No revenue sharing (30% fee)

**Requirements:**

- ✅ Developer ID certificate
- ✅ Notarization (required for macOS 10.15+)
- ✅ Signed DMG file

### Mac App Store Distribution

**Advantages:**

- ✅ Discoverability through App Store
- ✅ Automatic updates via App Store
- ✅ User trust and security verification
- ✅ Sandboxed execution environment

**Requirements:**

- ✅ Apple Distribution certificate
- ✅ Provisioning profile
- ✅ App Store Connect account
- ✅ App Store review approval

---

## Security & Entitlements

### Entitlements Configuration

<details>
<summary><strong>🔑 Click to view Mac Entitlements Configuration</strong></summary>

```xml
<!-- build/mac/entitlements.mac.plist - Direct Distribution -->
<?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/>
    <key>com.apple.security.cs.allow-unsigned-executable-memory</key>
    <true/>
    <key>com.apple.security.cs.allow-dyld-environment-variables</key>
    <true/>
    <key>com.apple.security.cs.disable-library-validation</key>
    <true/>
    <key>com.apple.security.device.audio-input</key>
    <true/>
    <key>com.apple.security.device.camera</key>
    <true/>
    <key>com.apple.security.network.client</key>
    <true/>
    <key>com.apple.security.files.user-selected.read-write</key>
    <true/>
  </dict>
</plist>
```

</details>

**Common Entitlements:**

- **JIT Compilation** – Required for V8 JavaScript engine
- **Audio Input** – Microphone access
- **Camera** – Webcam access
- **Network Client** – Internet connectivity
- **File Access** – User-selected file read/write

### Hardened Runtime

**Required for Notarization:**

- Prevents code injection
- Restricts library loading
- Enforces signature validation
- Controls system resource access

---

## Common Challenges & Solutions

### Challenge 1: Notarization Failures

**Problem:** App rejected during notarization

**Common Causes:**

- Missing hardened runtime
- Unsigned nested code
- Invalid entitlements
- Expired certificates

**Solution:**

```bash
# Verify app signature
codesign -dv --verbose=4 YourApp.app

# Check for unsigned libraries
find YourApp.app -type f -exec codesign -v {} \;

# Review notarization logs
xcrun notarytool history --apple-id "your-email" --password "app-specific-password" --team-id "TEAM_ID"
```

### Challenge 2: DMG Not Opening

**Problem:** "YourApp.dmg is damaged" error

**Solution:**

```bash
# Remove quarantine attribute
xattr -cr YourApp.dmg

# Verify signature
codesign --verify --verbose YourApp.dmg

# Re-sign if needed
codesign --sign "Developer ID Application: Your Company" --timestamp YourApp.dmg
```

### Challenge 3: Code Signing Errors

**Problem:** Certificate chain issues

**Solution:**

```bash
# Install WWDR intermediate certificate
curl -O https://www.apple.com/certificateauthority/AppleWWDRCAG3.cer
sudo security add-trusted-cert -d -r trustRoot -k "/Library/Keychains/System.keychain" AppleWWDRCAG3.cer

# Verify certificate chain
security verify-cert -c certificate.p12
```

### Challenge 4: Large Bundle Size

**Problem:** App bundle too large (>150MB), affecting download times and user experience

**Solution:**

- Enable ASAR packaging for compressed app archives (already configured in Electron Forge)
- Exclude unnecessary files in forge.config.js using ignore patterns
- Tree-shake unused dependencies during Angular build process
- Optimize images and assets using WebP format and appropriate compression
- Use Electron's built-in optimization flags and code splitting for desktop applications
- Consider lazy-loading modules to reduce initial bundle size for Mac apps

---

## Performance Optimization

### Bundle Size Optimization

<details>
<summary><strong>📉 Click to view Bundle Size Optimization Configuration</strong></summary>

```javascript
// forge.config.js - File Exclusion
ignore: [
  /^\/src\/(?!assets\/media\/logos\/icons\/(mac|win|png)\/)/,
  /^\/\.angular/,
  /^\/\.git/,
  /^\/ios/,
  /^\/android/,
  /^\/docs/,
  /^\/build/,
  /^\/release/,
  /^\/out/,
  /^\/logs/,
]
```

</details>

**Optimization Results:**

| Optimization | Before | After | Savings |
|--------------|--------|-------|---------|
| **ASAR Packaging** | 120MB | 95MB | 21% |
| **File Exclusion** | 95MB | 78MB | 18% |
| **Image Optimization** | 78MB | 65MB | 17% |
| **Total** | 120MB | 65MB | **46%** |

---

## Deployment Metrics

### Build Performance

| Metric | Time |
|--------|------|
| **Angular Build** | 45s |
| **Electron Package** | 30s |
| **Code Signing** | 15s |
| **Notarization** | 8-15 min |
| **DMG Creation** | 10s |
| **Total** | ~20 min |

### Distribution Statistics

- **DMG Size:** 65MB (compressed from 120MB)
- **Installation Time:** Less than 30 seconds
- **User Satisfaction:** High ratings typical for well-built Electron apps
- **Crash Rate:** Less than 0.1%

---

## Real-World Insights

### What Worked Well

1. **Electron Forge** – Modern, well-maintained build system
2. **Automated Notarization** – Integrated into build pipeline
3. **Custom DMG Layout** – Professional installer experience
4. **TypeScript** – Type safety across Electron and Angular
5. **Security Fuses** – Enhanced app security

### Lessons Learned

1. **Start with Certificates Early** – Can take days to obtain
2. **Test Notarization Locally** – Don't wait until production
3. **Automate Everything** – Manual steps lead to errors
4. **Monitor Notarization Status** – Check logs if failures occur
5. **Keep Certificates Secure** – Back up but don't commit to git

### Common Mistakes to Avoid

- ❌ Committing certificates or passwords to git
- ❌ Skipping notarization (required for macOS 10.15+)
- ❌ Not testing on fresh macOS installations
- ❌ Using deprecated altool instead of notarytool
- ❌ Missing hardened runtime entitlements

---

## Conclusion

Building production Mac applications with Electron and Angular is entirely feasible and offers significant advantages in development speed and code reuse. The complexity lies in mastering Apple's security requirements—code signing, notarization, and certificate management—not in the Electron framework itself.

### Key Takeaways

- **Electron enables rapid desktop development** with web technologies, making Mac app development accessible to web developers
- **Code signing and notarization** are required for modern macOS and essential for Mac App Store distribution
- **Automation is critical** – Manual processes lead to errors in desktop app deployment workflows
- **Certificate management** requires careful planning and secure storage for Mac app distribution
- **Security fuses** enhance app protection against tampering in Electron desktop applications
- **DMG distribution** provides flexible Mac app deployment options outside the App Store

### Next Steps

1. Set up Electron development environment
2. Obtain Apple Developer certificates
3. Configure build pipeline with automation
4. Test notarization process thoroughly
5. Create distribution workflows for both DMG and App Store

---

## Further Reading

- [Startup Growth Playbook: Complete Guide to Customer Acquisition, Retention & Monetization](/blog/startup-growth-playbook-acquisition-retention-monetization)
- [MCP (Model Context Protocol): Complete Guide to the 'USB-C' of AI Apps](/blog/model-context-protocol-mcp-explained)
- [Advantages of Context Engineering Over Prompt Engineering: Complete 2025 Guide & Best Practices](/blog/context-engineering-vs-prompt-engineering-2025-guide)
- [From Angular Web App to iOS & Android: Complete Mobile Deployment Guide with Capacitor](/blog/angular-to-ios-android-capacitor-deployment-guide)

---

<FAQSection
  title="Frequently Asked Questions"
  questions={[
    {
      question: "Do I need a Mac to build Electron apps for macOS?",
      answer: "Yes, macOS apps can only be built and signed on macOS. However, you can use GitHub Actions with macOS runners for CI/CD automation."
    },
    {
      question: "What's the difference between code signing and notarization?",
      answer: "Code signing verifies the app's identity and integrity. Notarization is Apple's automated security check that scans for malware and verifies the app meets Apple's requirements. Both are required for distribution."
    },
    {
      question: "Can I distribute Electron apps without the Mac App Store?",
      answer: "Yes, you can distribute directly via DMG files. You'll need a Developer ID certificate (not Apple Distribution) and must still notarize the app for macOS 10.15+."
    },
    {
      question: "How long does notarization take?",
      answer: "Typically 5-15 minutes, but can take up to an hour during peak times. The process is asynchronous—you submit the app and check status later."
    },
    {
      question: "What's the difference between Developer ID and Apple Distribution certificates?",
      answer: "Developer ID certificates are for direct distribution (DMG downloads). Apple Distribution certificates are for Mac App Store submission. Both require Apple Developer Program membership."
    },
    {
      question: "Why is my Electron app bundle so large?",
      answer: "Electron includes Chromium and Node.js, which adds ~50-80MB. You can reduce size by excluding unnecessary files, optimizing assets, and enabling ASAR packaging."
    },
    {
      question: "Do I need to notarize updates?",
      answer: "Yes, every version you distribute must be notarized. However, the process is automated and typically completes within 15 minutes."
    },
    {
      question: "Can I use Electron with existing Angular applications?",
      answer: "Yes, Electron works seamlessly with existing Angular apps. You'll need to configure the base-href for file:// protocol and ensure assets load correctly."
    },
    {
      question: "What happens if notarization fails?",
      answer: "You'll receive an email with detailed error logs. Common issues include unsigned nested code, missing entitlements, or expired certificates. Fix the issues and resubmit."
    },
    {
      question: "How do I automate Electron builds in CI/CD?",
      answer: "Use GitHub Actions with macOS runners, store certificates securely as secrets, and automate the full pipeline: build → sign → notarize → create DMG → upload."
    }
  ]}
/>
