Building Offline Desktop Apps from Existing Web Apps.

Electron Desktop App
Web Developers today have the power to build almost anything with the numerous JavaScript frameworks available.

Progressive web apps (PWAs) are fast and engaging. It’s a great way to convert your websites to an installable application. They can load under uncertain network conditions and be installed on your phone/computer, however having a Desktop Application saves you from worrying if your users get to change Web browsers.

Our first step to make a PWA is to add a Manifest.json file, a good guide on doing so can be found here (which has a sample manifest.json file).

Additionally, we need to implement Service workers, basically this is a script (JavaScript file) that runs in background and assists in offline first web application development. Service workers are used widely also to store data in IndexedDB for offline data persistence, it has access to the Cache API and Fetch API. Creating the service-worker.js file might be tedious, however there’s a tool to generate the file for you..

SW-Precache is a great Service Worker tool from Google. It is a node module designed to be integrated into your build process and to generate a service worker for you. There’s also a Codelab from Google to help you get started with sw-precache and can be found here, for Webpack projects, SWPrecacheWebpackPlugin can be used to generate the service-worker.js file during project build.

Offline data persistence should also be considered, so your app can access data when the device is offline and probably sync when back online. Alot of options are available which includes: PouchDB, Firestore, IndexDB etc… Sitepoint has a short guide to help you perform CRUD operations on the Client Side with PouchDB and can be found here.

Having made our web app a PWA and also integrating data persistence to our client side, we can deploy our frontend using any of our preferred provider.

I’ll recommend, A Static web publishing for Front-End Developers.

Finally, we’re now ready to bundle our Desktop Application. Alot of options are available such as NW.js or Electron.js. However, we’ll be making use of Electron in this tutorial.

We will be just wrapping our web app into an Electron web view we can start with the kit provided by Electron, let’s open the terminal and run following commands, I assume you already have Node.js and NPM installed.

# Clone the Quick Start repository
$ git clone

# Go into the repository
$ cd electron-quick-start

# Install the dependencies and run
$ npm install && npm start

Now by default electron is loading a local index.html file, so we will load the URL Open the main.js and tweak the createWindow() function on line 14 to load the URL. Check below for sample code.

function createWindow () {
// Create the browser window.
mainWindow = new BrowserWindow({
width: 1000,
height: 600,
minWidth: 480,
  // and load the index.html of the app.
// mainWindow.loadURL(url.format({
// pathname: path.join(__dirname, 'index.html'),
// protocol: 'file:',
// slashes: true
// }))
  // and load the url of the app.

However, we still need to fix the white screen while the web app is loading, let’s modify new BrowserWindow() by passing show: false, which will not show the window, and we will add a listener for ready then we will ask window to come on screen. See codes below:

// Create the browser window.
mainWindow = new BrowserWindow({
width: 1000,
height: 600,
minWidth: 480,
show: false


// Show when ready
mainWindow.once('ready-to-show', () => {

Feel free to add more properties to your Electron Desktop App such as Icons or Splash Screen. To build the Desktop for your desired enviroment, you can take a look at Electron packager.

Few major reasons I like this approach to building offline apps is because:

  1. Users get update when you make changes on your Hosted Web App without you having to build a new Desktop Application for them.
  2. Offline data can be synchronized with an online database as in PouchDB.

Hope this helps… I tried to bring so many things together into one place :-D