Skip to content

Latest commit

 

History

History
2154 lines (1704 loc) · 64.3 KB

File metadata and controls

2154 lines (1704 loc) · 64.3 KB

API Reference

📖 For tutorials, quick start, and conceptual guides, see README.md.

Contents


Entry API

Import from electron-incremental-update:

import { createElectronApp, startupWithUpdater, autoUpdate } from 'electron-incremental-update'

AppOption

Property Type Description
mainPath? string Path to index file that make startupWithUpdater as default export Generate from plugin configuration by default
updater? `(() => Promisable) UpdaterOption`
onInstall? OnInstallFunction Hooks on rename temp asar path to ${app.name}.asar
beforeStart? (mainFilePath: string, logger?: Logger) => Promisable<void> Hooks before app startup @param mainFilePath main file path of ${app.name}.asar @param logger logger
onStartError? (err: unknown, logger?: Logger) => void Hooks on app startup error @param err installing or startup error @param logger logger
export interface AppOption {
  /**
   * Path to index file that make {@link startupWithUpdater} as default export
   *
   * Generate from plugin configuration by default
   */
  mainPath?: string
  /**
   * Updater options
   */
  updater?: (() => Promisable<Updater>) | UpdaterOption
  /**
   * Hooks on rename temp asar path to `${app.name}.asar`
   */
  onInstall?: OnInstallFunction
  /**
   * Hooks before app startup
   * @param mainFilePath main file path of `${app.name}.asar`
   * @param logger logger
   */
  beforeStart?: (mainFilePath: string, logger?: Logger) => Promisable<void>
  /**
   * Hooks on app startup error
   * @param err installing or startup error
   * @param logger logger
   */
  onStartError?: (err: unknown, logger?: Logger) => void
}

startupWithUpdater

Utils to startup with updater

Parameter Type Description
fn (updater: Updater) => Promisable<void> startup function
export function startupWithUpdater(
  fn: (updater: Updater) => Promisable<void>,
): (updater: Updater) => Promisable<void> { /* ... */ }

Example:

// in electron/main/index.ts
export default startupWithUpdater((updater) => {
  updater.checkUpdate()
})

createElectronApp

Initialize Electron with updater

export async function createElectronApp(appOptions: AppOption = {}): Promise<void> { /* ... */ }

Example:

createElectronApp({
  updater: {
    provider: new GitHubProvider({
      username: 'yourname',
      repo: 'electron',
    }),
  },
  beforeStart(mainFilePath, logger) {
    logger?.debug(mainFilePath)
  },
})

UpdaterErrorCode

export type UpdaterErrorCode = 'ERR_DOWNLOAD' | 'ERR_VALIDATE' | 'ERR_PARAM' | 'ERR_NETWORK'

UpdaterUnavailableCode

export type UpdaterUnavailableCode = 'UNAVAILABLE_ERROR' | 'UNAVAILABLE_DEV' | 'UNAVAILABLE_VERSION'

UpdaterOption

Property Type Description
provider? IProvider Update provider If you will not setup UpdateJSON or Buffer in params when checking update or download, this option is required
SIGNATURE_CERT? string Certifaction key of signature, which will be auto generated by plugin, generate by selfsigned if not set
receiveBeta? boolean Whether to receive beta update
logger? Logger Updater logger
getAppVersion? () => string Override current app version source. This is mainly used by dev tooling where the installed asar version differs from Electron's package version.
export interface UpdaterOption {
  /**
   * Update provider
   *
   * If you will not setup `UpdateJSON` or `Buffer` in params when checking update or download, this option is **required**
   */
  provider?: IProvider
  /**
   * Certifaction key of signature, which will be auto generated by plugin,
   * generate by `selfsigned` if not set
   */
  SIGNATURE_CERT?: string
  /**
   * Whether to receive beta update
   */
  receiveBeta?: boolean
  /**
   * Updater logger
   */
  logger?: Logger
  /**
   * Override current app version source.
   *
   * This is mainly used by dev tooling where the installed asar version differs
   * from Electron's package version.
   */
  getAppVersion?: () => string
}

UpdateInfoWithExtraVersion

Update info with current app version and entry version

export type UpdateInfoWithExtraVersion = UpdateInfo & {
  /**
   * Current app version
   */
  appVersion: string
  /**
   * Current entry version
   */
  entryVersion: string
}

autoUpdate

Auto check update, download and install

export async function autoUpdate(updater: Updater): Promise<void> { /* ... */ }

createElectronApp

Bootstrap function that starts the Electron app, handles asar installation, loads the real main process, and initializes the updater.

function createElectronApp(appOptions?: AppOption): Promise<void>

AppOption

Property Type Description
mainPath string Path to main file inside ${app.name}.asar. Defaults to __EIU_MAIN_FILE__.
updater UpdaterOption | (() => Promisable<Updater>) Updater configuration or async factory.
onInstall OnInstallFunction Hook before renaming temp asar. Default: install(); logger.info('update success!').
beforeStart (mainFilePath: string, logger?: Logger) => Promisable<void> Hook before loading the main module.
onStartError (err: unknown, logger?: Logger) => void Hook called when main module fails to load.

startupWithUpdater

Wrapper for the main process default export. Provides the updater instance to the main function.

function startupWithUpdater(
  fn: (updater: Updater) => Promisable<void>,
): (updater: Updater) => Promisable<void>

autoUpdate

Convenience helper for the full update flow: checks, downloads, and installs.

function autoUpdate(updater: Updater): Promise<void>

Updater

EventEmitter-based class for the update lifecycle.

class Updater<T extends UpdateInfoWithExtraVersion = UpdateInfoWithExtraVersion> extends EventEmitter

Constructor

new Updater(options?: UpdaterOption)

Properties

Property Type Description
provider IProvider Update provider.
receiveBeta boolean Whether to receive beta updates.
logger Logger Logger instance.
forceUpdate boolean Force update check (used in dev).

Methods

Method Returns Description
checkForUpdates() Promise<boolean> Checks for available updates. Emits update-available or update-not-available.
downloadUpdate() Promise<boolean> Downloads, decompresses, verifies, and writes the temp asar. Emits download-progress and update-downloaded.
cancel() void Cancels an ongoing download. Emits update-cancelled.
quitAndInstall() void Restarts the app to install the temp asar.

