Open-source project
electron-vite/vite-plugin-electron avatar
electron-vite/vite-plugin-electron

vite-plugin-electron: the dev loop Vite was missing for Electron

:electron: Electron⚡️Vite core repo

922 stars76 forksTypeScriptMIT

At a glance

What is it?
vite-plugin-electron makes an Electron project develop like an ordinary Vite app by rebuilding and restarting the main process, reloading preload scripts and hot reloading the renderer, then launching the app for you from the build hook. It exposes a simple preset API, a flat low-level API and a multi-env entry point built on Vite's Environment API, and it supports both Vite 7 and Vite 8.
Who is it for?
vite-plugin-electron fits front-end teams that have standardised on Vite and want an Electron application to build and run through the same toolchain, with the main, preload and renderer targets each getting the reload behaviour it actually needs. It does not fit projects on webpack or on a dedicated Electron build system, and the flat API is only worth its extra flexibility if you know the plugin internals.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 26 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The three-process problem Vite does not know about

An Electron application has three parts that need different treatment from a bundler: a main process that runs Node, a preload script that bridges Node and the browser context, and a renderer that is an ordinary web page. A Vite project has one of those. That mismatch is the problem vite-plugin-electron addresses, and the summary in the README is that it makes developing Electron apps as easy as normal Vite projects. The mechanism is a set of Vite plugins that watch the right sources, rebuild the right outputs and then drive Electron itself. The repository is the core of the electron-vite organisation, with a `playground/` directory holding example projects for the flat, simple, multi-env and worker variants, a `migrate-to-v1.md` guide for projects coming from the 0.x line, and the plugin sources in `src/`. The audience is a JavaScript or TypeScript team already using Vite for its web work who now needs a desktop shell without changing build tools.

Hot restart, hot reload and HMR are different things here

The feature list is short and the three entries are the whole point. Hot Restart applies to the main process: when the main code changes, the process is restarted rather than patched, because main process state lives in a Node process that has no DOM to swap. Hot Reload applies to preload scripts, where the script is reloaded so the bridge is rebuilt with the new behaviour. HMR applies to the renderer process, where the page updates in place through Vite's own module replacement. Treating these as one thing is the classic mistake in Electron tooling, and the plugin separates them explicitly. That separation is also a limitation to keep in mind: main process changes cost you a restart, which means the state your main process held is gone, so a long-running connection or an in-memory cache will not survive a code change in that process.

The simple API presets, the flat API exposes

There are two entry points, and the README is clear about when to use each. The `vite-plugin-electron/simple` API is recommended in most cases and is what the quick setup uses. The flat API, imported from `vite-plugin-electron` itself, is for people who know the plugin well or want to build a secondary encapsulation of the low-level API on top of it. The technical difference is narrow but real: the flat API does not identify which entry represents the preload script, and therefore does not apply the preload adaptation. The README summarises the relationship as the simple API being based on the flat API, the simple API including preload script preset configs, and the flat API providing more general APIs that can be used for secondary encapsulation, with nuxt-electron given as an example of that pattern. The type signature is `electron(options: ElectronOptions | ElectronOptions[])`, so a single target and an array of targets are both first class.

The multi-env entry point builds targets through Vite environments

The third entry point, `vite-plugin-electron/multi-env`, uses Vite's Environment API to build the Electron targets instead of calling `build()` manually. The README calls it the future-facing way to handle multi-target builds and says the configuration is more concise and easier to maintain, with the entry and overridable environment config for each target specified through `rolldownOptions.input` on Vite 8 and later, or `rollupOptions.input` on earlier versions. The plugin is explicit about availability: the multi-env entry point only exists in `vite-plugin-electron@>=1.0.0` and is not present in 0.x releases. Its configuration is an array of targets, one for the main entry and one for the preload entry, and the same simple variant exists on top of it. For a team with several Electron entry points, this is the shape that scales without hand-written build orchestration.

Setting it up in four steps

Install the plugin as a development dependency:

sh
npm i -D vite-plugin-electron

Then add it to the `plugins` section of `vite.config.ts` using the simple API:

ts
import electron from 'vite-plugin-electron/simple'

export default {
  plugins: [
    electron({
      main: {
        // Shortcut of `build.lib.entry`
        entry: 'electron/main.ts',
      },
      preload: {
        // Shortcut of `build.rolldownOptions.input` (`build.rollupOptions.input` on Vite < 8)
        input: 'electron/preload.ts',
      },
      // Optional: Use Node.js API in the Renderer process
      renderer: {},
    }),
  ],
}

