Skip to content

feat(vite): support node integration in renderers#4317

Open
tzh476 wants to merge 1 commit into
electron:mainfrom
tzh476:feat/vite-node-integration
Open

feat(vite): support node integration in renderers#4317
tzh476 wants to merge 1 commit into
electron:mainfrom
tzh476:feat/vite-node-integration

Conversation

@tzh476

@tzh476 tzh476 commented Jul 10, 2026

Copy link
Copy Markdown

Closes #3961.

This follows up on #4258 and keeps its renderer-level nodeIntegration API. @rafael81 is retained as a co-author.

Why externalization is not enough

While validating #4258 in Electron, I found that externalizing Electron and Node.js built-ins leaves bare ESM imports in the renderer output. Vite loads that output as a browser module, which fails before application code runs:

Uncaught TypeError: Failed to resolve module specifier "electron".
Relative references must start with either "/", "./", or "../".

The development server similarly resolves Node.js modules to Vite browser-external stubs.

What changed

  • add an opt-in renderer[].nodeIntegration setting
  • load Electron and Node.js built-ins through runtime ESM shims in both serve and build modes
  • support default, named, namespace, side-effect, and dynamic imports
  • keep built-ins out of Vite dependency optimization and CommonJS conversion
  • disable Rollup namespace freezing so CommonJS packages such as fs-extra can augment Node.js modules
  • merge these settings with existing user Vite and Rollup configuration
  • document the required Electron preferences and security implications

The runtime-shim approach follows the model proven by
vite-plugin-electron-renderer,
implemented here only for built-ins so Forge does not gain another runtime
dependency.

Security boundary

This option only configures Vite. The corresponding BrowserWindow must use nodeIntegration: true and contextIsolation: false. It should only load trusted local content; a preload script with contextBridge remains the safer default.

Validation

$ yarn vitest run --project fast packages/plugin/vite/spec
Test Files  4 passed (4)
Tests       19 passed (19)

$ yarn tsc -b packages/plugin/vite --force
# passed

$ yarn eslint packages/plugin/vite/spec/ViteConfig.spec.ts packages/plugin/vite/spec/config/vite.node-integration.config.spec.ts packages/plugin/vite/src/Config.ts packages/plugin/vite/src/config/vite.node-integration.config.ts packages/plugin/vite/src/config/vite.renderer.config.ts
# passed

$ yarn electron-markdownlint packages/plugin/vite/README.md
# passed

I also ran an Electron 39.2.6 / Vite 6.4.3 smoke fixture against the compiled Forge plugin in both development-server and production-build modes. It exercised default, named, namespace, side-effect, and dynamic built-in imports plus a transitive fs-extra CommonJS dependency; both modes delivered the expected IPC result.

Co-authored-by: rafael81 <36774+rafael81@users.noreply.github.com>
@tzh476 tzh476 requested a review from a team as a code owner July 10, 2026 22:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Vite plugin: support nodeIntegration: true in the renderer process.

1 participant