Bringing Your Web Application to Desktop Life with Electron

Sick of dealing with browser quirks? Or maybe one of your users just LOVES some old crappy version of Internet Explorer? Or do you have users that simply cannot avoid the temptation of an address bar that can take them on a journey to social media land?

This short post will show you in just a few easy steps how you can take your existing web site or application and package it up as an Electron application that they can use without ever touching a browser.

What is Electron?

Electron is a framework for building cross-platform native applications using all your favorite web technologies like CSS, HTML and Javascript. It gets all of the difficult cross-platform concerns and allows you to actually just write some code.

If you want to check it out, I'd encourage you to visit their site, however we aren't going to be spending too much time on it specifically. We are more interested in quickly using it to migrate an existing web application.

Jumping from Web to Desktop

This post is going to take advantage of the existing Electron Quick Start application that you can find on GitHub. We are going to pull it down, make a single change, and then run it to see your web application running it a semi-desktop glory.

First, pull down the electron-quick-start repository here.

You can use your favorite code editor to see what it looks like at this point :

electron-quick-start

It's pretty bare-bones, and actually it's going to stay that way. The next step is to open up the main.js file and change the contents of the mainWindow.loadURL() function from :

mainWindow.loadURL(url.format({  
    pathname: path.join(__dirname, 'index.html'),
    protocol: 'file:',
    slashes: true
}))

to :

mainWindow.loadURL('http://your-web-application-url-here')  

This will tell Electron that it needs to load the given URL when the application opens the main window. Then you would just need to run it (either directly through your editor) or via the following command :

electron .  

After running this command, Electron will do its magic and create an Electron app that points to the URL specified in your main.js file. It'll look and feel much like a browser, except that it will be sandboxed to prevent users from looking at the source or doing any other kinds of tinkering :

Blog Example

If you wanted to adjust this further, you could set your own custom icon by defining it within the icon property of your window object :

// Create the browser window.
mainWindow = new BrowserWindow({  
    width: 1024, 
    height: 768,
    icon: __dirname + '/favicon.ico'
})

As well as explicitly hiding the menu bar by calling the setMenu() function :

// Hide the menu
mainWindow.setMenu(null);  

You can see a full set of documentation here of the BrowserWindow object to configure whatever your heart desires.

Packaging things up.

So we have shown that you can easily create this Electron wrapper for your existing web site or application, but now we want to take that a step further. Let's say that you want to actually build a proper executable that would allow the user to install this "app" onto their machines.

Thankfully, the team at Electron has already handled this for you thanks to their electron-packager project, which is specifically designed to handle packaging and distribution of your application.

To get started, ensure that you have the electron and electron-packager packages installed via :

npm install electron -g  
npm install electron-packager -g  

Once the packager is ready, then another quick command will package up your application into an executable (your parameters may vary) :

electron-packager . app --platform win32 --arch x64 --out dist/  

And then you should see your new shiny executable within a new dist/app output directory :

Electron Directory

But What about My Sweet Scripts?

You may notice that your Javascript code might not work as expected when running inside of Electron. This is simply because Electron doesn't know about it, but you can easily change this.

Simply wrap your <script> tags as follows :

<script>if (typeof module === 'object') {window.module = module; module = undefined;}</script>  
<script src="/app/app.js"></script>  
<script>if (window.module) module = window.module;</script>  

After adding this, you should see that all of your wondrous Javascript events trigger as expected.

Getting it to folks.

So at this point, we have the application packaged up as an executable, now we have to get it to people. Once again, there's a package for that: electron-installer-windows, which will handle building a Windows installer for you and handle things like deploying updates via Squirrel.

Again, we visit the command line to get this installed :

npm install electron-installer-windows -g  

and then run it :

electron-installer-windows --src dist/app-win32-x64/ --dest dist/installers/  

One issue that I frequently encountered was an "invalid URL" error during the build process for the installer. If you run into this yourself, you can simply add a homepage to your project.json file as seen below :

"homepage": "http://rion.io",

This should resolve the error and you can go about packaging your project up as expected. The process itself will usually take a while, but afterwards you should be presented with the installer that you've come to know and love within Windows :

Installer

Now you can go distribute it out as a holiday gift to your friends, family, and loved ones.

Note: Electron actually has a specific electron-builder project that handles building installers, but I found the above one a bit easier to use. YMMV.

Just to reiterate what this is.

Firstly, let's be clear about what this is. It's a desktop application that simply wraps a given URL to your web application in a sandbox to help retain consistency and avoid any browser-specific quirks (or curious users).

Obviously Electron can do some really interesting things, but this was just to demonstrate how you could run a few commands and build an executable for your web application (or even an installer).

comments powered by Disqus