Build a desktop app with Electron and Svelte
Tags: electron, svelte, javascript
Published: 2021-03-27 17:08:49


Hello everyone, welcome to another article in the series [Let's build something!](https://dev.to/khangnd/series/11440), a series dedicated to building, well, *something* that involves several techs (techniques and technologies) mostly in JavaScript. In this article, I would like to share my first experience building a desktop app with [Electron](https://www.electronjs.org/) (with the support from [Electron Builder](https://www.electron.build/)) and [Svelte](https://svelte.dev/). If you have never heard of any of them, simply click on the links to get to know the awesomeness. Now, let's just dive in.

# 1. Setup

The setup step is pretty simple and straightforward, we're going to start from a Svelte template as it already contains a lot of dependencies gathered in one boilerplate, then we integrate Electron into our app to get started.

## 1.1. Initiate a Svelte project

If you have seen my previous post with the browser extension, you should be familiar with this step already. From the CLI, run `npx degit sveltejs/template electron-app-svelte`. This will make a copy of the Svelte template to your machine with the name `electron-app-svelte`, and a basic structure as seen in the repository.

![](https://dev-to-uploads.s3.amazonaws.com/i/0qk48rw1f4at61vo91mb.png)

Run `npm install` to install all necessary dependencies in the template's `package.json`.

## 1.2. Integrate Electron

Now we install the Electron package by running `npm install electron --save-dev`. Once done, let's create our `index.js` file at the root with the following content:

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

app.on("ready", () => {
  const mainWindow = new BrowserWindow();
  mainWindow.loadFile(path.join(__dirname, "public/index.html"));
  mainWindow.webContents.openDevTools();
});
```

This is the minimum content required for Electron to create a window and attempt to load our entry HTML file from the `public` folder.

Next, let's make some changes in our `package.json` to get it to work:

```json
{
  ...
  "main": "index.js"
  "scripts": {
    "build": "rollup -c",
    "dev": "rollup -c -w",
    "start": "electron .",
  }
}
```

So, what I did was adding a new field `main` and pointing it to the `index.js` file we've just created, and also modifying the `start` script to invoke Electron to load our compiled code in the app's window. Now, we just need to run `npm run dev` to compile our Svelte source code, and subsequently, the start script will be called automatically (as predefined in our Rollup config). Let's try it to see if it already works:

![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kncxosyx3ewvg3zrmxnn.png)

Nope, our app appears blank with some errors in the Dev Console. Apparently, the relevant resources could not be loaded due to the incorrect path, this is due to the fact that we are not serving our resources through any kind of host. The workaround is fairly simple, let's open our `index.html` file and remove all the **/** at the start of the links, this should fix it. Try running it again:

![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7nzh9o5xqgd4so7ox9ua.png)

Awesome, we now have our Electron + Svelte app ready for development 🎉

# 2. Development

Once done with the setup, you can now continue the development just like you do with the web apps. The only difference is that our app is now run inside a window instead of a web browser (though they're still partially the same as the window is also using the V8 JavaScript engine under the hood to render web content).

Simply run `npm run dev` to start the development. Any changes in our source code are tracked and automatically re-compiled, we only need to press `Ctrl+R` to refresh our window and reflect the changes.

# 3. Build and distribute

After finishing the development, the next thing we must care about is obviously how to distribute our desktop app, how different it might be from the usual distribution of a web app?

For sure it is different, but not so hard at all. Let's see how this works:

Literally, all we need is an `electron-builder` package, so let's install it first with `npm install electron-builder --save-dev`. Next, in our `package.json`, add a new script as below:

```json
{
  scripts: {
    ...
    "dist": "npm run build && electron-builder"
  }
}
```

And that's it. Our `dist` script will produce a built version of our Svelte source code and trigger the `electron-builder` command to produce a complete distributable desktop app. Let's try it now and see what it gives us, run `npm run dist`:

![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hy002c4kh20cmqa8eded.png)

Look, a `dist` folder appears as a result, and inside of it, there are a lot of things, but we only need to concern ourselves with those 2 highlights:
* The `.exe` installer package (as Windows was my target OS), which is what we need to distribute our app to the users.
* Upon installing, the `.exe` package will just extract exactly what is inside the `win-unpacked` folder to the users' machine and the app can then be used. Therefore, alternatively, you may also compress this folder and distribute it to the users, which still delivers the same outcome.

*A complete repository you can find at: https://github.com/khang-nd/electron-app-svelte*

And that is all in this sharing article, thank you for reading and see you in the next one.