First years in my software craftsmanship started with Delphi 7. It was amazing, it was time when the internet was semi-empty. It was hard to find examples, ask help, basically, you were on your own. Ohh good old times, I wouldn’t change that experience, but I wouldn’t want to do that again.

Time goes on, everything evolves, new technologies come in play. Time to time, I stop and look at what has been changed. And that is so cool, always there is something new to look into. To change my own biases, yes painful, but the world isn’t stuck in time warp.

Ladies and gentlemen I bring to you my experience with Electron.

What is an Electron

An Electron is a framework to create native desktop applications for Windows, MacOS, and Linux. And what is the wow part in it, you can use vanilla javascript or any other javascript framework for building UI.

This is amazing, you can be a web app developer and by reusing the same skillset you can build a desktop app.

If you can build a website, you can build a desktop app. Electron is a framework for creating native applications with web technologies like JavaScript, HTML, and CSS. It takes care of the hard parts so you can focus on the core of your application.

The project

Let us create an empty npm project

npm init --yes

Add Electron stuff and start command

npm i -D electron

Add start script inside package.json

"start":"electron ."

If we execute the npm start, we should get a popup error from Electron. That is ok, this only means that Electron is alive and we don’t know how to boot it.

The main and renderer process

Before we dive into coding, it is important to understand the basics of Electrons architecture.

In Electron, the process that runs package.json 's main script is called the main process. The script that runs in the main process can display a GUI by creating web pages. An Electron app always has one main process, but never more. Since Electron uses Chromium for displaying web pages, Chromium’s multi-process architecture is also used. Each web page in Electron runs in its own process, which is called the renderer process. In normal browsers, web pages usually run in a sandboxed environment and are not allowed access to native resources. Electron users, however, have the power to use Node.js APIs in web pages allowing lower level operating system interactions.

My oversimplified explanation would be. There is a main process which creates a window and that window is a Chromium. Where Chromium is a process by itself aka renderer.

Typescript

Starting from the 1 June of the year 2017, Electron supports Typescript. Good, let’s use it.

npm i -D typescript

npm i -D tslint

npm i -D prettier

Add tslint.json in the project root

Add tsconfig.json in the root of the project

For typescript compilation, tsc could be used, but as the end game is to use React and manipulate with templates. Webpack is the way to go this time.

Web pack

Setup for the web pack

npm i -D webpack webpack-cli

npm i -D html-webpack-plugin

npm i -D @babel/cli @babel/core @babel/preset-env babel-loader @babel/plugin-proposal-class-properties @babel/plugin-transform-arrow-functions

npm i -D @babel/preset-typescript

Add .babelrc in the root of the project

So far so good, now let us create a main process of Electron and say hello to Mom!

Create a folder src

Add main.ts file in src folder

line 8 creating a window and loading index.html into window aka Chromium.

Add index.html to the src folder

Add webpack.config.js in the root. Instruction for the web pack how to handle Electrons main process build. Important target:"electron-main"

Adjust a bit package.json

Execute commands

npm run build

npm run start

And here it is. A fully functional desktop application. Which is saying hi to mom.

And this is actually the place where your front end developer skills kick in. As it is a Chromium you can use any kind of frontend technology, React, Vue, Angular, plain javascript.

The React

React will live in Electrons renderer process for that reason we will have to create a separate web pack build configuration. And teach babel to use react loader

npm i -D @babel/preset-react

npm i -S react react-dom

npm i -D @types/react @types/react-dom

Adjust .babelrc

Adjust webpack.config.js by removing the responsibility of index.html template generation. It is the responsibility of the renderer build process.

Add new web pack config file webpack.react.config.js . This configuration is responsible for compiling react stuff and making sure that compiled result is injected inside index.html

Adjust index.html so that it contains a container where React can place its component.

Create a folder app inside src and create renderer.tsx

Now let's say Hello mom again, only now we will use a React to do so.

Create a folder components inside app and create Dashboard.tsx

Adjust the package.json and add a new command so we can compile the renderer.

npm run build:react

npm run build

npm run start

Now, this is something I don’t see every day. A native desktop app running React inside of it. Well maybe I do, I just don’t know it as Electron is a popular framework and is used all over the place. For example, Visual Studio code, try to guess what is powering it ;).

The C# what?

A blog post by Rui Figueiredo ignited my interest in Electron.

Electron using C#. That is an interesting synergy going on here. And as it is C# core, it is cross-platform as well.

Cross-platform desktop app powered by Electron using React for UI and extended functionality by C# goodness. And now not only you can use your frontend skills, but backend as well.

Install new package for npm project

npm i -D electron-cgi

Adjust main.ts for a test run, we will send Mom to C# console app and it will return Hello Mom back. And we will console log that.

Create a simple dotnet C# core console app. Add ElectronCgi.DotNet nuget.

npm run build

npm run start

Amazing isn’t it? Rui did go an extra mile and added this to C# as well

connection.OnAsync();

Now we are talking serious stuff. Imagen what possibilities this opens? Async communication to a database, to Rest API, to Queues, all nice packages for clouds, Amazon, Azure etc. All the good stuff from C# at your fingertips.

And it is not limited only to sending strings, it can be strongly typed object in C#.

Here is how

ElectronCGI draws inspiration from how the first dynamic web requests were made a reality in the early days of the web. In the early days the only things that a web server was able to serve were static web pages. To serve dynamic pages the idea of having an external executable take in a representation of the web request and produce a response was put forward. The way that executable got the web request’s headers was through environment variables and the request’s body was sent through the standard input stream (stdin). After processing the request the executable would send the resulting html back to the web server through the standard output stream (stdout)

Heavy use of stdout. Which isn’t necessarily something bad, for example, php.exe and the frameworks which surround it ;).

I generally like the approach, clean, smart and innovating. I do endorse read a full blog post of Rui.

Extra mile with React and C#

Let’s make this even interesting, send the message to React from C#.

For that make changes in renderer by changing the Dashboard functional component to a component with the state.

What is going there? We subscribe to the channel greeging and upon receiving a message from the main process we put the message into the state. And from that point React takes ower, notices the state changes and renders the message.

Changes in the main process by sending received message from C# to React

Create a legit EXE file

Add package

npm i -D electron-packager

Adjust the package.json file by adding package-win command and point main to dist folder file main.js .

Tutorial for all platform build commands here.

npm run package-win

Copy C# folder “ core ” into “ release-builds\electron-demo-win32-ia32 ” and run the electron-demo.exe

The end

This journey of mine from Delphi 7 to React, Electron, C# is awesome. As I said before, nothing is stuck in time, every day new technologies pop up which makes us better and breaks our personal biases.

To stay open minded is our biggest challenge.

Sourcecode of demo in GitHub

For full Ract pipeline read here.