Events

Event Payload Description
update-available T (extends UpdateInfoWithExtraVersion) A newer version is available.
update-not-available code: UpdaterUnavailableCode, msg: string, info?: T No update is available.
download-progress DownloadingInfo Download progress update.
update-downloaded [] Update has been downloaded and verified.
update-cancelled [] Download was cancelled.
error UpdaterError An error occurred.

UpdaterError

Custom error with a machine-readable code.

class UpdaterError extends Error {
  code: UpdaterErrorCode
  constructor(code: UpdaterErrorCode, info: string)
}
Code Description
ERR_DOWNLOAD Download failed.
ERR_VALIDATE Signature or integrity validation failed.
ERR_PARAM Invalid parameters.
ERR_NETWORK Network error.

Entry Types

UpdaterOption

Property Type Description
provider IProvider Update provider. Required if not providing JSON/Buffer directly.
SIGNATURE_CERT string Cert for signature verification. Auto-generated by plugin.
receiveBeta boolean Whether to receive beta updates.
logger Logger Logger instance.
getAppVersion () => string Override current app version source.

UpdaterErrorCode: 'ERR_DOWNLOAD' | 'ERR_VALIDATE' | 'ERR_PARAM' | 'ERR_NETWORK'

UpdaterUnavailableCode: 'UNAVAILABLE_ERROR' | 'UNAVAILABLE_DEV' | 'UNAVAILABLE_VERSION'

Logger

interface Logger {
  info(msg: string): void
  debug(msg: string): void
  warn(msg: string): void
  error(msg: string, e?: unknown): void
}

UpdateInfoWithExtraVersion

type UpdateInfoWithExtraVersion = UpdateInfo & {
  appVersion: string // current app version
  entryVersion: string // current entry version
}

Provider API

Import from electron-incremental-update/provider:

import {
  GitHubProvider,
  GitHubAtomProvider,
  GitHubApiProvider,
  LocalDevProvider,
} from 'electron-incremental-update/provider'

getHeader

Safe get value from header

Parameter Type Description
headers Record<string, Arrayable<string>> response header
key any target header key
export function getHeader(headers: Record<string, Arrayable<string>>, key: any): any { /* ... */ }

defaultDownloadText

Default function to download json and parse to UpdateJson

Parameter Type Description
url string target url
headers Record<string, any> extra headers
signal AbortSignal abort signal
resolveData ResolveDataFn on resolve
export async function defaultDownloadText<T>(
  url: string,
  headers: Record<string, any>,
  signal: AbortSignal,
  resolveData: ResolveDataFn,
): Promise<T> { /* ... */ }

defaultDownloadUpdateJSON

Default function to download json and parse to UpdateJson

Parameter Type Description
url string target url
headers Record<string, any> extra headers
signal AbortSignal abort signal
export async function defaultDownloadUpdateJSON(
  url: string,
  headers: Record<string, any>,
  signal: AbortSignal,
): Promise<UpdateJSON> { /* ... */ }

defaultDownloadAsar

Default function to download asar buffer, get total size from Content-Length header

Parameter Type Description
url string target url
headers Record<string, any> extra headers
signal AbortSignal abort signal
onDownloading (progress: DownloadingInfo) => void on downloading callback
export async function defaultDownloadAsar(
  url: string,
  headers: Record<string, any>,
  signal: AbortSignal,
  onDownloading?: (progress: DownloadingInfo) => void,
): Promise<Buffer> { /* ... */ }

LocalDevProviderOptions

Property Type Default Description
baseDir string Base directory for update files
chunkSize? number 64 * 1024 Local read chunk size for simulated download progress
chunkDelay? number 30 Delay between chunks in milliseconds
export interface LocalDevProviderOptions {
  /**
   * Base directory for update files
   */
  baseDir: string
  /**
   * Local read chunk size for simulated download progress
   * @default 64 * 1024
   */
  chunkSize?: number
  /**
   * Delay between chunks in milliseconds
   * @default 30
   */
  chunkDelay?: number
}

LocalDevProvider

Update Provider for local development

  • download update json from {baseDir}/{versionPath}
  • download update asar from {baseDir}/{name}-{version}.asar.br This provider is useful for testing updates during development without needing to deploy to a remote server.
Parameter Description
options provider options
export class LocalDevProvider extends BaseProvider { /* ... */ }

UpdateInfoWithURL

export type UpdateInfoWithURL = UpdateInfo & { url: string }

DownloadingInfo

Property Type Description
delta number Download buffer delta
percent number Downloaded percent, 0 ~ 100 If no Content-Length header, will be -1
total number Total size If not Content-Length header, will be -1
transferred number Downloaded size
bps number Download speed, bytes per second
export interface DownloadingInfo {
  /**
   * Download buffer delta
   */
  delta: number
  /**
   * Downloaded percent, 0 ~ 100
   *
   * If no `Content-Length` header, will be -1
   */
  percent: number
  /**
   * Total size
   *
   * If not `Content-Length` header, will be -1
   */
  total: number
  /**
   * Downloaded size
   */
  transferred: number
  /**
   * Download speed, bytes per second
   */
  bps: number
}

VersionJSON

export type VersionJSON = UpdateInfoWithURL & { beta: UpdateInfoWithURL }

IProvider