Next, create `electron/main.ts` with a window that loads the dev server when one is running and the built file otherwise:

ts
import { app, BrowserWindow } from 'electron'

app.whenReady().then(() => {
  const win = new BrowserWindow({
    title: 'Main window',
  })

  // You can use `process.env.VITE_DEV_SERVER_URL` when the vite command is called `serve`
  if (process.env.VITE_DEV_SERVER_URL) {
    win.loadURL(process.env.VITE_DEV_SERVER_URL)
  } else {
    // Load your file
    win.loadFile('dist/index.html')
  }
})

Finally, point the `main` entry of package.json at `dist-electron/main.js`, since the files in the `electron` folder are built into the `dist-electron` directory by default.

The plugin starts Electron for you

The launch behaviour is small but is what turns a build into a running app. The README explains that the plugin just executes the `electron .` command in the Vite `closeBundle()` hook and then starts or restarts the Electron app. The main process entry in package.json is `dist-electron/main.js`, and the renderer is loaded from the dev server URL when the Vite command is `serve`, otherwise from `dist/index.html`. For projects that need to control the launch themselves, the `onstart` option is the escape hatch. When `onstart` is passed, the Electron app does not start automatically, and you start it through the `startup` function, which returns `true` if the app was started and `false` if the startup was prevented by `startup.prevent` or the `ELECTRON_STARTUP_PREVENT` environment variable. The startup function takes an argv array whose default value is `['.', '--no-sandbox']`, spawn options, and a custom Electron package name that defaults to `electron`.

Electron flags pass through the startup hook

The `onstart` signature is where the plugin exposes a small set of environment variables that control Electron CLI flags: `REMOTE_DEBUGGING_PORT`, `ELECTRON_IGNORE_CERTIFICATE_ERRORS`, `ELECTRON_DISABLE_WEB_SECURITY`, `ELECTRON_INSPECT` and `ELECTRON_INSPECT_BRK`. The documented convention is that `1` or `true` turns a flag on, `0` or `false` turns it off, and any other non-empty value is appended as `=<value>`, which is how a debug port is chosen. The same hook exposes `reload`, documented as reloading the Electron renderer, so a script can trigger a renderer reload without the usual file watcher path. Two of those variables disable security mechanisms in Electron, so on a project that ships to users they should be treated as development conveniences that never reach a release configuration. On maintenance, the plugin is versioned past 1.x, with v1.1.0 in June 2026, v1.1.1 in August 2026 and v1.1.2 on 2026-08-31, and the last push was on 2026-09-28. The licence is MIT, with the `LICENSE` file in the repository root.

Editorial conclusion

vite-plugin-electron fits front-end teams that have standardised on Vite and want an Electron application to build and run through the same toolchain, with the main, preload and renderer targets each getting the reload behaviour it actually needs. It does not fit projects on webpack or on a dedicated Electron build system, and the flat API is only worth its extra flexibility if you know the plugin internals. Before adopting it, check that your Vite version is covered, since the build config keys differ between Vite 8 and earlier, decide between the simple and flat API based on whether you need custom preload handling, and confirm the `main` entry in package.json points at dist-electron/main.js.

Frequently asked questions

How do I add vite-plugin-electron to a Vite project?

Install it with npm i -D vite-plugin-electron, then import electron from 'vite-plugin-electron/simple' in vite.config.ts and pass main and preload entries. Finally add the main entry dist-electron/main.js to package.json, since the electron folder is built into dist-electron by default.

Which Vite versions does vite-plugin-electron support?

The plugin supports both Vite 7 and Vite 8, and adapts build config keys automatically, using rolldownOptions on Vite 8 and later and rollupOptions on earlier versions.

What is the difference between the simple API and the flat API?

The simple API is recommended for most projects and includes preset configs for preload scripts. The flat API does not identify which entry is the preload script and so does not apply the preload adaptation, but it exposes more general APIs for building a secondary encapsulation.

How can I control when the Electron app starts?

Pass the onstart option, which stops the app from starting automatically and lets you start it through the startup function. That function accepts an argv array defaulting to ['.', '--no-sandbox'], spawn options, and a custom Electron package name.

Official sources

  1. electron-vite/vite-plugin-electron on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/electron-vite-vite-plugin-electron.svg)](https://hysenlabs.com/projects/electron-vite-vite-plugin-electron)

Was this useful?