Top Tools

Building a Vue 3 Desktop App with Vite and Electron

Matt Maribojoc

Matt Maribojoc · 6 min read

May 09, 2021

In this article, we’re going to be taking a look at how to Vue 3 Desktop Project from a Vite app.

To do this, we’re going to be using Electron – one of the most popular frameworks for building cross-platform desktop apps with Javascript. So many popular apps are using Electron like VSCode, Slack, Twitch, and a ton more.

Let’s first take a quick look at what we’re going to be doing in this tutorial..

So this is just the Vite starter template BUT it’s in its own dedicated app – not in our browser. That’s a super cool step and a necessary one to build your own desktop apps.

Alright – let’s jump right into the code.

Creating our Basic Vite App

First, let’s make our Vite app. I’m not going to go into too much detail about how Vite works. If you want to learn more about creating your vue project in Vite, check out our youtube video here.

But basically, let’s go to our terminal and run

Building our Vite app!

bash
npm init @vitejs/app
cd [project-name]
npm install

Alright – let’s first try this out just in our browser.

In our terminal, we can just run a plain old npm run dev. get our local host url, and load it up.

Here’s the Vite starter template!

Perfect – now it’s time to add Electron to this setup.

Adding Electron to Our Vite Project

For this quick start guide, we’re going to be loosely following the Electron’s own quick start guide from the official documentation – and tweaking it a little bit to work inside our Vite application.

The first thing we have to do is actually install Electron – so let’s head over to the terminal and do that.

Install Electron

bash
npm install --save-dev electron

Next, let’s take a quick look at the Electron guide again.

It says that a simple Electron setup needs a four main files:

  • package.json – awesome we already have this

  • main.js

  • preloader.js

  • index.html

At first, it may seem like we already have our main.js and index.html files, but those are the ones we need for Vite NOT the ones we need for Electron. The Vite files are used to run our Vite app, we need separate Electron files for our app.

main.js will create our desktop application and load in index.html, which will have our built Vite app.

Building our Vite App

So first things first, we have to build our Vite app. And since we’re working with Electron, we have to do a little bit of extra configuration.

We want to make sure that when our project is built, that all of its references to the final javascript and css files actually point to the right paths.

Building our Vite project creates a dist folder with the following structure.

But since our Electron code is in our root directory, we want to set the base for our entire project to be this dist folder. We can do this by using the path library and setting the base property in our vite.config.js file.

vite.config.js

javascript
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
const path = require("path");

// https://vitejs.dev/config/
export default defineConfig({
  base: path.resolve(__dirname, "./dist/"),
  plugins: [vue()],
});

Now we can just run npm run build in our terminal to create our own dist folder!

Perfect.

Setting up our Electron main.js

The next step is to create our main.js file in our root directory.

Once it’s created, we can just copy and paste the code from the Electron quick start guide!

There’s one change we have to make though.

Where we’re loading our index.html file, all we have to do is change that to dist/index.html so we’re using the file inside our dist folder.

So the final code inside main.js will look like this…

main.js

javascript
const { app, BrowserWindow } = require("electron");
const path = require("path");

function createWindow() {
  const win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      preload: path.join(__dirname, "preload.js"),
    },
  });

  win.loadFile("dist/index.html");
}

app.whenReady().then(() => {
  createWindow();

  app.on("activate", () => {
    if (BrowserWindow.getAllWindows().length === 0) {
      createWindow();
    }
  });
});

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

Making preload.js

Next up, let’s create our preload.js file in our root directory and once again, we can use the quick start code – but this time we don’t have to change anything.

preload.js

javascript
window.addEventListener("DOMContentLoaded", () => {
  const replaceText = (selector, text) => {
    const element = document.getElementById(selector);
    if (element) element.innerText = text;
  };

  for (const type of ["chrome", "node", "electron"]) {
    replaceText(`${type}-version`, process.versions[type]);
  }
});

Modifying package.json

Alright – almost there, the last thing we have to do is make some changes to our package.json file so that we can actually run some of our Electron commands.

First, we have to set the main property – by default, Electron will look for an index.js file in the root directory to start our app, but since our file is called main.js, we just have to define that in our package.json

package.json

json
{
  "name": "vite-electron",
  "version": "0.0.0",
  "main": "main.js", // this line
  ...
}

The final thing we have to do is actually make a way to run Electron, so inside the scripts section, let’s make a new script called electron:start that runs electron .

package.json

json
{
  "name": "vite-electron",
  "version": "0.0.0",
  "main": "main.js",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "serve": "vite preview",
    "electron:start": "electron ." // here
  },
  ...
}

And that’s all of the code to build our basic Electron app.

All we have to do now is go to our terminal and say npm run electron:start and…

We have our desktop app! Amazing 🙂

And that’s it!

Obviously, this is just a quick starter guide to get a basic Electron setup inside of Vite.

If you want to see more Vite + Electron tutorials, let me know in the replies because overall i love to teach what you find interesting. so if enough of you want, maybe ill start a series where we build a large Vue desktop app together.

But until then, happy coding!


Join the LearnVue Community

Every week we send out exclusive content to thousands of developers on our mailing list. 100% Free.

Latest Posts

Top Tools

Making a Markdown-Based Blog with Vue and Gridsome

Use Vue with Gridsome is one of the easiest ways to create static websites from just Markdown files.

Matt Maribojoc · 12 min Read More
Top Tools

5 VueUse Library Functions That Can Speed Up Development

VueUse is an open-source project that provides Vue developers with a huge collection of essential Composition API utility functions for both Vue 2 and Vue 3.

Matt Maribojoc · 12 min Read More
Dev Tips

Lazy Load Components in Vue with defineAsyncComponent

Using Vue 3’s defineAsyncComponent feature lets us lazy load components - meaning they’re only loaded when they’re needed.

Matt Maribojoc · 7 min Read More
Essentials

The Beginner’s Guide to Vue Template Refs - with Vue 3 Updates

Vue Template Refs give our Javascript code a reference to easily access the template.

Matt Maribojoc · 5 min Read More