Written by Elijah Asaolu ✏️
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.
Here is a preview of what our movie application will look like:
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:
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:
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:
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:
npm run electron:serve
And you should see an output similar to the screenshot below:
Closing the dev tool, you should see the complete preview of the application, like in the image below:
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.
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:
...
<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:
<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:
<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:
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 with them to retrieve your API key.
To do this, update src/App.vue
with the following code:
<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:
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:
...
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:
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:
npm electron:build -- --linux nsis
Conclusion
Throughout this tutorial, we've looked at how to use Electron 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.
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.
LogRocket 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.
Top comments (0)