How to create an Electron application with Vite
Tags: javascript, electron, svelte, vite
Published: 2021-12-09 20:34:12

**Note:** Cet article est disponible en français [ici](https://dev.to/olyno/comment-creer-une-application-electron-avec-vite-4noe)

To be able to create a software with Electron is not so complicated. [Lots of boilerplates](https://github.com/sindresorhus/awesome-electron#boilerplates) exist,  [documentation](https://www.electronjs.org/docs/latest/tutorial/quick-start) is really good...
However, i couldn't find anything to explain how to create an Electron project with Vite. So let's get right to it.

## Create the default Vite application

For this nothing is easier. I will use Yarn for my installation. Using the command:

```
yarn create vite
```

We just have to fill the prompt with the name of our project (in our case "electron-vite"), and pick a framework (in our case "Svelte"). 

We then move to our project folder and install our dependencies:

```
cd electron-vite
yarn install
```

## Install the builder

The builder will allow us to create the final electron application and deploy the software to production.  We will use [Electron Forge](https://www.electronforge.io/). 
We can install it with the following command:

```
yarn add --dev @electron-forge/cli
```

Once the forge CLI is installed, we just need to set it up. Fortunately, Electron Forge takes care of everything. We just have to run:

```
yarn electron-forge import
```

And the different scripts will be added to our ``package.json`` file.

## Let's edit the package.json

We still have some dependencies to install:

```shell
concurrently # To run Vite and Electron at the same time
cross-env    # To be able to set an environment at launch
```

To install them, we just have to do:

```
yarn add -D concurrently cross-env
```

Now that we have all the dependencies installed, we just have to setup the different scripts:

```json
"scripts": {
  "start": "npm run build && npm run electron:start",
  "dev": "concurrently -k "vite" "npm run electron:dev"",
  "build": "vite build",
  "preview": "vite preview",
  "electron:dev": "cross-env IS_DEV=true electron-forge start",
  "electron:build": "electron-forge make",
  "electron:package": "electron-forge package"
},
```

> You can modify the ``yarn`` by ``npm run`` in the different scripts

The environment variable ``IS_DEV`` can of course be renamed to ``NODE_ENV`` for example.

We are missing 3 fields to add/modify:

```
"main": "app/index.js",
"description": "Boilerplate Electron + Vite + Svelte",
"license": "MIT",
```

The ``main`` field will be the entry point of our Electron application.

The fields ``description`` and ``license`` are necessary to build Electron with Electron Forge.

## Let's edit the config of Vite

Nothing very complicated. First of all, we will have to modify the ``base`` of our application. If the application goes into production, then we will look for the files to import (like the assets). Then, we will just have to modify the build folder so that it is linked to our Electron application.

```js
import { svelte } from '@sveltejs/vite-plugin-svelte';
import { defineConfig } from 'vite';

// https://vitejs.dev/config/
export default defineConfig({
  base: process.env.IS_DEV !== 'true' ? './' : '/',
  build: {
    outDir: 'app/build',
  },
  plugins: [svelte()],
});
```

## We setup Electron

To create our Electron application, we just have to create a file ``app/index.js`` which will contain the default code of Electron:

```js
// app/index.js
const path = require('path');
const { app, BrowserWindow } = require('electron');

// Handle creating/removing shortcuts on Windows when installing/uninstalling.
if (require('electron-squirrel-startup')) {
  app.quit();
}

const isDev = process.env.IS_DEV === 'true';

function createWindow() {
  // Create the browser window.
  const mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      preload: path.join(__dirname, 'preload.js'),
      nodeIntegration: true,
    },
  });

  // Open the DevTools.
  if (isDev) {
    mainWindow.loadURL('http://localhost:3000');
    mainWindow.webContents.openDevTools();
  } else {
    // mainWindow.removeMenu();
    mainWindow.loadFile(path.join(__dirname, 'build', 'index.html'));
  }
}

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(() => {
  createWindow();
  app.on('activate', function () {
    // On macOS it's common to re-create a window in the app when the
    // dock icon is clicked and there are no other windows open.
    if (BrowserWindow.getAllWindows().length === 0) createWindow();
  });
});

// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit();
  }
});
```

In the above code, there are 2 things to note:

1. The following code is needed if you want to build your application with "squirrel" (a build template for Windows). 

```js
if (require('electron-squirrel-startup')) {
  app.quit();
}
```

2. About how to get the content:

```js
if (isDev) {
  mainWindow.loadURL('http://localhost:3000');
  mainWindow.webContents.openDevTools();
} else {
  // mainWindow.removeMenu(); // Optional
  mainWindow.loadFile(path.join(__dirname, 'build', 'index.html'));
}
```

If we are dev, we will just load a url which will be the one of Vite. However, if we are building our application for production, then we will need to get the ``index.html`` file directly.

Finally, we just need to create an ``app/preload.js`` file.

> Electron does not yet support esm syntaxes, so we will use the ``require``.

## We modify the Svelte config file

So yes, even if our application is finished, Electron doesn't support esm syntaxes, so we have to modify the import/export in require/module:

```js
// svelte.config.js

const sveltePreprocess = require('svelte-preprocess');

module.exports = {
  // Consult https://github.com/sveltejs/svelte-preprocess
  // for more information about preprocessors
  preprocess: sveltePreprocess(),
};
```

And that's it, you have just created your software with Vite et Electron! The livereload works perfectly, what more could you want!

You can find the repository at this link: https://github.com/frontend-templates-world/svelte-ts-electron-vite