@electron-forge/core vs electron-builder vs electron-packager
Electron App Packaging and Distribution Strategies
@electron-forge/coreelectron-builderelectron-packagerSimilar Packages:

Electron App Packaging and Distribution Strategies

@electron-forge/core, electron-builder, and electron-packager are tools used to bundle, package, and distribute Electron applications. electron-packager is a low-level utility that creates executable app folders without installers. electron-builder is a comprehensive solution that handles packaging, installer creation (DMG, NSIS, etc.), code signing, and publishing. @electron-forge/core serves as the underlying engine for the Electron Forge ecosystem, providing a unified workflow for scaffolding, bundling, and packaging with a focus on developer experience and plugin extensibility.

Npm Package Weekly Downloads Trend

3 Years

Github Stars Ranking

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
@electron-forge/core07,087435 kB27123 days agoMIT
electron-builder014,58884.5 kB683 days agoMIT
electron-packager0298145 kB463 years agoBSD-2-Clause

Electron Packaging Tools: Forge Core vs Builder vs Packager

Building a desktop app with Electron is only half the battle. Getting that app into the hands of users requires packaging, signing, and distributing it across Windows, macOS, and Linux. @electron-forge/core, electron-builder, and electron-packager tackle this problem with different levels of abstraction and scope. Let's look at how they handle the critical steps of shipping software.

🛠️ Configuration Setup: JS vs YAML vs CLI

How you define your build rules sets the tone for the rest of your project. The tools differ in where and how they store settings.

@electron-forge/core uses a JavaScript or TypeScript config file.

  • This allows you to use logic, imports, and environment variables directly in your config.
  • It integrates tightly with the Forge plugin system.
// forge.config.js
module.exports = {
  packagerConfig: {
    asar: true,
    icon: './src/assets/icon'
  },
  makers: [
    {
      name: '@electron-forge/maker-squirrel',
      config: { name: 'my_app' }
    }
  ]
};

electron-builder typically uses a build key in package.json or a separate YAML file.

  • This keeps configuration declarative and separate from logic.
  • It is widely supported by CI/CD tools that parse JSON or YAML.
// package.json
{
  "build": {
    "appId": "com.example.app",
    "mac": {
      "target": "dmg"
    },
    "win": {
      "target": "nsis"
    }
  }
}

electron-packager relies on command-line arguments or a JS API call.

  • There is no standard config file; options are passed directly when running the tool.
  • This makes it flexible for scripts but harder to manage for complex projects.
# CLI usage
npx electron-packager . MyApp --platform=win32 --arch=x64

// Or via JS API
const packager = require('electron-packager');
await packager({ dir: '.', platform: 'win32' });

📦 Installer Generation: Built-In vs Manual

Users expect an installer, not just a folder of files. The tools vary significantly in their ability to create setup wizards.

@electron-forge/core delegates installer creation to "makers".

  • You install specific maker plugins for Windows (Squirrel), macOS (DMG), or Linux (Deb/RPM).
  • This modular approach means you only install what you need.
// forge.config.js
makers: [
  {
    name: '@electron-forge/maker-wix',
    config: { name: 'MyApp' }
  }
]

electron-builder has installer generation built into the core.

  • It supports NSIS, AppImage, DMG, and MSI out of the box.
  • You configure the target formats in the build section without extra plugins.
// package.json
"build": {
  "win": {
    "target": ["nsis", "portable"]
  }
}

electron-packager does not create installers.

  • It only produces the raw application bundle (e.g., .app or .exe).
  • You must use a separate tool like electron-installer-windows to create a setup file.
# Packager only creates the folder
npx electron-packager . MyApp

# You must run a second tool for installers
npx electron-installer-windows --src dist/MyApp-win32-x64

🔄 Auto-Update Support: Integrated vs DIY

Keeping apps up to date is critical for security and features. The level of built-in support varies.

@electron-forge/core works with electron-updater via plugins.

  • The @electron-forge/plugin-auto-update simplifies the setup.
  • It handles the publish step to GitHub or S3 during the build.
// forge.config.js
plugins: [
  {
    name: '@electron-forge/plugin-auto-update',
    config: { provider: 'github' }
  }
]

electron-builder has deep integration with electron-updater.

  • It automatically publishes release artifacts to GitHub, S3, or Spaces.
  • The publish config in package.json defines where updates are hosted.
// package.json
"build": {
  "publish": [
    {
      "provider": "github",
      "owner": "my-org",
      "repo": "my-app"
    }
  ]
}

electron-packager has no update logic.

  • You must manually implement the update check using electron-updater.
  • You also need to manually upload the binaries to your hosting provider.
// Manual implementation required
const { autoUpdater } = require('electron-updater');
autoUpdater.checkForUpdatesAndNotify();
// You must upload files yourself

🧩 Bundler Integration: Webpack & Vite

Modern Electron apps use bundlers like Webpack or Vite. The tools handle this differently.

@electron-forge/core supports bundlers via plugins.

  • Official plugins exist for Webpack and Vite.
  • It manages the build hook to run your bundler before packaging.
