Logo Vincent
Back to all posts

Electron in Practice: Mac Packaging

Electron
Electron in Practice: Mac Packaging
Table of Contents

Preface

After developing an Electron app locally,

the next thing you want to do is package it and share it.

For how to manage an Electron project with monorepo,

see: Electron in Practice: Managing Electron Projects with Monorepo

Build

Continuing from the previous article, packaging is done in packages/dishi-electron.

At this point, packages/dishi-main already has everything needed to run locally:

main: main process code

renderer: built renderer process code

package.json: entry point

The first step of packaging is to build or copy the source code into dishi-electron.

This can be done in various ways — this article uses gulp.

The end result is copying the dishi-main folder to dishi-electron/dist

and running npm i.

This avoids pulling in unnecessary dependencies.

Icon

A Mac app bundle needs its own icon.

Without a custom icon, the default Electron icon is used after packaging:

After customization (even if a bit rough):

For details on creating Mac icons, see this article:

Electron in Practice: Creating icns Icons

The script added:

    "icon": "electron-icns ./pack/icon/pic.webp",

Result:

App Bundle

Next, package the local app as a Mac app bundle —

a .app Mac application.

There are many options for packaging Mac app bundles.

This article uses electron-packager: https://github.com/electron/electron-packager

A wrapper package has been built on top of electron-packager: https://qiao-electron-cli.vincentqiao.com/#/

The config file is at dishi-electron/pack/electron.config.js:

// pkg
const pkg = require("../dist/package.json");

// const
const arch = process.arch;
const platform = process.platform;
const version = pkg.version;
const iconPath = `pack/icon/icon${platform === "darwin" ? ".icns" : ".ico"}`;

// log
console.log(`arch: ${arch}`);
console.log(`platform: ${platform}`);
console.log(`version: ${version}`);
console.log(`iconPath: ${iconPath}`);

// config
let config = {
  // Whether to overwrite already generated files
  overwrite: true,

  // Source folder to package
  dir: "dist",

  // Output folder
  out: "out",

  // Whether to bundle source code as asar format
  asar: true,

  // Target arch
  arch: arch,

  // Target platform
  platform: platform,

  // App name
  name: "dishi",

  // App icon
  icon: iconPath,

  // App version
  appVersion: version,

  // App copyright
  appCopyright: "Copyright © 2023 insistime.com版权所有",
};

// qe config
module.exports = config;

Script:

    "packmac": "qelectron pm ./pack/electron.config.js",

Result:

The app bundle is generated in the out folder:

And it can be opened locally by double-clicking:

Installer

The app bundle isn’t convenient for direct distribution.

You also need to create a Mac installer.

Again using the qiao-electron-cli wrapper,

with the same config file.

Script:

    "packdmg": "qelectron pd ./pack/electron.config.js",

Result:

A DMG file is generated in the out folder:

Double-clicking prompts for installation:

Related Articles

Electron in Practice: Local Logging

Preface: After developing a local app with Electron, local logging is essential. It helps capture user actions and locate bugs. Local logs differ from real-time analytics — they are larger, more detailed, and not all information is suitable for reporting. Similarities and Differences with Node.js Logging: Writing local logs in Electron is similar to Node.js.

Electron in Practice: Registering Shortcuts

Preface: This article introduces how to register keyboard shortcuts in an Electron app. Main Process: Registering shortcuts in the main process is straightforward — just make sure to do it after app ready. Common key mappings: https://www.electronjs.org/docs/latest/api/accelerator. Also remember to unregister all shortcuts when the app quits.

Electron in Practice: Update Strategies

Preface: After developing a desktop app with Electron, the next question is how to update subsequent versions. This article introduces several update strategies. Electron Architecture: An Electron desktop app consists of several parts: the Electron runtime itself, the main process (Node.js and non-Node.js parts), and the renderer process.

Electron in Practice: Customizing Mac Menus

Preface: Previous articles covered developing an Electron app through to Mac packaging. Related articles: Learn Electron in One Article, Electron in Practice: Local Database SQLite, Electron in Practice: Managing Electron Projects with Monorepo, Electron in Practice: Mac Packaging, Electron in Practice: Registering an Apple Developer Account.

Electron in Practice: Package Size Optimization

Preface The previous articles covered developing an Electron app through to Mac packaging. Related articles: Learn Electron in One Article, Electron in Practice: Local Database SQLite, Electron in Practice: Managing Electron Projects with Monorepo, Electron in Practice: Mac Packaging, Electron in Practice: Register

© 2026 vincentqiao.com . All rights reserved.