Building an app with Electron and Vue
Tags: vue, webdev, tutorial
Published: 2021-12-22 19:17:57

**Written by [Elijah Asaolu](https://blog.logrocket.com/author/asaoluelijah/)** ✏️

JavaScript is regarded as one of the most commonly used programming languages in the world, as it doesn’t just excel at manipulating elements on the frontend; with this same language, you can create cross-platform mobile applications, develop APIs and work with backend infrastructure, and create desktop applications.

While there have been numerous libraries and frameworks for all of these aspects, Electron stands out when it comes to developing desktop apps with JavaScript, and in this post, we'll look at how to use Vue with Electron to create our first cross-platform desktop application.

## Prerequisites

This article assumes the following prerequisites:

*   Basic understanding of JavaScript
*   Basic familiarity with Vue
*   Node.js and npm installed
*   Prior experience with Electron is a plus, but not required

## What is Electron?

Electron is an open source JavaScript framework for building native cross-platform desktop applications with web technologies (HTML, CSS, and JavaScript). This implies that if you have prior familiarity working with these technologies, you can use the same codebase to develop a desktop application for Windows, Linux, and macOS.

Behind the scenes, Electron combines the Chromium engine with Node.js runtime to read and run your codebase as a standalone desktop program. And, to prove its capabilities, popular desktop programs created using Electron include Slack, VS Code, and WhatsApp Desktop.

### Pros

The following are some of the advantages of using Electron:

*   Single codebase — With Electron, you’ll only need a single codebase to create desktop applications for different operating systems
*   Leverage web skills — If you have prior experience working with basic web stacks (HTML, CSS, and Javascript), it is super easy to get started with Electron
*   Big community — The Electron community is quite a big and active one, a major factor adding to this is because the framework is being used and supported by top companies

### Cons

Just like anything else, there are some downsides to building desktop applications with Electron too. Some of them include:

*   Higher resource consumption — Desktop applications written in Electron are known to consume more CPU and RAM compared to apps written in other environments, such as Java FX, Objective C, and so on
*   Larger app size — As previously stated, Electron applications bundle the Chromium engine during the build process, which results in a big app size even for a simple application

## Vue + Electron

If you've worked with Vue before, it's fairly simple to get started with Electron. This is possible with a Vue CLI plugin called Electron Builder, and in the coming sections, we’ll learn how this plugin works by building a sample application that returns a wholesome list of trending movies from [themoviedb API](https://www.themoviedb.org/).

Here is a preview of what our movie application will look like:

![TMDB Demo App](https://blog.logrocket.com/wp-content/uploads/2021/12/tmdb-demo-electron-vue.png)

### Getting started

Since Electron builder is a Vue CLI plugin. This means we’ll need to install the Vue CLI itself before we can work with it. To do this run:

```bsh
npm install -g @vue/cli
```

Running the above command will install the most recent stable version of Vue CLI, and you can verify that it was successful by running `vue -V`, which should print out the installed version of Vue.

Next, we want to create a new Vue application, so go ahead and run the command below to create a new app named vue-desktop:

```bash
vue create vue-desktop
```

The final step is to add the Vue Electron Builder plugin, and we can do this by running the command below:

```bash
vue add electron-builder
```

This will ask you for the version of Electron you want to add to this Vue project, and once you've done so, you should see a success message indicating that Electron Builder was installed. You can then launch the app by running:

```bash
npm run electron:serve
```

And you should see an output similar to the screenshot below:

![Vue and Electron Builder Setup](https://blog.logrocket.com/wp-content/uploads/2021/12/vue-electron-builder-setup.png)

Closing the dev tool, you should see the complete preview of the application, like in the image below:

![Initial App Preview](https://blog.logrocket.com/wp-content/uploads/2021/12/initial-app-preview.png)

### File structure

When you open the project folder in your preferred text editor, you should be presented with the following files and directory as shown in the image below. And if you've worked with Vue CLI in the past, you will notice that the file structure is pretty much the same. The only change is the addition of a new `background.js` file, and this file is responsible for running our Vue application as a stand-alone desktop application.

![Background.js File Structure](https://blog.logrocket.com/wp-content/uploads/2021/12/background-js-file-structure.png)

In this file, you can configure the default width and height of the window the application launches with, set the application title, add an auto-update feature, among other things.

## Building our movie app

Now that we’re up to speed with Vue Electron Builder, let’s go ahead and start building our trending movie application.

The first step is to open up `public/index.html` and add an entry for Bootstrap and Font Awesome in the head section, like in the code below:

```html
...
<link
  href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css"
  rel="stylesheet"
/>
<link
  rel="stylesheet"
  href="https://pro.fontawesome.com/releases/v5.10.0/css/all.css"
/>
...
```

Next, in the `src/components` folder, create a new file called `MovieCard.vue` and paste the following code into it:

```js
<template>
  <main>
    <div class="card mb-4 shadow-lg border border-secondary bg-dark text-light">
      <img
        class="card-img-top"
        :src="'https://image.tmdb.org/t/p/w500/' + movie.poster_path"
        alt="Card image cap"
      />
      <div class="card-body">
        <p class="card-text">{{ movie.title }}</p>
        <div class="">
          <div class="d-flex justify-content-between align-items-center">
            <div class="btn-group">
              <button type="button" class="btn btn-sm btn-outline-secondary">
                <i class="fas fa-heart"></i>
              </button>
              <button type="button" class="btn btn-sm btn-outline-secondary">
                <i class="fas fa-plus"></i>
              </button>
            </div>
            <small class="ms-auto text-muted"
              >Rating {{ movie.vote_average }}/10</small
            >
          </div>
        </div>
      </div>
    </div>
  </main>
</template>
<script>
export default {
  name: "MovieCard",
  props: {
    movie: {
      type: Object,
      required: true,
    },
  },
};
</script>
```

Here, we have created a `MovieCard` component that accepts a prop containing all of the details for each movie. The next step is to delete all of the code contained in `src/App.vue` and update with the following:

```js
<template>
  <div id="app">
    <div class="container">
      <div class="text-center">
        <h2 class="text-center mt-5">Trending Movies 🍿</h2>
        <p>Keep up with the hottest movies that are trending this week.</p>
      </div>

      <div class="my-4">
        <a href="#" class="mx-3 h4"> Trending today</a>
        <a href="#" class="mx-3 h4">This week</a>
      </div>
    </div>
  </div>
</template>
```

At this point, if we run our application, we should have the following output:

![Step 2 Electron Vue App](https://blog.logrocket.com/wp-content/uploads/2021/12/app-step-2-electron-vue.png)

The final step is to define a method that fetches the most popular movies from the TMDB API. This process would require you to [create a free account](https://www.themoviedb.org/) with them to retrieve your API key.

To do this, update `src/App.vue` with the following code:

```js
<template>
  <div id="app">
    <div class="container">
      <div class="text-center">
        <h2 class="text-center mt-5">Trending Movies 🍿</h2>
        <p>Keep up with the hottest movies that are trending this week.</p>
      </div>

      <div class="my-4">
        <a href="#" @click="getTrendingMovies('day')" class="mx-3 h4">
          Trending today</a
        >
        <a href="#" @click="getTrendingMovies('week')" class="mx-3 h4"
          >This week</a
        >
      </div>

      <div class="row" v-if="movies.length > 0">
        <div class="col-md-3" v-for="(movie, i) in movies" :key="i">
          <movie-card :movie="movie" />
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import MovieCard from "./components/MovieCard.vue";
export default {
  name: "App",
  components: {
    MovieCard,
  },
  data() {
    return {
      movies: [],
      apiKey: "YOUR_API_KEY_HERE",
    };
  },
  methods: {
    getTrendingMovies(category) {
      return fetch(
        `https://api.themoviedb.org/3/trending/movie/${category}?api_key=${this.apiKey}`
      )
        .then((response) => response.json())
        .then((data) => {
          this.movies = data.results;
        });
    },
  },
  mounted() {
    this.getTrendingMovies("day");
  },
};
</script>
```

Here, we imported the `MovieCard` component we created earlier in the script section, and we also added a new method, `getTrendingMovies()`, which is responsible for loading our movies from TMDB API, and we then ran this function in the mounted hook.

And a small change to our markup is looping all of the results returned from TMDB into our `MovieCard` component.

If we refresh our application at this stage, everything should work fine, and you should have an output similar to the image below:

![TMDB Demo App](https://blog.logrocket.com/wp-content/uploads/2021/12/tmdb-demo-electron-vue.png)

### Updating app icon

The Electron icon is set as the default icon for your app, and most of the time, you'll probably want to set your custom icon. You can simply update the app icon by adding a new icon entry in the `newBrowserWindow()` method present in `background.js` like below:

```js
...
const win = new BrowserWindow({
    width: 800,
    height: 600,
    title: "Trending movies",
[+] icon: "./path/to/icon.png",
...
```

## Building the app

Compiling our application as a stand-alone executable file is straightforward. We can do so by running the command below:

```bash
npm run electron:build
```

Keep in mind the executable app that is generated is dependent on the operating system you’re working with. However, Electron Builder allows you to define which platform (or platforms) you want to generate executables for. Available options include Mac, Win, and Linux.

This means to build the Linux version of your applications, you’ll run the following command:

```bash
npm electron:build -- --linux nsis
```

## Conclusion

Throughout this tutorial, we've looked at how to use [Electron](https://blog.logrocket.com/advanced-electron-js-architecture/) and Vue to create a cross-platform desktop application. We also built an example trending movies application to understand how things worked. And the code for the complete application can be found here on [GitHub](https://github.com/AsaoluElijah/vue-electron).

If you enjoy reading the article, do leave a comment below!

---

## Experience your Vue apps exactly how a user does

Debugging Vue.js applications can be difficult, especially when there are dozens, if not hundreds of mutations during a user session. If you’re interested in monitoring and tracking Vue mutations for all of your users in production, [try LogRocket](https://logrocket.com/signup/). 

[![LogRocket Dashboard Free Trial Banner](https://files.readme.io/00591d0-687474703a2f2f692e696d6775722e636f6d2f6a3049327856572e706e67.png)](https://logrocket.com/signup/)

[LogRocket](https://logrocket.com/signup/) is like a DVR for web apps, recording literally everything that happens in your Vue apps including network requests, JavaScript errors, performance problems, and much more. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred.

The LogRocket Vuex plugin logs Vuex mutations to the LogRocket console, giving you context around what led to an error, and what state the application was in when an issue occurred.

Modernize how you debug your Vue apps - [Start monitoring for free](https://logrocket.com/signup/).