// forge.config.js
plugins: [
  {
    name: '@electron-forge/plugin-vite',
    config: { build: ['vite.config.js'] }
  }
]

electron-builder expects your app to be pre-built.

  • You run your bundler (e.g., npm run build) before running builder.
  • It packages the output directory (usually dist or out).
// package.json scripts
"scripts": {
  "build": "vite build",
  "dist": "npm run build && electron-builder"
}

electron-packager also expects a pre-built directory.

  • It takes a source directory and packages it as-is.
  • You are responsible for ensuring the code is transpiled and minified.
# Run bundler first, then package
npm run build
npx electron-packager ./dist MyApp

🛡️ Code Signing: Managed vs Manual

Distributing on macOS and Windows requires code signing to avoid security warnings.

@electron-forge/core manages signing through maker config.

  • You pass certificate details to the specific maker plugin.
  • It handles the timing of signing during the build process.
// forge.config.js
makers: [
  {
    name: '@electron-forge/maker-squirrel',
    config: { certificateFile: 'cert.pfx' }
  }
]

electron-builder automates signing based on environment variables.

  • It detects CSC_LINK or WIN_CSC_LINK automatically.
  • This makes CI/CD setup cleaner for secure environments.
// package.json
"build": {
  "mac": {
    "identity": "Developer ID Application: My Name"
  }
}

electron-packager requires manual signing flags.

  • You must pass osx-sign or sign options explicitly.
  • It does not manage certificates or provisioning profiles for you.
# Manual signing flags
npx electron-packager . MyApp --osx-sign --osx-notarize

🌱 When Not to Use These

These tools are powerful, but they are not always the right fit:

  • Avoid electron-packager for public consumer apps. The lack of installer generation and auto-update support creates too much manual work for production releases.
  • Avoid @electron-forge/core directly if you just want a standard app. Use the CLI instead. Direct core usage is for tooling authors, not app developers.
  • Avoid electron-builder if you need a highly custom build pipeline that doesn't fit its opinionated structure. In that case, scripting electron-packager might offer more freedom.

📌 Summary Table

Feature@electron-forge/coreelectron-builderelectron-packager
Config FormatJS/TS (forge.config.js)JSON/YAML (package.json)CLI Args / JS API
InstallersVia Maker PluginsBuilt-In (NSIS, DMG, etc.)None (Manual Required)
Auto-UpdateVia PluginBuilt-In IntegrationManual Implementation
BundlerVia Plugin (Vite/Webpack)External (Pre-build)External (Pre-build)
SigningMaker ConfigEnv Var / ConfigManual Flags
Best ForForge Ecosystem UsersProduction DistributionInternal/Portable Tools

💡 The Big Picture

electron-packager is the raw engine 🏗️. It does one thing: make the app folder. Use it if you want to build everything else yourself or need a portable binary without installation.

electron-builder is the complete factory 🏭. It takes your code and ships a signed, installable, auto-updating product. It is the standard choice for serious commercial Electron apps.

@electron-forge/core is the custom workshop 🛠️. It powers the Electron Forge experience. Use it if you are building tools within the Forge ecosystem, but for most app developers, the @electron-forge/cli is the practical entry point.

Final Thought: For most teams shipping a product, electron-builder offers the best balance of power and convenience. If you prefer a plugin-based workflow and are already using Forge for scaffolding, stick with the Forge ecosystem. Avoid electron-packager for end-user distribution unless you have a specific reason to manage your own installers.

How to Choose: @electron-forge/core vs electron-builder vs electron-packager

  • @electron-forge/core:

    Choose @electron-forge/core if you are building a custom Electron tooling pipeline or plugin that requires programmatic control over the Forge build process. It is best suited for teams already invested in the Electron Forge ecosystem who need to extend its functionality beyond the standard CLI. For standard app development, most teams should use the @electron-forge/cli which wraps this core logic.

  • electron-builder:

    Choose electron-builder if you need a robust, all-in-one solution for creating installers, handling code signing, and managing auto-updates without writing custom scripts. It is ideal for production applications targeting multiple platforms where you need fine-grained control over the distribution artifacts and publishing workflow.

  • electron-packager:

    Choose electron-packager only if you need a simple, low-level way to convert your source code into an Electron app folder without installers or auto-update logic. It is suitable for internal tools, portable apps, or scenarios where you will build your own installer and distribution pipeline on top of the raw executable.

README for @electron-forge/core

Electron Forge Core

This module contains the core logic of Electron Forge and exposes the base API as a number of simple JS functions.

Basic Usage

import { api } from '@electron-forge/core';

// Package the current directory as an Electron app
api.package(__dirname);

The named export api has it's methods documented over at ForgeAPI. All the methods are async and expose the core forge methods, please note that all user-side configuration is still done through your forge config file or the "config.forge" section of your package.json. This API simply let's you call the methods in node land without using the CLI.

Error Handling

As all methods return a promise you should handle all rejections, you should note that rejections will not always be errors, in fact we commonly reject our promises with just strings so do not assume that properties such as stack or message will exist on thrown errors.