This has been created starting from the soulehshaikh99/create-svelte-electron-app template.
The aim of this project is to provide Web Developers using svelte
the power to create cross-platform desktop apps using electron
, while providing a working ipc implementation out of the box.
electron
enables you to create desktop applications with pure JavaScript by providing a runtime with rich native (operating system) APIs. You could see it as a variant of the Node.js runtime that is focused on desktop applications instead of web servers.
electron-builder
is used as a complete solution to package and build a ready for distribution (supports Numerous target formats) Electron app with "auto update" support out of the box.
electron-serve
is used for Static file serving for Electron apps.
electron-updater
is used to automatically check and install updates when available.
svelte
is a radical new approach to building user interfaces. Whereas traditional frameworks like React and Vue do the bulk of their work in the browser, Svelte shifts that work into a compile step that happens when you build your app. Instead of using techniques like virtual DOM diffing, Svelte writes code that surgically updates the DOM when the state of your app changes.
concurrently
is used to run multiple commands concurrently.
wait-on
is used as it can wait for sockets, and http(s) resources to become available.
node-ipc
is used to allow inter-process communication between main process, renderer process and server process.
svelte-spa-router
is used for the routing of the renderer process. This is optional and can be replaced.
Note: If you wish to use npm over yarn then modify package.json
by replacing yarn
with npm
in electron-dev
and preelectron-pack
scripts.
But I strongly recommend using yarn as it is a better choice when compared to npm.
# Clone the Project
# or GitHub CLI Users
$ gh repo clone https://github.com/Ottozz/svelte-electron-ipc-boilerplate.git
# or Normal Git Users
$ git clone https://github.com/Ottozz/svelte-electron-ipc-boilerplate.git
# Switch location to the cloned directory
$ cd svelte-electron-ipc-boilerplate
# Install dependencies
$ yarn # or npm install
# Run your app
$ yarn electron-dev # or npm run electron-dev
# Package Your App
$ yarn electron-pack # or npm run electron-pack
This boilerplate uses three processes and let them communicate through a local tcp socket. Each process has a specific purpose and the folder structure reflects this implementation:
Main process:
The code executed by this process is in the src/main-process
folderServer Process:
The code executed by this process is in the src/server-process
folderRenderer Process:
The code executed by this process is in the src/renderer-process
folderThe main process is created by default when the electron app is started. When the ready
event is emitted, the following code is executed:
app.on('ready', async () => {
if(!isDev()) autoUpdater.checkForUpdates();
const { width, height } = screen.getPrimaryDisplay().workAreaSize;
screenWidth = width;
screenHeight = height;
let serverSocket = await findOpenSocket();
createWindow(serverSocket);
createBackgroundProcess(serverSocket);
});
The checkForUpdates()
function is invoked to check for updates, by connecting to the remote file server. The hostname and port of the server is defined in the package.json
. If the update is found, it is automatically downloaded and installed by listening to the update-downloaded
event.
Note: If you don't want to use a generic file server for the updates, different options are supported out of the box by the electron-builder
module.
After that, the process searches for a free socket name available with the method findOpenSocket()
and pass the socket name to the functions createWindow()
and createBackgroundProcess()
:
createWindow()
function creates the renderer process with nodeIntegraion: false
and specifies the client-preload.js
file as preload script to be executed before the creation. This file is responsible of defining the methods to initialize the client socket and send/listen messages and expose them to the renderer process trhough the contextBridge.exposeInMainWorld()
method.createBackgroundProcess()
creates the server process by doing a fork of the main process. This could be avoided, but it follows the separation of concern principle and ensure that all the server logic is performed in a dedicated process.All of the server side business logics , are implemented by this process, leveraging the power of Nodejs.
The server.js
file is the entry point of the process. Here, the init()
method of the server-ipc.js
file is invoked. This creates the server socket and defines the send()
method to broadcast messages to all the clients connected.
The file server-handlers.js
exports and object which defines the messages to be listened and the functions to be invoked when the respective message is received. The folder services
contains the implementaion of these functions.
This is the process that creates the broswer window and all of the front-end code inside it, using Svelte.
The main.js
file is the entry point and renders the App
component. When the component is mounted, the initclientIPC()
method, exposed by the main process, is invoked. After that, messages can be sent to the server process from any .svelte file through the exposed send()
method.
onMount(async () => {
/* Invoke the method exposed by the main process to create the client socket */
await window.electron.initClientIPC();
/* Once initialized, messges can be sent to the server process like this */
let params; //can be any type of input. String/Array/Object...
await window.electron.send('message', params);
});
The App
component also include the <Router>
tag to allow routing; the rules are defined in the routes.js
file. The svelte-spa-router is used.
As for the folder strucutre:
pages
folder contains all of the svelte components for which a route is defined.components
folder contains the svelte components imported and used by pages or other components.