Property Type Description
name string Provider name
downloadJSON (name: string, versionPath: string, signal: AbortSignal) => Promise<VersionJSON> Download update json @param name app name @param versionPath normalized version path in project @param signal abort signal
downloadAsar (updateInfo: UpdateInfoWithURL, signal: AbortSignal, onDownloading?: (info: DownloadingInfo) => void,) => Promise<Buffer> Download update asar buffer @param updateInfo existing update info @param signal abort signal @param onDownloading hook for on downloading
isLowerVersion (oldVer: string, newVer: string) => boolean Check the old version is less than new version @param oldVer old version string @param newVer new version string
decompressFile (buffer: Buffer) => Promise<Buffer> Function to decompress file using brotli @param buffer compressed file buffer
verifySignature (buffer: Buffer, version: string, signature: string, cert: string,) => Promisable<boolean> Verify asar signature, if signature is valid, returns the version, otherwise returns undefined @param buffer file buffer @param version target version @param signature signature @param cert certificate
export interface IProvider {
  /**
   * Provider name
   */
  name: string
  /**
   * Download update json
   * @param name app name
   * @param versionPath normalized version path in project
   * @param signal abort signal
   */
  downloadJSON: (name: string, versionPath: string, signal: AbortSignal) => Promise<VersionJSON>
  /**
   * Download update asar buffer
   * @param updateInfo existing update info
   * @param signal abort signal
   * @param onDownloading hook for on downloading
   */
  downloadAsar: (
    updateInfo: UpdateInfoWithURL,
    signal: AbortSignal,
    onDownloading?: (info: DownloadingInfo) => void,
  ) => Promise<Buffer>
  /**
   * Check the old version is less than new version
   * @param oldVer old version string
   * @param newVer new version string
   */
  isLowerVersion: (oldVer: string, newVer: string) => boolean
  /**
   * Function to decompress file using brotli
   * @param buffer compressed file buffer
   */
  decompressFile: (buffer: Buffer) => Promise<Buffer>
  /**
   * Verify asar signature,
   * if signature is valid, returns the version, otherwise returns `undefined`
   * @param buffer file buffer
   * @param version target version
   * @param signature signature
   * @param cert certificate
   */
  verifySignature: (
    buffer: Buffer,
    version: string,
    signature: string,
    cert: string,
  ) => Promisable<boolean>
}

URLHandler

Custom URL handler for GitHub provider, useful for mirrors and custom gateways

Parameter Description
url original URL
export type URLHandler = (url: URL) => Promisable<URL | string | undefined | null>

Example:

(url) => {
  url.hostname = 'mirror.ghproxy.com'
  url.pathname = 'https://github.com' + url.pathname
  return url
}

GitHubApiProvider

Update Provider for Github API, you need to upload version.json to release as well

  • check update from https://api.github.com/repos/{user}/{repo}/releases?per_page=1
  • download update json and get version and download url
  • download update asar from update info you can setup urlHandler in options to modify url before request
Parameter Description
options provider options

Extends: GitHubApiProviderOptions

export class GitHubApiProvider extends BaseGitHubProvider<GitHubApiProviderOptions> { /* ... */ }

GitHubAtomProvider

Update Provider for Github repo

  • check update from https://github.com/{user}/{repo}/releases.atom
  • download update json from https://github.com/{user}/{repo}/releases/download/v{version}/{versionPath}
  • download update asar from https://github.com/{user}/{repo}/releases/download/v{version}/{name}-{version}.asar.br you can setup urlHandler in options to modify url before request
Parameter Description
options provider options
export class GitHubAtomProvider extends BaseGitHubProvider { /* ... */ }

BaseGitHubProviderOptions

Property Type Description
user string Github user name
repo string Github repo name
extraHeaders? Record<string, string> Extra headers
urlHandler? URLHandler Custom url handler (some public CDN links). See URLHandler for details.
export interface BaseGitHubProviderOptions {
  /**
   * Github user name
   */
  user: string
  /**
   * Github repo name
   */
  repo: string
  /**
   * Extra headers
   */
  extraHeaders?: Record<string, string>
  /**
   * Custom url handler ([some public CDN links](https://github.com/XIU2/UserScript/blob/master/GithubEnhanced-High-Speed-Download.user.js#L40)). See {@link URLHandler} for details.
   */
  urlHandler?: URLHandler
}

GitHubProviderOptions

Extends: BaseGitHubProviderOptions

Property Type Default Description
branch? string 'HEAD' Github branch name that fetch version
export interface GitHubProviderOptions extends BaseGitHubProviderOptions {
  /**
   * Github branch name that fetch version
   * @default 'HEAD'
   */
  branch?: string
}

GitHubProvider

Update Provider for Github repo

  • download update json from https://github.com/{user}/{repo}/raw/HEAD/{versionPath}
  • download update asar from https://github.com/{user}/{repo}/releases/download/v{version}/{name}-{version}.asar.br you can setup urlHandler in options to modify url before request
Parameter Description
options provider options

Extends: GitHubProviderOptions

export class GitHubProvider extends BaseGitHubProvider<GitHubProviderOptions> { /* ... */ }

IProvider

The contract all providers must implement.

interface IProvider {
  name: string
  downloadJSON(name: string, versionPath: string, signal: AbortSignal): Promise<VersionJSON>
  downloadAsar(
    updateInfo: UpdateInfoWithURL,
    signal: AbortSignal,
    onDownloading?: (info: DownloadingInfo) => void,
  ): Promise<Buffer>
  isLowerVersion(oldVer: string, newVer: string): boolean
  decompressFile(buffer: Buffer): Promise<Buffer>
  verifySignature(
    buffer: Buffer,
    version: string,
    signature: string,
    cert: string,
  ): Promisable<boolean>
}
Method Description
downloadJSON Downloads and parses version.json.
downloadAsar Downloads the compressed asar file.
isLowerVersion Compares two version strings. Returns true if oldVer < newVer.
decompressFile Decompresses the asar buffer.
verifySignature Verifies the asar signature against the cert.

GitHubProvider

Reads version.json from a GitHub repository branch and downloads the asar from GitHub Releases.

import { GitHubProvider } from 'electron-incremental-update/provider'

const provider = new GitHubProvider({
  user: 'your-github-user',
  repo: 'your-repo',
  branch: 'HEAD',
})

Constructor options

Option Type Default Description
user string required GitHub user or organization.
repo string required GitHub repository name.
branch string 'HEAD' Branch to read version.json from.
extraHeaders Record<string, string> Extra HTTP headers for requests.
urlHandler URLHandler Transform URLs before requests (mirrors, gateways).

Default URLs:

  • update JSON: https://github.com/{user}/{repo}/raw/{branch}/{versionPath}
  • asar: https://github.com/{user}/{repo}/releases/download/v{version}/{name}-{version}.asar.br

