# @electron/osx-sign

> Codesign Electron macOS apps

Latest version **2.7.0** (published 2026-08-18) · BSD-2-Clause license · 0 weekly downloads

## Install

```sh
npm install @electron/osx-sign
pnpm add @electron/osx-sign
yarn add @electron/osx-sign
bun add @electron/osx-sign
```

Provides the commands `electron-osx-flat`, `electron-osx-sign`.

## Health

**Score 65/100 (B)** — status: active.

Positive: esm support; no vulnerabilities; has provenance; recently updated; high maintenance score.

Warnings: low downloads; no types.

## Facts

| | |
|---|---|
| Version | 2.7.0 |
| Published | 2026-08-18 |
| First published | 2022-03-24 |
| Weekly downloads | 0 |
| License | BSD-2-Clause |
| TypeScript types | none |
| Module format | ESM |
| Node | >=22.12.0 |
| Dependencies | 4 |
| Unpacked size | 298.5 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Provenance | attested (GitHub Actions) |
| GitHub stars | 631 |
| Author | electron |
| Maintainers | electron-cfa |

## Links

- npm: https://www.npmjs.com/package/@electron/osx-sign
- Repository: https://github.com/electron/osx-sign
- Issues: https://github.com/electron/osx-sign/issues
- npm.io page: https://npm.io/package/@electron/osx-sign

## Dependencies (4)

