Tutorial: Making dVPN desktop application with Electron & React

Making client application.

Hello friends, in this tutorial we will show how to build the simplest desktop dVPN application based on the Electron framework and will cover the main parts of the dVPN client, to give you an understanding of how they interact.

For those who want’s to go straight to the code, here is a link

What we will use:

  • NodeJs: >=v16.9.1
  • npm: >=7.21.1
  • yarn: >= 1.22.5
  • Electron: >= 14.0.1
  • Typescript: >= 4.4.3
  • webpack: == 4.46.0 // we can’t use Webpack 5, because of limitation in electron-webpack
  • electron-webpack: >= 2.8.2
  • React: >= 17.0.2
  • @mysteriumnetwork/node: > 0.64.0 // Client Mysterium Node
  • mysterium-vpn-js: > 15.1.0 // Tequila API client
  • electron-builder: > 22.11.7

How is client application work

Every client application consist of these four parts:

  • Application — your client application
  • Mysterium Node — client node to interact with Mysterium Network
  • Supervisor — service used to move out from Node any services that need escalation of privileges, and also used to control them. Supervisor used only for client applications.
  • Wireguard — VPN tunnel

Typical application startup:

  1. Start the Node.
  2. Install & Start Supervisor service(if it has not been installed yet).
  3. Setup connection to the Node Tequila API through the localhost.
  4. Setup connection to the Supervisor through the socket.
  5. Do some application logic…

Each Mysterium client Node is running Tequila API on `localhost:44050` which is used for communication and control. To interact with this API we will use the package `mysterium-vpn-js`. You can see docs for API by opening localhost:44050/docs in your browser(when Node working) and by visiting mysterium-vpn-js client

Let’s build some simple Electron App

Clone our demo repository to your local machine

  1. git clone https://github.com/mysteriumnetwork/dvpn-desktop-tutorial
  2. yarn install
  3. yarn dev - to see how it looks like

Structure & main modules

Usually, people are building react app with the use of create-react-app tool which separates Source code from Electron. But this approach has some negative consequences if we want that all our code to be written on TypeScript. That's why we will be using webkit & electron-webkit wrapper.

From this point our project structure will look like this:

|static             // static files
|---bin // place where bin from @mysteriumnetwork/node will be copied
|src // our code
|---electron // electron part with main process
|---|---node // IPC Host code
|---renderer // app part
|---|---api // api methods to work with Tequila API
|---|---components // UI components
|---shared // shared code, libraries, utils
|---|---ipc // IPC clients

In electronWebpack part of package.json we set location of our app parts like electron and app, also adding webpack config for renderer process.

We use postinstall directive to copy Node binaries to our static folder so we could get access to them later from the application.

Setting up Electron

The first entry point of our application is src/electron/main.ts which will run our Electron. To create an Electron window we use:

Besides typical stuff, we need to setup IPC channels for our Node and Supervisor. And stop Node and disconnect from Supervisor before quit

Mysterium Node & Supervisor

In the src/electron/node/ we have mysteriumNode.ts and supervisor.ts. This is our IPC listeners that runs in the Electron thread, and which will give our App the possibility to run Node and Supervisor. We need this because our renderer process with our app has no access to the system, but the electron process has.

We will communicate with them using IPC clients in src/shared/ipc folder.

In mysteriumNode.ts we have 3 IPC methods: start, stop and kill. If you need Import/Export identity methods you can find them here.

In supervisor.ts we have 4 IPC methods: install, upgrade, connect, disconnect. During Supervisor installation user will need to enter Admin password as it will be run with system privileges.

Main App

Our application is very simple and consists of a few views components and API to work with Node Tequila API.

Let’s discuss the process of interaction with Node and creating VPN tunnel with some exit nodes:

1. We need to create an identity, which looks something like this 0x142362c0a179da288903f21adcba24686c01e654 and which is basically user id in Mysterium Network

2. To use identity we need to unlock it(with a password) and register in the Registry service of Mysterium Network.

3. Get a list of proposals using some filtration by country, connection type, price, speed, etc. The proposal is information about the provider(exit node) to which you are able to connect.

4. Connect to one of the providers and all traffic will be routed through him.

5. Disconnect from the provider to stop route traffic through him.

We will not be using any redux, mobx, etc. Instead, we will store state in the api.ts to make the app simpler.

We use steps here instead of a router to just update the App view on State update in the API.On startup, we calling Startup() and Preload() to start the Node and the Supervisor and preload identities list with current connection status(if we reload the app during work)

After that, all pretty simple -> User select identity(or create new), unlock it, and connect to random Node.


As you can see building dVPN application for Mysterium Network is simple enough. Just a few files for Node and Supervisor integration, Tequila API to control the Node and that’s all.



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store