• English
  • Electron options

    There are two layers of electron config — same property name, different scope:

    • Process-level — on main / preload / renderer: module format, dependency externalization, hot reload, and related source-build behavior.
    • App-level — on the top level of defineConfig: launch entry, Electron executable, and process args.

    Electron is always resolved from a project-local install. Version ranges: Compatibility.

    Full example

    rselectron.config.ts
    import { defineConfig } from '@rselectron/core';
    
    export default defineConfig({
      electron: {
        // App-level: launch entry and args
        entry: './out/main/index.js',
        args: ['--trace-warnings'],
      },
      main: {
        root: './src/main',
        source: { entry: { index: './index.ts' } },
        electron: {
          format: 'auto',
          watch: true,
          externalizeDeps: true,
        },
      },
      preload: {
        root: './src/preload',
        source: { entry: { index: './index.ts' } },
        electron: {
          format: 'cjs',
          isolatedEntries: true,
          // Isolation defaults externalizeDeps off so sandboxed preload can ship as one file
          externalizeDeps: false,
        },
      },
      renderer: {
        root: './src/renderer',
        source: { entry: { index: './index.ts' } },
      },
    });

    Process-level fields

    format

    Controls the output module format for main / preload.

    ValueMeaning
    auto (default)Derived from the project-local Electron version and environment
    cjsCommonJS
    esmES Module (requires an Electron version that supports ESM)

    When unset, Rselectron also considers the application manifest "type" and applies the result through Rsbuild output.module. Explicit filenames still win over the default entry filename policy ([name].mjs / [name].cjs / [name].js).

    For "type": "module" apps on Electron that supports ESM Main/Preload, prefer leaving format at auto (Preferred ESM path). Do not pin format: 'cjs' solely to work around import-only / ESM-only dependencies—see Troubleshooting.

    main: {
      electron: { format: 'cjs' }, // explicit override when you intentionally want CJS
    },
    preload: {
      electron: { format: 'esm' },
    },

    Renderer usually does not need format; it uses browser-oriented Rsbuild targets.

    watch

    During dev, opt this process into rebuilds. A successful main rebuild restarts Electron; a successful preload rebuild asks connected renderer pages to fully reload.

    main: {
      electron: { watch: true },
    },
    preload: {
      electron: { watch: true },
    },

    CLI --watch / --watch=main / --watch=preload override electron.watch in config for the session. See CLI.

    externalizeDeps

    For main / preload, decide whether Node dependencies stay in node_modules (externalized) instead of being bundled. Externalization is format-aware: ESM outputs use module-import (and node-commonjs where require originated the external); CJS outputs use CommonJS externals.

    ValueMeaning
    omittedOn by default for main / preload; electron and Node builtins are always external
    trueExplicitly enable
    falseDisable (bundle deps into the output; common for sandboxed preload)
    { include, exclude }Fine-grained: include forces bundling, exclude forces externalization
    main: {
      electron: {
        externalizeDeps: {
          // Bundle ESM-only packages into a CJS output
          include: ['execa'],
          // Force extra externals
          exclude: ['better-sqlite3'],
        },
      },
    },

    electron and Node builtins (including the node: prefix) are always external and ignore include.

    Under CJS Main/Preload, a CommonJS-externalized import-only package (or subpath) can build cleanly and still fail at runtime (ERR_REQUIRE_ESM, is not a function, and similar). Rselectron emits RSELECTRON_IMPORT_ONLY_EXTERNAL for that case. Prefer switching the role to format: 'esm' (or auto under "type": "module") before reaching for include; use include (as with execa above) when you intentionally stay on CJS. electron-vite documents the same failure class; its bundle escape is named exclude—in Rselectron the same intent is include. The framework does not auto-include import-only packages, and bundler-ignore magic comments do not silence the warning. See Troubleshooting · Import-only package fails under CJS main / preload.

    isolatedEntries

    Build isolated entry graphs: disable shared chunks so each entry stays self-contained. Useful for multiple preload scripts or when shared code across entries is undesirable.

    preload: {
      source: {
        entry: {
          browser: './browser.ts',
          webview: './webview.ts',
        },
      },
      electron: {
        isolatedEntries: true,
        externalizeDeps: false,
      },
    },

    With isolatedEntries on preload, dependency externalization defaults to off (so a sandboxed preload can load a single file). Setting externalizeDeps: true explicitly keeps your choice and emits a warning.

    App-level fields

    Top-level electron on the config:

    FieldDescription
    entryElectron launch entry file; falls back to package.json#main when omitted
    packageJsonCustom application manifest path (relative to the project root)
    execPathCustom Electron executable; must be consistent with runtime facts or the run fails
    argsExtra arguments passed to the Electron process
    export default defineConfig({
      electron: {
        entry: './out/main/index.cjs',
        packageJson: './package.json',
        args: ['--no-sandbox'],
      },
      main: {/* ... */},
    });

    More often you point package.json#main at the main-process output instead of setting electron.entry every time. See Getting started · Electron entry.