GitHubAtomProvider

Reads the latest release tag from releases.atom, then fetches update JSON and asar from that release.

import { GitHubAtomProvider } from 'electron-incremental-update/provider'

const provider = new GitHubAtomProvider({
  user: 'your-github-user',
  repo: 'your-repo',
})

Constructor options: Same as GitHubProvider minus branch.

GitHubApiProvider

Uses the GitHub Releases API. Supports a token for private repos or higher rate limits.

import { GitHubApiProvider } from 'electron-incremental-update/provider'

const provider = new GitHubApiProvider({
  user: 'your-github-user',
  repo: 'your-repo',
  token: process.env.GITHUB_TOKEN,
})

Constructor options: Same as GitHubProvider minus branch, plus:

Option Type Description
token string GitHub personal access token.

GitHub URL Handling

All GitHub providers support urlHandler for mirrors, custom gateways, or request rewriting.

const provider = new GitHubProvider({
  user: 'your-github-user',
  repo: 'your-repo',
  urlHandler(url) {
    url.hostname = 'mirror.example.com'
    url.pathname = `https://github.com${url.pathname}`
    return url
  },
})

LocalDevProvider

Reads update metadata and compressed asar from the local filesystem. Used for development testing.

import { LocalDevProvider } from 'electron-incremental-update/provider'

const provider = new LocalDevProvider({
  baseDir: 'release/local-update',
  chunkSize: 32 * 1024,
  chunkDelay: 50,
})

Constructor options

Option Type Default Description
baseDir string required Directory containing version.json and asar.
chunkSize number 64 * 1024 Simulated download chunk size in bytes.
chunkDelay number 30 Delay between chunks in milliseconds.

It reads from:

  • {baseDir}/{versionPath}
  • {baseDir}/{name}-{version}.asar.br

Prefer localDevUpdate: true in the Vite plugin over constructing LocalDevProvider manually. See Plugin Options.

Provider Types

UpdateInfo

interface UpdateInfo {
  signature: string
  minimumVersion: string
  version: string
}

UpdateInfoWithURL: UpdateInfo & { url: string }

VersionJSON: UpdateInfoWithURL & { beta: UpdateInfoWithURL }

DownloadingInfo

interface DownloadingInfo {
  delta: number // download buffer delta
  percent: number // 0-100, or -1 if Content-Length unknown
  total: number // total bytes, or -1 if unknown
  transferred: number // downloaded bytes
  bps: number // bytes per second
}

URLHandler: (url: URL) => Promisable<URL | string | undefined | null>


Vite Plugin API

Import from electron-incremental-update/vite:

import { electronWithUpdater, defineElectronConfig } from 'electron-incremental-update/vite'

filterErrorMessageStartup

Filter error messages from stdout/stderr during startup

Parameter Type Description
args `` Startup arguments
filter (msg: string) => boolean Filter function to determine which messages to show
export async function filterErrorMessageStartup(filter: (msg: string) => boolean): Promise<void> { /* ... */ }

fixWinCharEncoding

Fix Windows character encoding by setting code page to UTF-8

  • @returns Wrapped function with Windows encoding fix
Parameter Type Description
fn T Function to wrap with encoding fix
export function fixWinCharEncoding<T extends AnyFunction>(fn: T): T { /* ... */ }

electronWithUpdater

Base on vite-plugin-electron/multi-env

  • integrate with updater
  • no renderer config
  • remove old output file
  • externalize dependencies
  • auto restart when entry file changes You can override all the environment configs, except output directories (use options.updater.paths.electronDistPath instead)
export async function electronWithUpdater(
  options: ElectronWithUpdaterOptions,
): Promise<Plugin[] | undefined> { /* ... */ }

Example:

import { defineConfig } from 'vite'
import { electronWithUpdater } from 'electron-incremental-update/vite'

export default defineConfig(async ({ command }) => {
  const isBuild = command === 'build'
  return {
    plugins: [
      electronWithUpdater({
        isBuild,
        main: {
          files: ['./electron/main/index.ts', './electron/main/worker.ts'],
        },
        preload: {
          files: './electron/preload/index.ts',
        },
        updater: {
          // options
        }
      }),
    ],
  }
})

ElectronViteHelperOptions

Extends: ElectronWithUpdaterOptions

Property Type Default Description
root? string process.cwd() Root dir of project
renderer? Omit<UserConfig, 'root'> Config for renderer process
export interface ElectronViteHelperOptions extends ElectronWithUpdaterOptions {
  /**
   * Root dir of project
   * @default process.cwd()
   */
  root?: string
  /**
   * Config for renderer process
   */
  renderer?: Omit<UserConfig, 'root'>
}

defineElectronConfig

Vite config helper See also: electronWithUpdater

export function defineElectronConfig(options: ElectronViteHelperOptions): UserConfig { /* ... */ }

Example:

import { defineElectronConfig } from 'electron-incremental-update/vite'

export default defineElectronConfig({
  // root: './apps'
  main: {
    files: ['./electron/main/index.ts', './electron/main/worker.ts'],
  },
  preload: {
    files: './electron/preload/index.ts',
  },
  updater: {
    // options
  },
  renderer: {
    // plugins: []
  }
})

CommonBuildOption

Property Type Description
files NonNullable<MultiEnvElectronOptions['input']> Shortcut of build.rolldownOptions.input
options? MultiEnvElectronOptions['options'] & { build?: { outDir: never sourcemap: never minify: never rolldownOptions?: { output?: { dir: never } } } } Override vite options
export interface CommonBuildOption {
  /**
   * Shortcut of `build.rolldownOptions.input`
   */
  files: NonNullable<MultiEnvElectronOptions['input']>
  /**
   * Override vite options
   */
  options?: MultiEnvElectronOptions['options'] & {
    build?: {
      outDir: never
      sourcemap: never
      minify: never
      rolldownOptions?: {
        output?: {
          dir: never
        }
      }
    }
  }
}

ElectronWithUpdaterOptions

Extends: Pick

