DEV Community

Cover image for Electron + React + Vite + Typescript
Abdallah Mohammad
Abdallah Mohammad

Posted on • Updated on

Electron + React + Vite + Typescript

What is React ⚛️

React is a JavaScript library developed by Facebook which, among other things, was used to build Instagram.com. Its aim is to allow developers to easily create fast user interfaces for websites and applications alike. The main concept of React. js is virtual DOM

What is Electron

Electron.js is a runtime framework that allows the user to create desktop-suite applications with HTML5, CSS, and JavaScript. It’s an open source project started by Cheng Zhao, an engineer at GitHub.

What is Vite ⚡

Vite is a build tool created by Evan You, the creator of Vue. It allows for faster development thanks to super fast Hot Module Reload (HMR), fast cold start times, and CSS + JSX + TypeScript support out of the box.

How to merge them together

At first we will initialize a new vite app using

  • yarn yarn create vite
  • npm npm create vite

Now answer the questions
you will get something like this
Terminal Output

Now cd into the new directory and install the dependencies for me i will use
cd vite-project && npm install

  • Optional add sass support using npm i --save-dev sass and vite will automatically detect it

Right now we have a functional react project
you can test it using npm run dev

Add electron

First run npm i --save-dev electron vite-electron-plugin

and create a directory named src-electron
and create file main.ts inside it with the following code

import { app, BrowserWindow, shell, ipcMain } from "electron";
import { release } from "node:os";
import { join } from "node:path";

// Disable GPU Acceleration for Windows 7
if (release().startsWith("6.1")) app.disableHardwareAcceleration();

// Set application name for Windows 10+ notifications
if (process.platform === "win32") app.setAppUserModelId(app.getName());

if (!app.requestSingleInstanceLock()) {
  app.quit();
  process.exit(0);
}

let win: BrowserWindow | null = null;
// Here, you can also use other preload
const url = process.env.VITE_DEV_SERVER_URL;
const DIST = join(__dirname, "..", "dist");
const indexHtml = join(DIST, "index.html");
const isDev = !app.isPackaged;

// Save userData in separate folders for each environment.
// Thanks to this you can use production and development versions of the app
// on same machine like those are two separate apps.
if (isDev) {
  const userDataPath = app.getPath("userData");
  app.setPath("userData", `${userDataPath}(dev)`);
}

async function createWindow() {
  win = new BrowserWindow({
    title: "Main window",
  });

  if (isDev) {
    win.loadURL(url);
    // Open devTool if the app is not packaged
    win.webContents.openDevTools();
    return;
  }
  // If not dev load html file
  win.loadFile(indexHtml);
}

app.whenReady().then(createWindow);

app.on("window-all-closed", () => {
  win = null;
  if (process.platform !== "darwin") app.quit();
});

app.on("second-instance", () => {
  if (win) {
    // Focus on the main window if the user tried to open another
    if (win.isMinimized()) win.restore();
    win.focus();
  }
});

app.on("activate", () => {
  const allWindows = BrowserWindow.getAllWindows();
  if (allWindows.length) {
    allWindows[0].focus();
  } else {
    createWindow();
  }
});

Enter fullscreen mode Exit fullscreen mode

Familiar Vite React application structure, just with src-electron folder on the top 😉

Files in this folder will be separated from your React application and built into dist-electron

├── src-electron                 Electron-related code
│   ├── main.ts                  Main-process source code
│
├── public                       Static assets
└── src                          Renderer source code, your React application
Enter fullscreen mode Exit fullscreen mode

And now we will tell vite to compile our electron code by updating vite.config.ts to look like this

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import electron from "vite-electron-plugin";
import { rmSync } from "node:fs";

// Remove previously compiled electron to prevent code from conflicting
rmSync("dist-electron", { recursive: true, force: true });


// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    react(),
    electron({
      // Include our electron code
      include: ["src-electron"],
    }),
  ],
});

Enter fullscreen mode Exit fullscreen mode

We have two steps left to have every thing working
Update the package.json to include compiled electron code

{
  "name": "vite-project",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "main": "dist-electron/main.js", <-- The new line
  "scripts": {
    "dev": "vite",
    "build": "tsc && vite build",
    "preview": "vite preview"
  },
  "dependencies": {
    "react": "^18.2.0",
    "react-dom": "^18.2.0"
  },
  "devDependencies": {
    "@types/react": "^18.0.27",
    "@types/react-dom": "^18.0.10",
    "@vitejs/plugin-react": "^3.1.0",
    "electron": "^23.0.0",
    "typescript": "^4.9.3",
    "vite": "^4.1.0",
    "vite-electron-plugin": "^0.7.4"
  }
}
Enter fullscreen mode Exit fullscreen mode

Now run npm run dev this will start react server
and compile our electron code and start electron.
Running npm run dev will now give you an error saying that "type":"module" is not supported
so we will remove "type":"module" from our package.json and re run the command and we will have our electron app running

If you want to know how to add nodeIntegration or How to use electron builder with this setup request from me and hopefully I will create a new post for each one because they will need more code and dependencies

Top comments (1)

Collapse
 
reacthunter0324 profile image
React Hunter

It's a good boilerplate for starter
Thanks