- [debug](https://npm.io/package/debug.md) ^4.3.4
- [plist](https://npm.io/package/plist.md) ^3.0.5
- [semver](https://npm.io/package/semver.md) ^7.7.1
- [isbinaryfile](https://npm.io/package/isbinaryfile.md) ^4.0.8

## Recent versions

- 2.7.0 (latest) — 2026-08-18
- 2.6.2 — 2026-08-17
- 2.6.0 — 2026-07-17
- 2.5.0 — 2026-07-01
- 2.4.2 — 2026-06-29
- 2.4.1 — 2026-06-27
- 2.4.0 — 2026-04-15
- 2.3.0 — 2025-11-03
- 2.2.0 — 2025-08-29
- 2.1.0 — 2025-08-28
- 2.0.0 — 2025-04-04
- 1.3.3 — 2025-03-05
- 1.3.2 — 2024-12-31
- 1.3.1 — 2024-07-04
- 1.3.0 — 2024-05-15
- … 7 more at https://npm.io/package/@electron/osx-sign/versions

## README

# @electron/osx-sign

[![npm][npm_img]][npm_url]
[![Test][gha_img]][gha_url] 
[![API docs](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fregistry.npmjs.org%2F%40electron%2Fosx-sign%2Flatest&query=%24.version&logo=typescript&logoColor=white&label=API%20Docs)](https://packages.electronjs.org/osx-sign)

Codesign Electron macOS apps

## About

[`@electron/osx-sign`][electron-osx-sign] minimizes the extra work needed to eventually prepare
your apps for shipping, providing options that work out of the box for most applications.
Additional configuration is available via its API.

There are two main functionalities exposed via this package:
* Signing macOS apps via `sign` functions. Under the hood, this uses the `codesign` utility.
* Creating `.pkg` installer packages via `flat` functions. Under the hood, this uses the `productbuild` utility.

## Installation

`@electron/osx-sign` is integrated into other Electron packaging tools, and can be configured accordingly:
* [Electron Packager](https://electron.github.io/packager/main/interfaces/OsxSignOptions.html)
* [Electron Forge](https://www.electronforge.io/guides/code-signing/code-signing-macos)

You can also install `@electron/osx-sign` separately if your packaging pipeline does not involve those tools:

```sh
npm install --save-dev @electron/osx-sign
```

## Code signing

The signing procedure implemented in this package is based on what described in Electron's [Code Signing Guide](https://github.com/electron/electron/blob/main/docs/tutorial/code-signing.md).

### Prerequisites

* You must be a registered member of the [Apple Developer Program](https://developer.apple.com/programs/).
  Please note that you could be charged by Apple in order to get issued with the required certificates.
* You must have [Xcode](https://developer.apple.com/xcode/) installed from the
  [Mac App Store](https://apps.apple.com/us/app/xcode/id497799835). It is not recommended to download your
  copy from other 3rd party sources for security reasons.
* You must have Xcode Command Line Tools installed. To check whether it is available,
  try `xcode-select --install` and follow the instructions.
* To distribute your app on the Mac App Store, You must create a Mac App on [App Store Connect](https://appstoreconnect.apple.com/).
* You must give your app a unique Bundle ID.
* You must give your app a version number.

### Certificates

In order to distribute your application either inside or outside the Mac App Store,
you will have to have the following certificates from Apple after becoming a registered developer.

Certificates can be created through the
[Certificates, Identities & Profiles](https://developer.apple.com/account/resources/certificates/add)
page in the Apple Developer website or via [Account Preferences in Xcode](https://help.apple.com/xcode/mac/current/#/dev3a05256b8).

For distribution inside the Mac App Store, you will need to create:
* Mac App Distribution: `3rd Party Mac Developer Application: * (*)`
* Mac Installer Distribution: `3rd Party Mac Developer Installer: * (*)`

For distribution outside the Mac App Store:
* Developer ID Application: `Developer ID Application: * (*)`
* Developer ID Installer: `Developer ID Installer: * (*)`

After you create the necessary certifications, download them and open each so that they are
installed in your keychain. We recommend installing them in your system default keychain so
that `@electron/osx-sign` can detect them automatically.

> [!TIP]
> Apple developer certificates tend to come in related pairs. It’s simplest to install
> both of them for future use. However, if you only want to distribute outside the Mac App Store,
> there is no need to have the 3rd Party Mac Developer ones installed, and vice versa.

### API

```javascript
import { sign } = from '@electron/osx-sign'
const opts = {
  app: 'path/to/my.app'
};
sign(opts)
  .then(function () {
    // Application signed
  })
  .catch(function (err) {
    // Handle the error
  })
```

The only mandatory option for `sign` is a path to your `.app` package.
Configuration for most Electron apps should work out of the box.
For full configuration options, see the [API documentation].

### Usage examples

#### Signing for Mac App Store distribution

```javascript
import { sign } from '@electron/osx-sign'
const opts = {
  app: 'path/to/my.app',
  // optional parameters for additional customization
  platform: "mas", // should be auto-detected if your app was packaged for MAS via Packager or Forge
  type: "distribution", // defaults to "distribution" for submission to App Store Connect
  provisioningProfile: 'path/to/my.provisionprofile', // defaults to the current working directory
  keychain: 'my-keychain', // defaults to the system default login keychain
};
sign(opts)
  .then(function () {
    // Application signed
  })
  .catch(function (err) {
    // Handle the error
  })
```

Mac App Store apps require a [Provisioning Profile](https://www.electronjs.org/docs/latest/tutorial/mac-app-store-submission-guide#prepare-provisioning-profile)
for submission to App Store Connect. We recommend having the provisioning profile for distribution
placed in the current working directory and the signing identity installed in the default keychain.

The app is not expected to run after codesigning since there is no provisioned device, and it is
intended only for submission to App Store Connect. Since `@electron/osx-sign` adds the entry
`com.apple.developer.team-identifier` to a temporary copy of the specified entitlements file
(with the default option `preAutoEntitlements`), distribution builds can no longer be run directly.

To run an app codesigned for distribution locally after codesigning, you may manually add
`ElectronTeamID` in your `Info.plist` and `com.apple.security.application-groups` in the
entitlements file, and set `preAutoEntitlements: false` for `@electron/osx-sign` to avoid
this extra bit. Note that "certain features are only allowed across apps whose team-identifier value match"
([Technical Note TN2415](https://developer.apple.com/library/content/technotes/tn2415/_index.html#//apple_ref/doc/uid/DTS40016427-CH1-ENTITLEMENTSLIST)).

Alternatively, set the app's `type` to `development` to codesign a development version of your app,
which will allow it to be run on your development provisioned machine. Apps signed for development
will not be eligible for submission via App Store Connect.

#### Signing with `--deep`

Some subresources that you may include in your Electron app may need to be signed with `--deep`.
This is not typically safe to apply to the entire Electron app and therefore should be applied to _just_ your file.

```javascript
sign({
  app: 'path/to/my.app',
  optionsForFile: (filePath, { platform }) => {
    // The second argument provides additional context about the current signing
    // operation, such as the resolved `platform` ('darwin' or 'mas').

    // For our one specific file we can pass extra options to be merged
    // with the default options
    if (path.basename(filePath) === 'myStrangeFile.jar') {
      return {
        additionalArguments: ['--deep'],
      };
    }

    // Just use the default options for everything else
    return null;
  },
});
```

#### Signing legacy versions of Electron

`@electron/osx-sign` maintains backwards compatibility with older versions of Electron, but
generally assumes that you are on the latest stable version.

If you are running an older unsupported version of Electron, you should pass in the `version`
option as such:

```javascript
sign({
  app: 'path/to/my.app',
  version: '0.34.0',
});
```

## Flat installer packaging

This module also handles the creation of flat installer packages (`.pkg` installers).

> [!NOTE]
> Modern `.pkg` installers are also named "flat" packages for historical purposes. Prior
> to Mac OS X Leopard (10.5), installation packages were organized in hierarchical
> directories. OS X Leopard introduced a new flat package format that is used for modern
> `.pkg` installers.

### API usage

```javascript
import { flat } = '@electron/osx-sign'
flat({
  app: 'path/to/my.app'
})
  .then(function () {
    // Application flattened
  })
  .catch(function (err) {
    // Handle the error
  })
```

The only mandatory option for `flat` is a path to your `.app` package.
For full configuration options, see the [API documentation].

### Pure-JavaScript packaging

By default `flat` shells out to Apple's `pkgbuild`/`productbuild` binaries. Passing
`implementation: 'js'` switches to a bundled pure-JavaScript implementation of the
flat package format that is typically **4–5× faster** on a real Electron app and works
on any platform (Linux/Windows included) for unsigned packages:

```javascript
await flat({
  app: 'path/to/my.app',
  implementation: 'js',
});
```

The JS implementation reimplements the entire flat package stack — the cpio payload
archive, Apple's Bill-of-Materials (`Bom`) binary format, the `PackageInfo`/`Distribution`
documents and the outer xar archive. Its output is verified against the native tools by
an extensive parity test suite (`spec/pkg-utils/`): uncompressed payloads are
byte-identical, `lsbom` output matches on every field, and the XML documents are
byte-identical modulo the `generator-version` attribute. Run `yarn bench` to reproduce
the performance comparison on your machine.

Notes on intentional differences from the native tools:

- The payload is gzip-compressed as a standards-compliant multi-member stream so members
  can be compressed in parallel. Compressed output is ~3% larger than Apple's private
  zlib flavor; decompressed content is identical.
- Extended attributes are not preserved (no AppleDouble `._*` entries are generated).
- The app's `Info.plist` must be XML; binary property lists are rejected with an error.
- Hardlinked files are stored as independent copies rather than deduplicated the way
  pkgbuild archives them (Electron apps use symlinks, not hardlinks).
- Individual files larger than 4 GB are rejected (the flat package Bom format stores
  32-bit sizes; `Size64` support is not implemented).
- Files with NFC-normalized (composed) Unicode names are packaged correctly; native
  `pkgbuild` silently omits such files from the payload.
- When a signing `identity` is provided, the built package is signed with `productsign`,
  which requires macOS.

## CLI

`@electron/osx-sign` also exposes a legacy command-line interface (CLI) for both signing
and installer generation. However, we recommend using the JavaScript API as it has a more
complete API surface (e.g. `optionsForFile` is only available via JS).

```sh
# install the package locally into devDependencies
npm install --save-dev @electron/osx-sign

# Sign a packaged .app bundle
npx electron-osx-sign path/to/my.app [options ...]

# Create a .pkg installer from a packaged .app bundle
npx electron-osx-flat path/to/my.app [options ...]
```

For full options, use the `--help` flag for either command.


## Debug

The [`debug`](https://www.npmjs.com/package/debug) module is used to display advanced logs and messages.
If you are having problems with signing your app with `@electron/osx-sign`, run your signing scripts with
the `DEBUG=electron-osx-sign*` environment variable.

## Test

The project's configured to run automated tests on GitHub Actions.

If you wish to manually test the module, you need to first generate a self-signed certificate
via the `spec/ci/generate-identity.sh` script.

[API documentation]: https://packages.electronjs.org/osx-sign
[Electron]: https://github.com/electron/electron
[electron-osx-sign]: https://github.com/electron/osx-sign
[npm_img]: https://img.shields.io/npm/v/@electron/osx-sign.svg
[npm_url]: https://npmjs.org/package/@electron/osx-sign
[gha_img]: https://github.com/electron/osx-sign/actions/workflows/test.yml/badge.svg
[gha_url]: https://github.com/electron/osx-sign/actions/workflows/test.yml

---
_Source: https://npm.io/package/@electron/osx-sign · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