Property Type Default Description
bundleDeps? MultiEnvElectronOptions['bundleDeps'] electron-incremental-update and its subpath imports are always bundled, regardless of this dependency policy.
sourcemap? boolean `!isBuild
minify? boolean isBuild Whether to minify the code
bytecode? `boolean BytecodeOptions`
buildVersionJson? boolean isCI Whether to generate version json
localDevUpdate? `boolean LocalDevUpdateOptions` false
external? `(string RegExp)[] boolean`
entry { /** * By default, all the unbundled modules will be packaged by packager like electron-builder. * If setup, all the dependenciesinpackage.jsonwill be bundled by default, and you need * to manually handle the native module files. * * If you are usingelectron-buidler, don't forget to append '!node_modules/**'in * electron-build config'sfilesarray */ postBuild?: (args: { /** * Whether is in build mode */ isBuild: boolean /** * Get path fromentryOutputDirPath*/ getPathFromEntryOutputDir: (...paths: string[]) => string /** * Check exist and copy file toentryOutputDirPath* * Iftoabsent, set tobasename(from)* * IfskipIfExistabsent, skip copy iftoexist */ copyToEntryOutputDir: (options: { from: string to?: string /** * Skip copy iftoexist * @default true */ skipIfExist?: boolean }) => void /** * Copy specified modules to entry output dir, just likeexternaloption in rolldown */ copyModules: (options: { /** * External Modules */ modules: string[] /** * Skip copy ifto exist * @default true */ skipIfExist?: boolean }) => void }) => Promisable<void> } & CommonBuildOption Options for entry (app.asar) To change output directories, use options.updater.paths.electronDistPath instead
main { /** * Electron App startup function. * * It will mount the Electron App child-process to process.electronApp. * @param argv default value ['.', '--no-sandbox']* @param options options forchild_process.spawn * @param customElectronPkg custom electron package name (default: 'electron') */ onstart?: MultiEnvElectronOptions['onstart'] } & CommonBuildOption Main process options To change output directories, use options.updater.paths.electronDistPath instead
preload? CommonBuildOption Preload process options To change output directories, use options.updater.paths.electronDistPath instead
updater? UpdaterOptions Updater options
export interface ElectronWithUpdaterOptions extends Pick<MultiEnvElectronOptions, 'bundleDeps'> {
  /**
   * `electron-incremental-update` and its subpath imports are always bundled,
   * regardless of this dependency policy.
   */
  bundleDeps?: MultiEnvElectronOptions['bundleDeps']
  /**
   * Whether to generate sourcemap
   * @default !isBuild || !!process.env.VSCODE_DEBUG
   */
  sourcemap?: boolean
  /**
   * Whether to minify the code
   * @default isBuild
   */
  minify?: boolean
  /**
   * Whether to generate bytecode
   *
   * **Only support CommonJS**
   *
   * Only main process by default, if you want to use in preload script, please use `electronWithUpdater({ bytecode: { enablePreload: true } })` and set `sandbox: false` when creating window
   */
  bytecode?: boolean | BytecodeOptions
  /**
   * Whether to generate version json
   * @default isCI
   */
  buildVersionJson?: boolean
  /**
   * Generate and serve a local update package during dev startup.
   *
   * This is useful for testing update checks, simulated download progress,
   * and restart/install behavior without publishing a remote release.
   *
   * @default false
   */
  localDevUpdate?: boolean | LocalDevUpdateOptions
  /**
   * Addtional `external` option in `build.rolldownOptions`,
   *
   * If equals `true`,
   * external `dependencies` in `package.json` by default
   */
  external?: (string | RegExp)[] | boolean
  /**
   * Options for entry (app.asar)
   *
   * To change output directories, use `options.updater.paths.electronDistPath` instead
   */
  entry: {
    /**
     * By default, all the unbundled modules will be packaged by packager like `electron-builder`.
     * If setup, all the `dependencies` in `package.json` will be bundled by default, and you need
     * to manually handle the native module files.
     *
     * If you are using `electron-buidler`, don't forget to append `'!node_modules/**'` in
     * electron-build config's `files` array
     */
    postBuild?: (args: {
      /**
       * Whether is in build mode
       */
      isBuild: boolean
      /**
       * Get path from `entryOutputDirPath`
       */
      getPathFromEntryOutputDir: (...paths: string[]) => string
      /**
       * Check exist and copy file to `entryOutputDirPath`
       *
       * If `to` absent, set to `basename(from)`
       *
       * If `skipIfExist` absent, skip copy if `to` exist
       */
      copyToEntryOutputDir: (options: {
        from: string
        to?: string
        /**
         * Skip copy if `to` exist
         * @default true
         */
        skipIfExist?: boolean
      }) => void
      /**
       * Copy specified modules to entry output dir, just like `external` option in rolldown
       */
      copyModules: (options: {
        /**
         * External Modules
         */
        modules: string[]
        /**
         * Skip copy if `to` exist
         * @default true
         */
        skipIfExist?: boolean
      }) => void
    }) => Promisable<void>
  } & CommonBuildOption
  /**
   * Main process options
   *
   * To change output directories, use `options.updater.paths.electronDistPath` instead
   */
  main: {
    /**
     * Electron App startup function.
     *
     * It will mount the Electron App child-process to `process.electronApp`.
     * @param argv default value `['.', '--no-sandbox']`
     * @param options options for `child_process.spawn`
     * @param customElectronPkg custom electron package name (default: 'electron')
     */
    onstart?: MultiEnvElectronOptions['onstart']
  } & CommonBuildOption
  /**
   * Preload process options
   *
   * To change output directories, use `options.updater.paths.electronDistPath` instead
   */
  preload?: CommonBuildOption
  /**
   * Updater options
   */
  updater?: UpdaterOptions
}

LocalDevUpdateOptions

Property Type Default Description
packageJsonPath? string project package.json Package file used for local dev update name/version. This is useful when the Electron app package is not the project root package, such as a playground or example app.
baseDir? string 'release/local-update' Directory that contains local update resources. The generated version file is written under {baseDir}/{versionPath} and update archives are written as {baseDir}/{name}-{version}.asar.br.
chunkSize? number LocalDevProvider default Local read chunk size for simulated download progress.
chunkDelay? number LocalDevProvider default Delay between simulated progress chunks in milliseconds.
export interface LocalDevUpdateOptions {
  /**
   * Package file used for local dev update name/version.
   *
   * This is useful when the Electron app package is not the project root
   * package, such as a playground or example app.
   *
   * @default project package.json
   */
  packageJsonPath?: string
  /**
   * Directory that contains local update resources.
   *
   * The generated version file is written under `{baseDir}/{versionPath}` and
   * update archives are written as `{baseDir}/{name}-{version}.asar.br`.
   *
   * @default 'release/local-update'
   */
  baseDir?: string
  /**
   * Local read chunk size for simulated download progress.
   *
   * @default LocalDevProvider default
   */
  chunkSize?: number
  /**
   * Delay between simulated progress chunks in milliseconds.
   *
   * @default LocalDevProvider default
   */
  chunkDelay?: number
}

UpdaterOptions

Property Type Default Description
minimumVersion? string '0.0.0' Minimum version of entry
paths? { /** * Path to asar file * @default release/${app.name}.asar*/ asarOutputPath?: string /** * Path to app entry output file * @default 'dist-entry' */ entryOutDir?: string /** * Path to version info output, content is {@link UpdateJSON} * @defaultrelease/version.json*/ versionPath?: string /** * Path to compressed asar file * @defaultrelease/${app.name}-${version}.asar.br*/ compressedPath?: string /** * Path to electron build output * @defaultdist-electron*/ electronDistPath?: string /** * Path to renderer build output * @defaultdist */ rendererDistPath?: string } Options for paths
keys? { /** * Path to the pem file that contains private key * If not ended with .pem, it will be appended * * **If UPDATER_PKis set, will read it instead of read fromprivateKeyPath** * @default 'keys/private.pem' */ privateKeyPath?: string /** * Path to the pem file that contains public key * If not ended with .pem, it will be appended * * **If UPDATER_CERTis set, will read it instead of read fromcertPath** * @default 'keys/cert.pem' */ certPath?: string /** * Length of the key * @default 2048 */ keyLength?: number /** * X509 certificate info * * Only generate simple **self-signed** certificate **without extensions** */ certInfo?: { /** * The subject of the certificate * * @default { commonName: ${app.name}, organizationName: org.${app.name} } */ subject?: DistinguishedName /** * Expire days of the certificate * * @default 3650 */ days?: number } } signature config
export interface UpdaterOptions {
  /**
   * Minimum version of entry
   * @default '0.0.0'
   */
  minimumVersion?: string
  /**
   * Options for paths
   */
  paths?: {
    /**
     * Path to asar file
     * @default `release/${app.name}.asar`
     */
    asarOutputPath?: string
    /**
     * Path to app entry output file
     * @default 'dist-entry'
     */
    entryOutDir?: string
    /**
     * Path to version info output, content is {@link UpdateJSON}
     * @default `release/version.json`
     */
    versionPath?: string
    /**
     * Path to compressed asar file
     * @default `release/${app.name}-${version}.asar.br`
     */
    compressedPath?: string
    /**
     * Path to electron build output
     * @default `dist-electron`
     */
    electronDistPath?: string
    /**
     * Path to renderer build output
     * @default `dist`
     */
    rendererDistPath?: string
  }
  /**
   * signature config
   */
  keys?: {
    /**
     * Path to the pem file that contains private key
     * If not ended with .pem, it will be appended
     *
     * **If `UPDATER_PK` is set, will read it instead of read from `privateKeyPath`**
     * @default 'keys/private.pem'
     */
    privateKeyPath?: string
    /**
     * Path to the pem file that contains public key
     * If not ended with .pem, it will be appended
     *
     * **If `UPDATER_CERT` is set, will read it instead of read from `certPath`**
     * @default 'keys/cert.pem'
     */
    certPath?: string
    /**
     * Length of the key
     * @default 2048
     */
    keyLength?: number
    /**
     * X509 certificate info
     *
     * Only generate simple **self-signed** certificate **without extensions**
     */
    certInfo?: {
      /**
       * The subject of the certificate
       *
       * @default { commonName: `${app.name}`, organizationName: `org.${app.name}` }
       */
      subject?: DistinguishedName
      /**
       * Expire days of the certificate
       *
       * @default 3650
       */
      days?: number
    }
  }
  overrideGenerator?: GeneratorOverrideFunctions
}

GeneratorOverrideFunctions

Property Type Description
generateSignature? (buffer: Buffer, privateKey: string, cert: string, version: string,) => Promisable<string> Custom signature generate function @param buffer file buffer @param privateKey private key @param cert certificate string, EOL must be \n @param version current version
generateUpdateJson? (existingJson: UpdateJSON, signature: string, version: string, minVersion: string,) => Promisable<UpdateJSON> Custom generate update json function @param existingJson The existing JSON object. @param signature generated signature @param version current version @param minVersion The minimum version
generateCompressedFile? (buffer: Buffer) => Promisable<Buffer> Custom generate compressed file buffer @param buffer source buffer
export interface GeneratorOverrideFunctions {
  /**
   * Custom signature generate function
   * @param buffer file buffer
   * @param privateKey private key
   * @param cert certificate string, **EOL must be `\n`**
   * @param version current version
   */
  generateSignature?: (
    buffer: Buffer,
    privateKey: string,
    cert: string,
    version: string,
  ) => Promisable<string>
  /**
   * Custom generate update json function
   * @param existingJson The existing JSON object.
   * @param signature generated signature
   * @param version current version
   * @param minVersion The minimum version
   */
  generateUpdateJson?: (
    existingJson: UpdateJSON,
    signature: string,
    version: string,
    minVersion: string,
  ) => Promisable<UpdateJSON>
  /**
   * Custom generate compressed file buffer
   * @param buffer source buffer
   */
  generateCompressedFile?: (buffer: Buffer) => Promisable<Buffer>
}

All option types are auto-generated from JSDoc in the source code. See the sections above for ElectronWithUpdaterOptions, CommonBuildOption, UpdaterOptions, LocalDevUpdateOptions, BytecodeOptions, ElectronViteHelperOptions, etc.


Utilities API

Import from electron-incremental-update/utils:

import {
  aesDecrypt,
  aesEncrypt,
  beautifyDevTools,
  defaultIsLowerVersion,
  defaultSignature,
  defaultDecompressFile,
  defaultVerifySignature,
  defaultCompressFile,
  getAppVersion,
  getEntryVersion,
  getPathFromAppNameAsar,
  getPathFromEntryAsar,
  getPathFromMain,
  getPathFromPreload,
  getPathFromPublic,
  handleUnexpectedErrors,
  hashBuffer,
  importNative,
  isDev,
  isLinux,
  isMac,
  isWin,
  loadPage,
  parseVersion,
  requireNative,
  restartApp,
  setAppUserModelId,
  setPortableDataPath,
  singleInstance,
} from 'electron-incremental-update/utils'

defaultSignature

Default function to generate asar signature, returns generated signature

Parameter Type Description
buffer Buffer file buffer
privateKey string primary key
cert string certificate
version string target version
export function defaultSignature(
  buffer: Buffer,
  privateKey: string,
  cert: string,
  version: string,
): string { /* ... */ }

defaultVerifySignature

Default function to verify asar signature, if signature is valid, returns the version, otherwise returns undefined

Parameter Type Description
buffer Buffer file buffer
version string target version
signature string signature
cert string certificate
export function defaultVerifySignature(
  buffer: Buffer,
  version: string,
  signature: string,
  cert: string,
): boolean { /* ... */ }

getHeader

Safe get value from header

Parameter Type Description
headers Record<string, Arrayable<string>> response header
key any target header key
export function getHeader(headers: Record<string, Arrayable<string>>, key: any): any { /* ... */ }

defaultDownloadText

Default function to download json and parse to UpdateJson

Parameter Type Description
url string target url
headers Record<string, any> extra headers
signal AbortSignal abort signal
resolveData ResolveDataFn on resolve
export async function defaultDownloadText<T>(
  url: string,
  headers: Record<string, any>,
  signal: AbortSignal,
  resolveData: ResolveDataFn,
): Promise<T> { /* ... */ }

defaultDownloadUpdateJSON

Default function to download json and parse to UpdateJson

Parameter Type Description
url string target url
headers Record<string, any> extra headers
signal AbortSignal abort signal
export async function defaultDownloadUpdateJSON(
  url: string,
  headers: Record<string, any>,
  signal: AbortSignal,
): Promise<UpdateJSON> { /* ... */ }

defaultDownloadAsar

Default function to download asar buffer, get total size from Content-Length header

Parameter Type Description
url string target url
headers Record<string, any> extra headers
signal AbortSignal abort signal
onDownloading (progress: DownloadingInfo) => void on downloading callback
export async function defaultDownloadAsar(
  url: string,
  headers: Record<string, any>,
  signal: AbortSignal,
  onDownloading?: (progress: DownloadingInfo) => void,
): Promise<Buffer> { /* ... */ }

isDev

Compile time dev check

export const isDev = __EIU_IS_DEV__

getPathFromAppNameAsar

Get joined path of ${electron.app.name}.asar (not app.asar) If is in dev, always return 'DEV.asar'

export function getPathFromAppNameAsar(...paths: string[]): string { /* ... */ }

getAppVersion

Get app version, if is in dev, return getEntryVersion()

export function getAppVersion(): string { /* ... */ }

getEntryVersion

Get entry version

export function getEntryVersion(): string { /* ... */ }

requireNative

Use require to load native module from entry asar

Parameter Type Description
moduleName string file name in entry
export function requireNative<T = any>(moduleName: string): T { /* ... */ }

Example:

requireNative<typeof import('../native/db')>('db')

importNative

Use import to load native module from entry asar

Parameter Type Description
moduleName string file name in entry
export async function importNative<T = any>(moduleName: string): Promise<T> { /* ... */ }

Example:

await importNative<typeof import('../native/db')>('db')

restartApp

Restarts the Electron app.

export function restartApp(): void { /* ... */ }

setAppUserModelId

Fix app use model id, only for Windows

Parameter Type Description
id string app id, default is org.${electron.app.name}
export function setAppUserModelId(id?: string): void { /* ... */ }

disableHWAccForWin7

Disable hardware acceleration for Windows 7 Only support CommonJS

export function disableHWAccForWin7(): void { /* ... */ }

singleInstance

Keep single electron instance and auto restore window on second-instance event

Parameter Type Description
window BrowserWindow brwoser window to show
export function singleInstance(window?: BrowserWindow): void { /* ... */ }

setPortableDataPath

Set userData dir to the dir of .exe file Useful for portable Windows app

Parameter Type Description
dirName string dir name, default to data
create boolean whether to create dir, default to true
export function setPortableDataPath(dirName: string = 'data', create: boolean = true): void { /* ... */ }

loadPage

Load process.env.VITE_DEV_SERVER_URL when dev, else load html file

Parameter Type Description
win BrowserWindow window
htmlFilePath `` html file path, default is index.html
export function loadPage(win: BrowserWindow, htmlFilePath = 'index.html'): void { /* ... */ }

beautifyDevTools

Beautify devtools' font and scrollbar See also: electron/electron#42055

Parameter Type Description
win BrowserWindow target window
options BeautifyDevToolsOptions sans font family, mono font family and scrollbar
export function beautifyDevTools(win: BrowserWindow, options: BeautifyDevToolsOptions): void { /* ... */ }

getPathFromMain

Get joined path from main dir

Parameter Description
paths rest paths
export function getPathFromMain(...paths: string[]): string { /* ... */ }

getPathFromPreload

Get joined path from preload dir

Parameter Description
paths rest paths
export function getPathFromPreload(...paths: string[]): string { /* ... */ }

getPathFromPublic

Get joined path from publich dir

Parameter Description
paths rest paths
export function getPathFromPublic(...paths: string[]): string { /* ... */ }

getPathFromEntryAsar

Get joined path from entry asar

Parameter Description
paths rest paths
export function getPathFromEntryAsar(...paths: string[]): string { /* ... */ }

handleUnexpectedErrors

Handle all unhandled error

Parameter Type Description
callback (err: unknown) => void callback function
export function handleUnexpectedErrors(callback: (err: unknown) => void): void { /* ... */ }

Version

Property Type Description
major number 4 of 4.3.2-beta.1
minor number 3 of 4.3.2-beta.1
patch number 2 of 4.3.2-beta.1
stage string beta of 4.3.2-beta.1
stageVersion number 1 of 4.3.2-beta.1
export interface Version {
  /**
   * `4` of `4.3.2-beta.1`
   */
  major: number
  /**
   * `3` of `4.3.2-beta.1`
   */
  minor: number
  /**
   * `2` of `4.3.2-beta.1`
   */
  patch: number
  /**
   * `beta` of `4.3.2-beta.1`
   */
  stage: string
  /**
   * `1` of `4.3.2-beta.1`
   */
  stageVersion: number
}

parseVersion

Parse version string to { Version}, like 0.2.0-beta.1

Supported format: major.minor.patch[-stage[.stageVersion]]

Build metadata (+build) and complex semver prerelease identifiers (e.g. 1.0.0-beta.1.2) are not supported yet.

Parameter Type Description
version string version string
export function parseVersion(version: string): Version { /* ... */ }

defaultIsLowerVersion

Default function to check the old version is less than new version

Parameter Type Description
oldVer string old version string
newVer string new version string
export function defaultIsLowerVersion(oldVer: string, newVer: string): boolean { /* ... */ }

UpdateInfo

Update info json

export interface UpdateInfo {
  /**
   * Update Asar signature
   */
  signature: string
  /**
   * Minimum version
   */
  minimumVersion: string
  /**
   * Target version
   */
  version: string
}

UpdateJSON

{ UpdateInfo} with beta

export type UpdateJSON = UpdateInfo & {
  /**
   * Beta update info
   */
  beta: UpdateInfo
}

isUpdateJSON

Check is UpdateJSON

Parameter Type Description
json object any variable
export function isUpdateJSON(json: object): json is UpdateJSON { /* ... */ }

defaultVersionJsonGenerator

Default function to generate UpdateJSON

Parameter Type Description
existingJson UpdateJSON exising update json
signature string sigature
version string target version
minimumVersion string minimum version
export function defaultVersionJsonGenerator(
  existingJson: UpdateJSON,
  signature: string,
  version: string,
  minimumVersion: string,
): UpdateJSON { /* ... */ }

defaultCompressFile

Default function to compress file using brotli

Parameter Type Description
buffer Buffer uncompressed file buffer
export async function defaultCompressFile(buffer: Buffer): Promise<Buffer> { /* ... */ }

defaultDecompressFile

Default function to decompress file using brotli

Parameter Type Description
buffer Buffer compressed file buffer
export async function defaultDecompressFile(buffer: Buffer): Promise<Buffer> { /* ... */ }

Path Helpers

Function Description
getPathFromAppNameAsar(...paths) Path inside ${app.name}.asar. In dev, returns DEV.asar.
getPathFromEntryAsar(...paths) Path inside app.asar.
getPathFromMain(...paths) Path inside the built main directory.
getPathFromPreload(...paths) Path inside the built preload directory.
getPathFromPublic(...paths) Path inside public in dev or renderer output in production.

App Version

Function Description
getAppVersion() Current app version. In dev, returns the entry version.
getEntryVersion() Version from Electron app metadata.

Native Modules

Function Description
requireNative<T>(moduleName) Load CommonJS native helper from app.asar.
importNative<T>(moduleName) Import ES module native helper from app.asar.

App Control

Function Description
restartApp() Restart the Electron app.
singleInstance(window?) Restore and focus window on second-instance.
setPortableDataPath(dirName?, create?) Store user data beside the executable.
setAppUserModelId(id?) Set the Windows app user model ID.

UI Helpers

Function Description
loadPage(win, htmlFilePath?) Load VITE_DEV_SERVER_URL in dev or renderer HTML in production.
beautifyDevTools(win, options) Inject custom CSS/JS into DevTools.

Platform Checks

Constant Value
isDev boolean — compile-time dev check.
isWin booleanprocess.platform === 'win32'.
isMac booleanprocess.platform === 'darwin'.
isLinux booleanprocess.platform === 'linux'.

Lifecycle

Function Description
handleUnexpectedErrors(callback) Register a handler for uncaught errors.

Crypto

Function Signature
hashBuffer (data: string | Buffer, length: number) => Buffer
aesEncrypt (plainText: string, key: Buffer, iv: Buffer) => string
aesDecrypt (encryptedText: string, key: Buffer, iv: Buffer) => string
defaultSignature (buffer: Buffer, privateKey: string, cert: string, version: string) => string
defaultVerifySignature (buffer: Buffer, version: string, signature: string, cert: string) => boolean

Compression

Function Signature
defaultCompressFile (buffer: Buffer) => Promise<Buffer>
defaultDecompressFile (buffer: Buffer) => Promise<Buffer>

Download

Function Signature
defaultDownloadText (url: string, headers: Record<string, any>, signal: AbortSignal, resolveData: ResolveDataFn) => Promise<T>
defaultDownloadUpdateJSON (url: string, headers: Record<string, any>, signal: AbortSignal) => Promise<UpdateJSON>
defaultDownloadAsar (url: string, headers: Record<string, any>, signal: AbortSignal, onDownloading?: (progress: DownloadingInfo) => void) => Promise<Buffer>
getHeader (headers: Record<string, Arrayable<string>>, key: any) => any

Version Parsing

Function Signature Description
parseVersion (version: string) => Version Parse a version string into components.
defaultIsLowerVersion (oldVer: string, newVer: string) => boolean Default version comparator.
isUpdateJSON (json: object) => json is UpdateJSON Type guard for update JSON.
defaultVersionJsonGenerator (existingJson: UpdateJSON, signature: string, version: string, minimumVersion: string) => UpdateJSON Generate version.json with signatures.

Version

interface Version {
  major: number
  minor: number
  patch: number
  stage: string
  stageVersion: number
}