DEV Community

Cover image for Build a desktop app with Electron and Svelte
Khang
Khang

Posted on

Build a desktop app with Electron and Svelte

Hello everyone, welcome to another article in the series Let's build something!, 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 (with the support from Electron Builder) and Svelte. 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.

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:

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();
});
Enter fullscreen mode Exit fullscreen mode

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:

{
  ...
  "main": "index.js"
  "scripts": {
    "build": "rollup -c",
    "dev": "rollup -c -w",
    "start": "electron .",
  }
}
Enter fullscreen mode Exit fullscreen mode

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:

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:

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:

{
  scripts: {
    ...
    "dist": "npm run build && electron-builder"
  }
}
Enter fullscreen mode Exit fullscreen mode

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:

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.

Top comments (10)

Collapse
 
triptych profile image
Andrew Wooldridge

Thanks for this!

Collapse
 
souksyp profile image
Souk Syp.

It works. Are there any hot reloading tricks? thanks for the tuto.

Collapse
 
khangnd profile image
Khang

Maybe try this electron-reload package, I personally haven't tried it but it looks fairly simple to use.

Collapse
 
souksyp profile image
Souk Syp.

Exactly what I need. Thanks !

Collapse
 
yozawiratama profile image
Yoza Wiratama

how to pass click event from svelte to electron? or call some electron function from svelte?

Collapse
 
khangnd profile image
Khang

I'm not sure if it's possible for the first one, due to the fact that Svelte and Electron are 2 separate processes, but the second one is doable. I would advise that you consult the Electron documentation for a better explanation.

Collapse
 
johngicharu profile image
John Gicharu

Hi, you could try sending messages once the click event is detected to ipcMain. You might find this useful electronjs.org/docs/api/ipc-main

Collapse
 
abdallahmoh profile image
Abdallah Mohammed

Finally got it working Github Repo

Collapse
 
bmehder profile image
Brad Mehder

Oh, man. The possibilities are endless. Thank you for sharing!

Collapse
 
khangnd profile image
Khang

My pleasure!