Create a Progressive Web App — A Quick Tutorial

Image for post
Image for post
Image credits:

This is a simple and minimal guide to build a progressive web app. Feel free to skip what you already know.

A PWA allows the visitors of your web site to install it as an app on their devices. Once installed, users will have an icon on the home screen to launch your web app, just like a native app.


  • PWAs can be a lot faster than web sites since they can cache resources like images, sounds, CSS for faster loading.
  • Users will be able to use some functionalities of your app even if they are completely offline. E.g. Dinner menu if you are making a restaurant app.
  • You can send notifications to your users to increase interactions. At the time of writing iOS support for this is yet to arrive.
  • You can seamlessly update PWAs. Updates are installed in the background without the user’s involvement.
  • You can use all the HTML 5 goodies: Web Payments, Bio Metric Authentication, WebRTC, WebSockets, WebGL, GeoLocation, WebAudio, Web Speech Recognition, WebVR and many more!
  • You don’t need to pay and submit your PWA to an app store.


  • A PWA can only be installed from a web site that uses HTTPS.
  • It doesn’t suite if you want to write platform-specific apps and do low-level programming. (E.g. A file zipper, a wallpaper changer)

0. Prepare your web site

<img src="image.gif"/>

1. Creating webmanifest file

"name": "My Progressive Web App",
"short_name": "My PWA",
"start_url": "./",
"display": "standalone",
"background_color": "red",
"theme_color": "red",
"description": "A dead simple progressive web app",
"icons": [
"src": "icon_192.png",
"sizes": "192x192",
"type": "image/png"
"src": "icon_512.png",
"sizes": "512x512",
"type": "image/png"
  • start_url — A URL to the page you land just after opening the app.
  • display — Defines screen space reserved for the app.
  • background_color — The color of the screen before your app loads.
  • theme_color — Components outside the app will adapt this color when displaying your app
  • icons — Launcher icons for your PWA. The given two sizes are recommended for Android.

NOTE: iOS Safari currently doesn’t obey this file. It thinks different!

2. Creating a basic Service Worker

  • Fetch and show notifications form your site.
  • Update the PWA seamlessly
  • Act as a mini local server and let users work offline.
  • Fetch new content from your site even before the user open the app

Your success depends on your understanding on Service Workers. First, lets see how they work.

The first visit

  1. The browser looks for a service worker file and then creates a new Service Worker dedicated to your web site. (This is called Service Worker Registration)
  2. Since this is a new Service Worker, the browser pushes the Service Worker to the install phase. Here the Service Worker is free to do whatever it wants including doing nothing.
  3. After the install phase, the browser pushes the Service Worker to activate phase. This is the phase where your Service worker is ready to serve but it’s letting you do anything just before it starts.
  4. Finally, the Service Worker starts. It does nothing for now.
  5. Next, the user closes the web page, but still, the service worker continues to breathe. That’s how their life is like. Born to do background tasks.

Prepare your almost empty Service Worker file sw.js:

self.addEventListener( 'install', function (event) {})self.addEventListener( 'activate', function (event) {})self.addEventListener( 'fetch', function (event) {})

Every service worker MUST handle install, activate and fetch events. A Service worker without these three events has no purpose in its life

The fetch event is called whenever your user makes a request. Here we have the power to let that request reach your web server, or stop that from happening and serve something else. For now let’s keep the event handlers empty and get the PWA up and running.

Have your index.html load Service Worker by adding:

<script>    navigator.serviceWorker.register('sw.js')</script>

Your bare bone PWA is now ready. Right-click on index.html and open it with Live Server:

Image for post
Image for post

Then go to Chrome Developer Options (F12) > Application tab:

Image for post
Image for post

If you have done something wrong, you will be seeing it here. Go to the Service Workers section in sidebar:

Image for post
Image for post

Note the phase of the Service Worker is Running. Which means it has passed install and activate phases!

This doesn’t mean your PWA is installed. This only means that a Service Worker has been spawned for your site and ready to do background tasks. PWA installation is indicated somewhere else :

Image for post
Image for post
On desktop Chrome
Image for post
Image for post
On mobile Chrome (Credits: Chromium team)

After the installation, you will get a launcher icon on your device to open the PWA. You can easily test this on your Android smartphone through Remote Debugging by plugging the phone to your PC.

Keep in mind that PWAs are installable only if they have HTTPS or run on localhost. In this case, forward one of your mobile’s localhost port to PC’s Visual Studio Code Live Server port:

Image for post
Image for post

This maps http://localhost:8080 on phone to http://localhost:5500 on PC.

The following visits to your site…

Updating a PWA while it’s running can break the running app and cause bad user experiences. Hence, updating occurs the next time the user launches the app. At that point browser replaces the old Service worker with the new one. (There are ways to update a running app. I do not consider it as a good practice)

3. install, activate and fetch handlers

Install handler is used to cache the static assets such as images, style sheets in your web site. This will reduce the load on your server. You do not need to cache the manifest and service worker since the browser already stores them internally at installation.

Activate handler an opportunity for you to do something just before the Service Worker fires up. We usually clean up old cache files here.

Fetch handler acts as a tiny server. It decides whether a request is first served by the server or by local cache. The order depends on your requirements.

All above is somewhat common for every Service Worker. Therefore, here is a template you can use as your Service Worker. Feel free to change as needed:

Make sure to update the CACHE_VERSION every time you update a web page. Changing the CACHE_VERSION will change the Service Worker file. The existing PWA installations will identify the change and update themselves. Otherwise, they will be serving an outdated content to your users even if you have added fresh content to your site.

Don’t stop from here. Learn how you can send push notifications to your PWA installations!

Weekly Webtips

Explore the world of web technologies through a series of tutorials

Sign up for 💌 Weekly Newsletter

By Weekly Webtips

Get the latest news on the world of web technologies with a series of tutorial Take a look

By signing up, you will create a Medium account if you don’t already have one. Review our Privacy Policy for more information about our privacy practices.

Check your inbox
Medium sent you an email at to complete your subscription.

Naveen Kumarasinghe

Written by

Software Engineer, London Stock Exchange

Weekly Webtips

Explore the world of web technologies through a series of tutorials

Naveen Kumarasinghe

Written by

Software Engineer, London Stock Exchange

Weekly Webtips

Explore the world of web technologies through a series of tutorials

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app