Table of Contents
- Getting an Electron shell running
- Getting the Stopwatch code
- Building a native application wrapper
- The final product
Few days ago I decided to find a Stopwatch app for my Mac. I went over to the App Store and noticed that there were no good free options available.
I thought to myself, how hard would it be to make one with Electron? Turns out, it was very easy.
Getting an Electron shell running
As you probably already know, Electron is a very popular open source framework that makes developing cross platform Desktop GUI apps very easy. It works as a wrapper around Chrome browser, so all Electron apps are just regular web apps wrapped in some magic.
Since Chrome runs on most platforms, so does Electron. Electron powers Slack, Atom, Visual Studio Code, Hyper and many other apps.
I’ve read various Electron tutorials a number of times, but never got around to building an actual app myself. I was pleasantly surprised that it took less than 2 minutes to get and run an Electron shell on my computer.
I used the Electron Quick Start project with the following steps:
git clone https://github.com/electron/electron-quick-start
cd electron-quick-start/
npm install
npm start
Code language: PHP (php)
This opened an Electron shell that looked as such:
Looking inside the index.html
file, I noticed the following code:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
</head>
<body>
<h1>Hello World!</h1>
<!-- All of the Node.js APIs are available in this renderer process. -->
We are using Node.js <script>document.write(process.versions.node)</script>,
Chromium <script>document.write(process.versions.chrome)</script>,
and Electron <script>document.write(process.versions.electron)</script>.
</body>
<script>
// You can also require other files to run in this process
require('./renderer.js')
</script>
</html>
Code language: HTML, XML (xml)
So the Electron shell above was just using the content of this index.html
file. All I had to do to make the stopwatch app, was to add some HTML, CSS and JavaScript inside the index.html
file.
Getting the Stopwatch code
There are a lot of stopwatch examples available online. For inspiration I went to codepen.io and searched for stopwatch there. As a proof of concept I copy/pasted a random example into the index.html
file (making sure to wrap it into proper <body></body>
, <style></style>
and <script></script>
tags) and it just worked.
While other people’s example were great, I wanted to write my own version. You can see it bellow running inside Codepen. I also forked the Electron Quick Start and tracked my development in Simple Stopwatch repo on Github. There you can see the final index.html file, as well as the app.js where I implemented all of the JavaScript logic and style.css file with all of the CSS.
See the Pen stop-watch by Alex (@akras14) on CodePen.
I noticed that the default electron window was a little too big for my use case, so I modified the mainWindow = new BrowserWindow({width: 500, height: 300})
line inside main.js file to make it a little smaller.
I believe the code is fairly self explanatory so I am not going to go over it in detail in this post. Please let me know in the comment area if you would like to see a more detailed walk through and I’ll make sure to write one.
Building a native application wrapper
I used another repo called Electron Packager to generate an actual app bundle. I installed it via npm install --save-dev electron-packager
. Once installed, I added the following npm script
into my package.json file:
"build": "electron-packager ./ simple-stopwatch --icon=icon/stopwatch.icns --overwrite"
Code language: JavaScript (javascript)
The parameters are:
- The folder my app is in
- Name that I want to use for the app
- Icon that I want to use for the app
- Force over-write the old app on build re-run
Running this command with npm run build
would generate a /simple-stopwatch-darwin-x64
folder, inside of which I’ll have the generated simple-stopwatch.app
. Finally, I just had to move the generated app into the /Applications
folder and I was done.
Few additional notes. In order to generate the app icon I downloaded a free stopwatch image from pixabay.com and converted it to icns
format via iconverticons.com. (A reader named Paola suggested that https://www.websiteplanet.com/webtools/favicon-generator/ might be a better tool to generate icns
).
Also electron-packager
was smart enough to generate an app for the right system (Mac OS in my case). I have not tried it, but I am sure that it would be just as easy to generate a working app for Windows or Linux. The only thing that would vary between platforms is the icon format. More information is available in electron-packager’s documentation.
The final product
I am pretty happy with the final product. It feels and act like a native app.
The UI is not polished, but UX does what I want it to do. It will be very easy to make it even better, since it’s just a regular web app.
Most importantly, I can see why Electron is such a popular project and why so many companies are choosing to build OS specific apps with it.
Update 07/28/2017: Some people criticized me for calling Electron a “native” app. By that I simply meant that I could run the app without having to open a browser. There are a lot of “in browser” stopwatches available, but I wanted to be able to use my stopwatch via regular app hotkeys like “Command + Tab”. Electron project describes itself as follows:
“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.”
I believe that whether Electron apps should be called “native” depends mainly on how “native” is defined.
Another criticism is that Electron apps are very bloated, since they have to package and run a full browser to execute something as simple as a stopwatch. This is true and Electron’s performance implications should be carefully consider when deciding to use it for a production app.